xref: /OK3568_Linux_fs/external/xserver/hw/xfree86/x86emu/ops.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /****************************************************************************
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun *						Realmode X86 Emulator Library
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun *            	Copyright (C) 1996-1999 SciTech Software, Inc.
6*4882a593Smuzhiyun * 				     Copyright (C) David Mosberger-Tang
7*4882a593Smuzhiyun * 					   Copyright (C) 1999 Egbert Eich
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun *  ========================================================================
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun *  Permission to use, copy, modify, distribute, and sell this software and
12*4882a593Smuzhiyun *  its documentation for any purpose is hereby granted without fee,
13*4882a593Smuzhiyun *  provided that the above copyright notice appear in all copies and that
14*4882a593Smuzhiyun *  both that copyright notice and this permission notice appear in
15*4882a593Smuzhiyun *  supporting documentation, and that the name of the authors not be used
16*4882a593Smuzhiyun *  in advertising or publicity pertaining to distribution of the software
17*4882a593Smuzhiyun *  without specific, written prior permission.  The authors makes no
18*4882a593Smuzhiyun *  representations about the suitability of this software for any purpose.
19*4882a593Smuzhiyun *  It is provided "as is" without express or implied warranty.
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22*4882a593Smuzhiyun *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23*4882a593Smuzhiyun *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24*4882a593Smuzhiyun *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25*4882a593Smuzhiyun *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26*4882a593Smuzhiyun *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27*4882a593Smuzhiyun *  PERFORMANCE OF THIS SOFTWARE.
28*4882a593Smuzhiyun *
29*4882a593Smuzhiyun *  ========================================================================
30*4882a593Smuzhiyun *
31*4882a593Smuzhiyun * Language:		ANSI C
32*4882a593Smuzhiyun * Environment:	Any
33*4882a593Smuzhiyun * Developer:    Kendall Bennett
34*4882a593Smuzhiyun *
35*4882a593Smuzhiyun * Description:  This file includes subroutines to implement the decoding
36*4882a593Smuzhiyun *               and emulation of all the x86 processor instructions.
37*4882a593Smuzhiyun *
38*4882a593Smuzhiyun * There are approximately 250 subroutines in here, which correspond
39*4882a593Smuzhiyun * to the 256 byte-"opcodes" found on the 8086.  The table which
40*4882a593Smuzhiyun * dispatches this is found in the files optab.[ch].
41*4882a593Smuzhiyun *
42*4882a593Smuzhiyun * Each opcode proc has a comment preceeding it which gives it's table
43*4882a593Smuzhiyun * address.  Several opcodes are missing (undefined) in the table.
44*4882a593Smuzhiyun *
45*4882a593Smuzhiyun * Each proc includes information for decoding (DECODE_PRINTF and
46*4882a593Smuzhiyun * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
47*4882a593Smuzhiyun * functions (START_OF_INSTR, END_OF_INSTR).
48*4882a593Smuzhiyun *
49*4882a593Smuzhiyun * Many of the procedures are *VERY* similar in coding.  This has
50*4882a593Smuzhiyun * allowed for a very large amount of code to be generated in a fairly
51*4882a593Smuzhiyun * short amount of time (i.e. cut, paste, and modify).  The result is
52*4882a593Smuzhiyun * that much of the code below could have been folded into subroutines
53*4882a593Smuzhiyun * for a large reduction in size of this file.  The downside would be
54*4882a593Smuzhiyun * that there would be a penalty in execution speed.  The file could
55*4882a593Smuzhiyun * also have been *MUCH* larger by inlining certain functions which
56*4882a593Smuzhiyun * were called.  This could have resulted even faster execution.  The
57*4882a593Smuzhiyun * prime directive I used to decide whether to inline the code or to
58*4882a593Smuzhiyun * modularize it, was basically: 1) no unnecessary subroutine calls,
59*4882a593Smuzhiyun * 2) no routines more than about 200 lines in size, and 3) modularize
60*4882a593Smuzhiyun * any code that I might not get right the first time.  The fetch_*
61*4882a593Smuzhiyun * subroutines fall into the latter category.  The The decode_* fall
62*4882a593Smuzhiyun * into the second category.  The coding of the "switch(mod){ .... }"
63*4882a593Smuzhiyun * in many of the subroutines below falls into the first category.
64*4882a593Smuzhiyun * Especially, the coding of {add,and,or,sub,...}_{byte,word}
65*4882a593Smuzhiyun * subroutines are an especially glaring case of the third guideline.
66*4882a593Smuzhiyun * Since so much of the code is cloned from other modules (compare
67*4882a593Smuzhiyun * opcode #00 to opcode #01), making the basic operations subroutine
68*4882a593Smuzhiyun * calls is especially important; otherwise mistakes in coding an
69*4882a593Smuzhiyun * "add" would represent a nightmare in maintenance.
70*4882a593Smuzhiyun *
71*4882a593Smuzhiyun ****************************************************************************/
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun #include "x86emu/x86emui.h"
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun /*----------------------------- Implementation ----------------------------*/
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun /****************************************************************************
78*4882a593Smuzhiyun PARAMETERS:
79*4882a593Smuzhiyun op1 - Instruction op code
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun REMARKS:
82*4882a593Smuzhiyun Handles illegal opcodes.
83*4882a593Smuzhiyun ****************************************************************************/
84*4882a593Smuzhiyun static void
x86emuOp_illegal_op(u8 op1)85*4882a593Smuzhiyun x86emuOp_illegal_op(u8 op1)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun     START_OF_INSTR();
88*4882a593Smuzhiyun     if (M.x86.R_SP != 0) {
89*4882a593Smuzhiyun         DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
90*4882a593Smuzhiyun         TRACE_REGS();
91*4882a593Smuzhiyun         DB(printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
92*4882a593Smuzhiyun                   M.x86.R_CS, M.x86.R_IP - 1, op1));
93*4882a593Smuzhiyun         HALT_SYS();
94*4882a593Smuzhiyun     }
95*4882a593Smuzhiyun     else {
96*4882a593Smuzhiyun         /* If we get here, it means the stack pointer is back to zero
97*4882a593Smuzhiyun          * so we are just returning from an emulator service call
98*4882a593Smuzhiyun          * so therte is no need to display an error message. We trap
99*4882a593Smuzhiyun          * the emulator with an 0xF1 opcode to finish the service
100*4882a593Smuzhiyun          * call.
101*4882a593Smuzhiyun          */
102*4882a593Smuzhiyun         X86EMU_halt_sys();
103*4882a593Smuzhiyun     }
104*4882a593Smuzhiyun     END_OF_INSTR();
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /****************************************************************************
108*4882a593Smuzhiyun REMARKS:
109*4882a593Smuzhiyun Handles opcode 0x00
110*4882a593Smuzhiyun ****************************************************************************/
111*4882a593Smuzhiyun static void
x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED (op1))112*4882a593Smuzhiyun x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun     int mod, rl, rh;
115*4882a593Smuzhiyun     uint destoffset;
116*4882a593Smuzhiyun     u8 *destreg, *srcreg;
117*4882a593Smuzhiyun     u8 destval;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun     START_OF_INSTR();
120*4882a593Smuzhiyun     DECODE_PRINTF("ADD\t");
121*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
122*4882a593Smuzhiyun     switch (mod) {
123*4882a593Smuzhiyun     case 0:
124*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
125*4882a593Smuzhiyun         DECODE_PRINTF(",");
126*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
127*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
128*4882a593Smuzhiyun         DECODE_PRINTF("\n");
129*4882a593Smuzhiyun         TRACE_AND_STEP();
130*4882a593Smuzhiyun         destval = add_byte(destval, *srcreg);
131*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
132*4882a593Smuzhiyun         break;
133*4882a593Smuzhiyun     case 1:
134*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
135*4882a593Smuzhiyun         DECODE_PRINTF(",");
136*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
137*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
138*4882a593Smuzhiyun         DECODE_PRINTF("\n");
139*4882a593Smuzhiyun         TRACE_AND_STEP();
140*4882a593Smuzhiyun         destval = add_byte(destval, *srcreg);
141*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
142*4882a593Smuzhiyun         break;
143*4882a593Smuzhiyun     case 2:
144*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
145*4882a593Smuzhiyun         DECODE_PRINTF(",");
146*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
147*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
148*4882a593Smuzhiyun         DECODE_PRINTF("\n");
149*4882a593Smuzhiyun         TRACE_AND_STEP();
150*4882a593Smuzhiyun         destval = add_byte(destval, *srcreg);
151*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
152*4882a593Smuzhiyun         break;
153*4882a593Smuzhiyun     case 3:                    /* register to register */
154*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
155*4882a593Smuzhiyun         DECODE_PRINTF(",");
156*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
157*4882a593Smuzhiyun         DECODE_PRINTF("\n");
158*4882a593Smuzhiyun         TRACE_AND_STEP();
159*4882a593Smuzhiyun         *destreg = add_byte(*destreg, *srcreg);
160*4882a593Smuzhiyun         break;
161*4882a593Smuzhiyun     }
162*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
163*4882a593Smuzhiyun     END_OF_INSTR();
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun /****************************************************************************
167*4882a593Smuzhiyun REMARKS:
168*4882a593Smuzhiyun Handles opcode 0x01
169*4882a593Smuzhiyun ****************************************************************************/
170*4882a593Smuzhiyun static void
x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED (op1))171*4882a593Smuzhiyun x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun     int mod, rl, rh;
174*4882a593Smuzhiyun     uint destoffset;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun     START_OF_INSTR();
177*4882a593Smuzhiyun     DECODE_PRINTF("ADD\t");
178*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
179*4882a593Smuzhiyun     switch (mod) {
180*4882a593Smuzhiyun     case 0:
181*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
182*4882a593Smuzhiyun             u32 destval;
183*4882a593Smuzhiyun             u32 *srcreg;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
186*4882a593Smuzhiyun             DECODE_PRINTF(",");
187*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
188*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
189*4882a593Smuzhiyun             DECODE_PRINTF("\n");
190*4882a593Smuzhiyun             TRACE_AND_STEP();
191*4882a593Smuzhiyun             destval = add_long(destval, *srcreg);
192*4882a593Smuzhiyun             store_data_long(destoffset, destval);
193*4882a593Smuzhiyun         }
194*4882a593Smuzhiyun         else {
195*4882a593Smuzhiyun             u16 destval;
196*4882a593Smuzhiyun             u16 *srcreg;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
199*4882a593Smuzhiyun             DECODE_PRINTF(",");
200*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
201*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
202*4882a593Smuzhiyun             DECODE_PRINTF("\n");
203*4882a593Smuzhiyun             TRACE_AND_STEP();
204*4882a593Smuzhiyun             destval = add_word(destval, *srcreg);
205*4882a593Smuzhiyun             store_data_word(destoffset, destval);
206*4882a593Smuzhiyun         }
207*4882a593Smuzhiyun         break;
208*4882a593Smuzhiyun     case 1:
209*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
210*4882a593Smuzhiyun             u32 destval;
211*4882a593Smuzhiyun             u32 *srcreg;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
214*4882a593Smuzhiyun             DECODE_PRINTF(",");
215*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
216*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
217*4882a593Smuzhiyun             DECODE_PRINTF("\n");
218*4882a593Smuzhiyun             TRACE_AND_STEP();
219*4882a593Smuzhiyun             destval = add_long(destval, *srcreg);
220*4882a593Smuzhiyun             store_data_long(destoffset, destval);
221*4882a593Smuzhiyun         }
222*4882a593Smuzhiyun         else {
223*4882a593Smuzhiyun             u16 destval;
224*4882a593Smuzhiyun             u16 *srcreg;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
227*4882a593Smuzhiyun             DECODE_PRINTF(",");
228*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
229*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
230*4882a593Smuzhiyun             DECODE_PRINTF("\n");
231*4882a593Smuzhiyun             TRACE_AND_STEP();
232*4882a593Smuzhiyun             destval = add_word(destval, *srcreg);
233*4882a593Smuzhiyun             store_data_word(destoffset, destval);
234*4882a593Smuzhiyun         }
235*4882a593Smuzhiyun         break;
236*4882a593Smuzhiyun     case 2:
237*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
238*4882a593Smuzhiyun             u32 destval;
239*4882a593Smuzhiyun             u32 *srcreg;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
242*4882a593Smuzhiyun             DECODE_PRINTF(",");
243*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
244*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
245*4882a593Smuzhiyun             DECODE_PRINTF("\n");
246*4882a593Smuzhiyun             TRACE_AND_STEP();
247*4882a593Smuzhiyun             destval = add_long(destval, *srcreg);
248*4882a593Smuzhiyun             store_data_long(destoffset, destval);
249*4882a593Smuzhiyun         }
250*4882a593Smuzhiyun         else {
251*4882a593Smuzhiyun             u16 destval;
252*4882a593Smuzhiyun             u16 *srcreg;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
255*4882a593Smuzhiyun             DECODE_PRINTF(",");
256*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
257*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
258*4882a593Smuzhiyun             DECODE_PRINTF("\n");
259*4882a593Smuzhiyun             TRACE_AND_STEP();
260*4882a593Smuzhiyun             destval = add_word(destval, *srcreg);
261*4882a593Smuzhiyun             store_data_word(destoffset, destval);
262*4882a593Smuzhiyun         }
263*4882a593Smuzhiyun         break;
264*4882a593Smuzhiyun     case 3:                    /* register to register */
265*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
266*4882a593Smuzhiyun             u32 *destreg, *srcreg;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
269*4882a593Smuzhiyun             DECODE_PRINTF(",");
270*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
271*4882a593Smuzhiyun             DECODE_PRINTF("\n");
272*4882a593Smuzhiyun             TRACE_AND_STEP();
273*4882a593Smuzhiyun             *destreg = add_long(*destreg, *srcreg);
274*4882a593Smuzhiyun         }
275*4882a593Smuzhiyun         else {
276*4882a593Smuzhiyun             u16 *destreg, *srcreg;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
279*4882a593Smuzhiyun             DECODE_PRINTF(",");
280*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
281*4882a593Smuzhiyun             DECODE_PRINTF("\n");
282*4882a593Smuzhiyun             TRACE_AND_STEP();
283*4882a593Smuzhiyun             *destreg = add_word(*destreg, *srcreg);
284*4882a593Smuzhiyun         }
285*4882a593Smuzhiyun         break;
286*4882a593Smuzhiyun     }
287*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
288*4882a593Smuzhiyun     END_OF_INSTR();
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun /****************************************************************************
292*4882a593Smuzhiyun REMARKS:
293*4882a593Smuzhiyun Handles opcode 0x02
294*4882a593Smuzhiyun ****************************************************************************/
295*4882a593Smuzhiyun static void
x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED (op1))296*4882a593Smuzhiyun x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
297*4882a593Smuzhiyun {
298*4882a593Smuzhiyun     int mod, rl, rh;
299*4882a593Smuzhiyun     u8 *destreg, *srcreg;
300*4882a593Smuzhiyun     uint srcoffset;
301*4882a593Smuzhiyun     u8 srcval;
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun     START_OF_INSTR();
304*4882a593Smuzhiyun     DECODE_PRINTF("ADD\t");
305*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
306*4882a593Smuzhiyun     switch (mod) {
307*4882a593Smuzhiyun     case 0:
308*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
309*4882a593Smuzhiyun         DECODE_PRINTF(",");
310*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
311*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
312*4882a593Smuzhiyun         DECODE_PRINTF("\n");
313*4882a593Smuzhiyun         TRACE_AND_STEP();
314*4882a593Smuzhiyun         *destreg = add_byte(*destreg, srcval);
315*4882a593Smuzhiyun         break;
316*4882a593Smuzhiyun     case 1:
317*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
318*4882a593Smuzhiyun         DECODE_PRINTF(",");
319*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
320*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
321*4882a593Smuzhiyun         DECODE_PRINTF("\n");
322*4882a593Smuzhiyun         TRACE_AND_STEP();
323*4882a593Smuzhiyun         *destreg = add_byte(*destreg, srcval);
324*4882a593Smuzhiyun         break;
325*4882a593Smuzhiyun     case 2:
326*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
327*4882a593Smuzhiyun         DECODE_PRINTF(",");
328*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
329*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
330*4882a593Smuzhiyun         DECODE_PRINTF("\n");
331*4882a593Smuzhiyun         TRACE_AND_STEP();
332*4882a593Smuzhiyun         *destreg = add_byte(*destreg, srcval);
333*4882a593Smuzhiyun         break;
334*4882a593Smuzhiyun     case 3:                    /* register to register */
335*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
336*4882a593Smuzhiyun         DECODE_PRINTF(",");
337*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rl);
338*4882a593Smuzhiyun         DECODE_PRINTF("\n");
339*4882a593Smuzhiyun         TRACE_AND_STEP();
340*4882a593Smuzhiyun         *destreg = add_byte(*destreg, *srcreg);
341*4882a593Smuzhiyun         break;
342*4882a593Smuzhiyun     }
343*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
344*4882a593Smuzhiyun     END_OF_INSTR();
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun /****************************************************************************
348*4882a593Smuzhiyun REMARKS:
349*4882a593Smuzhiyun Handles opcode 0x03
350*4882a593Smuzhiyun ****************************************************************************/
351*4882a593Smuzhiyun static void
x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED (op1))352*4882a593Smuzhiyun x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
353*4882a593Smuzhiyun {
354*4882a593Smuzhiyun     int mod, rl, rh;
355*4882a593Smuzhiyun     uint srcoffset;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun     START_OF_INSTR();
358*4882a593Smuzhiyun     DECODE_PRINTF("ADD\t");
359*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
360*4882a593Smuzhiyun     switch (mod) {
361*4882a593Smuzhiyun     case 0:
362*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
363*4882a593Smuzhiyun             u32 *destreg;
364*4882a593Smuzhiyun             u32 srcval;
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
367*4882a593Smuzhiyun             DECODE_PRINTF(",");
368*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
369*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
370*4882a593Smuzhiyun             DECODE_PRINTF("\n");
371*4882a593Smuzhiyun             TRACE_AND_STEP();
372*4882a593Smuzhiyun             *destreg = add_long(*destreg, srcval);
373*4882a593Smuzhiyun         }
374*4882a593Smuzhiyun         else {
375*4882a593Smuzhiyun             u16 *destreg;
376*4882a593Smuzhiyun             u16 srcval;
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
379*4882a593Smuzhiyun             DECODE_PRINTF(",");
380*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
381*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
382*4882a593Smuzhiyun             DECODE_PRINTF("\n");
383*4882a593Smuzhiyun             TRACE_AND_STEP();
384*4882a593Smuzhiyun             *destreg = add_word(*destreg, srcval);
385*4882a593Smuzhiyun         }
386*4882a593Smuzhiyun         break;
387*4882a593Smuzhiyun     case 1:
388*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
389*4882a593Smuzhiyun             u32 *destreg;
390*4882a593Smuzhiyun             u32 srcval;
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
393*4882a593Smuzhiyun             DECODE_PRINTF(",");
394*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
395*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
396*4882a593Smuzhiyun             DECODE_PRINTF("\n");
397*4882a593Smuzhiyun             TRACE_AND_STEP();
398*4882a593Smuzhiyun             *destreg = add_long(*destreg, srcval);
399*4882a593Smuzhiyun         }
400*4882a593Smuzhiyun         else {
401*4882a593Smuzhiyun             u16 *destreg;
402*4882a593Smuzhiyun             u16 srcval;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
405*4882a593Smuzhiyun             DECODE_PRINTF(",");
406*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
407*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
408*4882a593Smuzhiyun             DECODE_PRINTF("\n");
409*4882a593Smuzhiyun             TRACE_AND_STEP();
410*4882a593Smuzhiyun             *destreg = add_word(*destreg, srcval);
411*4882a593Smuzhiyun         }
412*4882a593Smuzhiyun         break;
413*4882a593Smuzhiyun     case 2:
414*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
415*4882a593Smuzhiyun             u32 *destreg;
416*4882a593Smuzhiyun             u32 srcval;
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
419*4882a593Smuzhiyun             DECODE_PRINTF(",");
420*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
421*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
422*4882a593Smuzhiyun             DECODE_PRINTF("\n");
423*4882a593Smuzhiyun             TRACE_AND_STEP();
424*4882a593Smuzhiyun             *destreg = add_long(*destreg, srcval);
425*4882a593Smuzhiyun         }
426*4882a593Smuzhiyun         else {
427*4882a593Smuzhiyun             u16 *destreg;
428*4882a593Smuzhiyun             u16 srcval;
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
431*4882a593Smuzhiyun             DECODE_PRINTF(",");
432*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
433*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
434*4882a593Smuzhiyun             DECODE_PRINTF("\n");
435*4882a593Smuzhiyun             TRACE_AND_STEP();
436*4882a593Smuzhiyun             *destreg = add_word(*destreg, srcval);
437*4882a593Smuzhiyun         }
438*4882a593Smuzhiyun         break;
439*4882a593Smuzhiyun     case 3:                    /* register to register */
440*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
441*4882a593Smuzhiyun             u32 *destreg, *srcreg;
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
444*4882a593Smuzhiyun             DECODE_PRINTF(",");
445*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
446*4882a593Smuzhiyun             DECODE_PRINTF("\n");
447*4882a593Smuzhiyun             TRACE_AND_STEP();
448*4882a593Smuzhiyun             *destreg = add_long(*destreg, *srcreg);
449*4882a593Smuzhiyun         }
450*4882a593Smuzhiyun         else {
451*4882a593Smuzhiyun             u16 *destreg, *srcreg;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
454*4882a593Smuzhiyun             DECODE_PRINTF(",");
455*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
456*4882a593Smuzhiyun             DECODE_PRINTF("\n");
457*4882a593Smuzhiyun             TRACE_AND_STEP();
458*4882a593Smuzhiyun             *destreg = add_word(*destreg, *srcreg);
459*4882a593Smuzhiyun         }
460*4882a593Smuzhiyun         break;
461*4882a593Smuzhiyun     }
462*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
463*4882a593Smuzhiyun     END_OF_INSTR();
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun /****************************************************************************
467*4882a593Smuzhiyun REMARKS:
468*4882a593Smuzhiyun Handles opcode 0x04
469*4882a593Smuzhiyun ****************************************************************************/
470*4882a593Smuzhiyun static void
x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED (op1))471*4882a593Smuzhiyun x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
472*4882a593Smuzhiyun {
473*4882a593Smuzhiyun     u8 srcval;
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun     START_OF_INSTR();
476*4882a593Smuzhiyun     DECODE_PRINTF("ADD\tAL,");
477*4882a593Smuzhiyun     srcval = fetch_byte_imm();
478*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
479*4882a593Smuzhiyun     TRACE_AND_STEP();
480*4882a593Smuzhiyun     M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
481*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
482*4882a593Smuzhiyun     END_OF_INSTR();
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun /****************************************************************************
486*4882a593Smuzhiyun REMARKS:
487*4882a593Smuzhiyun Handles opcode 0x05
488*4882a593Smuzhiyun ****************************************************************************/
489*4882a593Smuzhiyun static void
x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED (op1))490*4882a593Smuzhiyun x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
491*4882a593Smuzhiyun {
492*4882a593Smuzhiyun     u32 srcval;
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun     START_OF_INSTR();
495*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
496*4882a593Smuzhiyun         DECODE_PRINTF("ADD\tEAX,");
497*4882a593Smuzhiyun         srcval = fetch_long_imm();
498*4882a593Smuzhiyun     }
499*4882a593Smuzhiyun     else {
500*4882a593Smuzhiyun         DECODE_PRINTF("ADD\tAX,");
501*4882a593Smuzhiyun         srcval = fetch_word_imm();
502*4882a593Smuzhiyun     }
503*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
504*4882a593Smuzhiyun     TRACE_AND_STEP();
505*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
506*4882a593Smuzhiyun         M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
507*4882a593Smuzhiyun     }
508*4882a593Smuzhiyun     else {
509*4882a593Smuzhiyun         M.x86.R_AX = add_word(M.x86.R_AX, (u16) srcval);
510*4882a593Smuzhiyun     }
511*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
512*4882a593Smuzhiyun     END_OF_INSTR();
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun /****************************************************************************
516*4882a593Smuzhiyun REMARKS:
517*4882a593Smuzhiyun Handles opcode 0x06
518*4882a593Smuzhiyun ****************************************************************************/
519*4882a593Smuzhiyun static void
x86emuOp_push_ES(u8 X86EMU_UNUSED (op1))520*4882a593Smuzhiyun x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun     START_OF_INSTR();
523*4882a593Smuzhiyun     DECODE_PRINTF("PUSH\tES\n");
524*4882a593Smuzhiyun     TRACE_AND_STEP();
525*4882a593Smuzhiyun     push_word(M.x86.R_ES);
526*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
527*4882a593Smuzhiyun     END_OF_INSTR();
528*4882a593Smuzhiyun }
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun /****************************************************************************
531*4882a593Smuzhiyun REMARKS:
532*4882a593Smuzhiyun Handles opcode 0x07
533*4882a593Smuzhiyun ****************************************************************************/
534*4882a593Smuzhiyun static void
x86emuOp_pop_ES(u8 X86EMU_UNUSED (op1))535*4882a593Smuzhiyun x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
536*4882a593Smuzhiyun {
537*4882a593Smuzhiyun     START_OF_INSTR();
538*4882a593Smuzhiyun     DECODE_PRINTF("POP\tES\n");
539*4882a593Smuzhiyun     TRACE_AND_STEP();
540*4882a593Smuzhiyun     M.x86.R_ES = pop_word();
541*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
542*4882a593Smuzhiyun     END_OF_INSTR();
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun /****************************************************************************
546*4882a593Smuzhiyun REMARKS:
547*4882a593Smuzhiyun Handles opcode 0x08
548*4882a593Smuzhiyun ****************************************************************************/
549*4882a593Smuzhiyun static void
x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED (op1))550*4882a593Smuzhiyun x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun     int mod, rl, rh;
553*4882a593Smuzhiyun     u8 *destreg, *srcreg;
554*4882a593Smuzhiyun     uint destoffset;
555*4882a593Smuzhiyun     u8 destval;
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun     START_OF_INSTR();
558*4882a593Smuzhiyun     DECODE_PRINTF("OR\t");
559*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
560*4882a593Smuzhiyun     switch (mod) {
561*4882a593Smuzhiyun     case 0:
562*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
563*4882a593Smuzhiyun         DECODE_PRINTF(",");
564*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
565*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
566*4882a593Smuzhiyun         DECODE_PRINTF("\n");
567*4882a593Smuzhiyun         TRACE_AND_STEP();
568*4882a593Smuzhiyun         destval = or_byte(destval, *srcreg);
569*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
570*4882a593Smuzhiyun         break;
571*4882a593Smuzhiyun     case 1:
572*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
573*4882a593Smuzhiyun         DECODE_PRINTF(",");
574*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
575*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
576*4882a593Smuzhiyun         DECODE_PRINTF("\n");
577*4882a593Smuzhiyun         TRACE_AND_STEP();
578*4882a593Smuzhiyun         destval = or_byte(destval, *srcreg);
579*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
580*4882a593Smuzhiyun         break;
581*4882a593Smuzhiyun     case 2:
582*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
583*4882a593Smuzhiyun         DECODE_PRINTF(",");
584*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
585*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
586*4882a593Smuzhiyun         DECODE_PRINTF("\n");
587*4882a593Smuzhiyun         TRACE_AND_STEP();
588*4882a593Smuzhiyun         destval = or_byte(destval, *srcreg);
589*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
590*4882a593Smuzhiyun         break;
591*4882a593Smuzhiyun     case 3:                    /* register to register */
592*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
593*4882a593Smuzhiyun         DECODE_PRINTF(",");
594*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
595*4882a593Smuzhiyun         DECODE_PRINTF("\n");
596*4882a593Smuzhiyun         TRACE_AND_STEP();
597*4882a593Smuzhiyun         *destreg = or_byte(*destreg, *srcreg);
598*4882a593Smuzhiyun         break;
599*4882a593Smuzhiyun     }
600*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
601*4882a593Smuzhiyun     END_OF_INSTR();
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun /****************************************************************************
605*4882a593Smuzhiyun REMARKS:
606*4882a593Smuzhiyun Handles opcode 0x09
607*4882a593Smuzhiyun ****************************************************************************/
608*4882a593Smuzhiyun static void
x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED (op1))609*4882a593Smuzhiyun x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
610*4882a593Smuzhiyun {
611*4882a593Smuzhiyun     int mod, rl, rh;
612*4882a593Smuzhiyun     uint destoffset;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun     START_OF_INSTR();
615*4882a593Smuzhiyun     DECODE_PRINTF("OR\t");
616*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
617*4882a593Smuzhiyun     switch (mod) {
618*4882a593Smuzhiyun     case 0:
619*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
620*4882a593Smuzhiyun             u32 destval;
621*4882a593Smuzhiyun             u32 *srcreg;
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
624*4882a593Smuzhiyun             DECODE_PRINTF(",");
625*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
626*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
627*4882a593Smuzhiyun             DECODE_PRINTF("\n");
628*4882a593Smuzhiyun             TRACE_AND_STEP();
629*4882a593Smuzhiyun             destval = or_long(destval, *srcreg);
630*4882a593Smuzhiyun             store_data_long(destoffset, destval);
631*4882a593Smuzhiyun         }
632*4882a593Smuzhiyun         else {
633*4882a593Smuzhiyun             u16 destval;
634*4882a593Smuzhiyun             u16 *srcreg;
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
637*4882a593Smuzhiyun             DECODE_PRINTF(",");
638*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
639*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
640*4882a593Smuzhiyun             DECODE_PRINTF("\n");
641*4882a593Smuzhiyun             TRACE_AND_STEP();
642*4882a593Smuzhiyun             destval = or_word(destval, *srcreg);
643*4882a593Smuzhiyun             store_data_word(destoffset, destval);
644*4882a593Smuzhiyun         }
645*4882a593Smuzhiyun         break;
646*4882a593Smuzhiyun     case 1:
647*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
648*4882a593Smuzhiyun             u32 destval;
649*4882a593Smuzhiyun             u32 *srcreg;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
652*4882a593Smuzhiyun             DECODE_PRINTF(",");
653*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
654*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
655*4882a593Smuzhiyun             DECODE_PRINTF("\n");
656*4882a593Smuzhiyun             TRACE_AND_STEP();
657*4882a593Smuzhiyun             destval = or_long(destval, *srcreg);
658*4882a593Smuzhiyun             store_data_long(destoffset, destval);
659*4882a593Smuzhiyun         }
660*4882a593Smuzhiyun         else {
661*4882a593Smuzhiyun             u16 destval;
662*4882a593Smuzhiyun             u16 *srcreg;
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
665*4882a593Smuzhiyun             DECODE_PRINTF(",");
666*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
667*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
668*4882a593Smuzhiyun             DECODE_PRINTF("\n");
669*4882a593Smuzhiyun             TRACE_AND_STEP();
670*4882a593Smuzhiyun             destval = or_word(destval, *srcreg);
671*4882a593Smuzhiyun             store_data_word(destoffset, destval);
672*4882a593Smuzhiyun         }
673*4882a593Smuzhiyun         break;
674*4882a593Smuzhiyun     case 2:
675*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
676*4882a593Smuzhiyun             u32 destval;
677*4882a593Smuzhiyun             u32 *srcreg;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
680*4882a593Smuzhiyun             DECODE_PRINTF(",");
681*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
682*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
683*4882a593Smuzhiyun             DECODE_PRINTF("\n");
684*4882a593Smuzhiyun             TRACE_AND_STEP();
685*4882a593Smuzhiyun             destval = or_long(destval, *srcreg);
686*4882a593Smuzhiyun             store_data_long(destoffset, destval);
687*4882a593Smuzhiyun         }
688*4882a593Smuzhiyun         else {
689*4882a593Smuzhiyun             u16 destval;
690*4882a593Smuzhiyun             u16 *srcreg;
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
693*4882a593Smuzhiyun             DECODE_PRINTF(",");
694*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
695*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
696*4882a593Smuzhiyun             DECODE_PRINTF("\n");
697*4882a593Smuzhiyun             TRACE_AND_STEP();
698*4882a593Smuzhiyun             destval = or_word(destval, *srcreg);
699*4882a593Smuzhiyun             store_data_word(destoffset, destval);
700*4882a593Smuzhiyun         }
701*4882a593Smuzhiyun         break;
702*4882a593Smuzhiyun     case 3:                    /* register to register */
703*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
704*4882a593Smuzhiyun             u32 *destreg, *srcreg;
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
707*4882a593Smuzhiyun             DECODE_PRINTF(",");
708*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
709*4882a593Smuzhiyun             DECODE_PRINTF("\n");
710*4882a593Smuzhiyun             TRACE_AND_STEP();
711*4882a593Smuzhiyun             *destreg = or_long(*destreg, *srcreg);
712*4882a593Smuzhiyun         }
713*4882a593Smuzhiyun         else {
714*4882a593Smuzhiyun             u16 *destreg, *srcreg;
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
717*4882a593Smuzhiyun             DECODE_PRINTF(",");
718*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
719*4882a593Smuzhiyun             DECODE_PRINTF("\n");
720*4882a593Smuzhiyun             TRACE_AND_STEP();
721*4882a593Smuzhiyun             *destreg = or_word(*destreg, *srcreg);
722*4882a593Smuzhiyun         }
723*4882a593Smuzhiyun         break;
724*4882a593Smuzhiyun     }
725*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
726*4882a593Smuzhiyun     END_OF_INSTR();
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun /****************************************************************************
730*4882a593Smuzhiyun REMARKS:
731*4882a593Smuzhiyun Handles opcode 0x0a
732*4882a593Smuzhiyun ****************************************************************************/
733*4882a593Smuzhiyun static void
x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED (op1))734*4882a593Smuzhiyun x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
735*4882a593Smuzhiyun {
736*4882a593Smuzhiyun     int mod, rl, rh;
737*4882a593Smuzhiyun     u8 *destreg, *srcreg;
738*4882a593Smuzhiyun     uint srcoffset;
739*4882a593Smuzhiyun     u8 srcval;
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun     START_OF_INSTR();
742*4882a593Smuzhiyun     DECODE_PRINTF("OR\t");
743*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
744*4882a593Smuzhiyun     switch (mod) {
745*4882a593Smuzhiyun     case 0:
746*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
747*4882a593Smuzhiyun         DECODE_PRINTF(",");
748*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
749*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
750*4882a593Smuzhiyun         DECODE_PRINTF("\n");
751*4882a593Smuzhiyun         TRACE_AND_STEP();
752*4882a593Smuzhiyun         *destreg = or_byte(*destreg, srcval);
753*4882a593Smuzhiyun         break;
754*4882a593Smuzhiyun     case 1:
755*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
756*4882a593Smuzhiyun         DECODE_PRINTF(",");
757*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
758*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
759*4882a593Smuzhiyun         DECODE_PRINTF("\n");
760*4882a593Smuzhiyun         TRACE_AND_STEP();
761*4882a593Smuzhiyun         *destreg = or_byte(*destreg, srcval);
762*4882a593Smuzhiyun         break;
763*4882a593Smuzhiyun     case 2:
764*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
765*4882a593Smuzhiyun         DECODE_PRINTF(",");
766*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
767*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
768*4882a593Smuzhiyun         DECODE_PRINTF("\n");
769*4882a593Smuzhiyun         TRACE_AND_STEP();
770*4882a593Smuzhiyun         *destreg = or_byte(*destreg, srcval);
771*4882a593Smuzhiyun         break;
772*4882a593Smuzhiyun     case 3:                    /* register to register */
773*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
774*4882a593Smuzhiyun         DECODE_PRINTF(",");
775*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rl);
776*4882a593Smuzhiyun         DECODE_PRINTF("\n");
777*4882a593Smuzhiyun         TRACE_AND_STEP();
778*4882a593Smuzhiyun         *destreg = or_byte(*destreg, *srcreg);
779*4882a593Smuzhiyun         break;
780*4882a593Smuzhiyun     }
781*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
782*4882a593Smuzhiyun     END_OF_INSTR();
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun /****************************************************************************
786*4882a593Smuzhiyun REMARKS:
787*4882a593Smuzhiyun Handles opcode 0x0b
788*4882a593Smuzhiyun ****************************************************************************/
789*4882a593Smuzhiyun static void
x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED (op1))790*4882a593Smuzhiyun x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
791*4882a593Smuzhiyun {
792*4882a593Smuzhiyun     int mod, rl, rh;
793*4882a593Smuzhiyun     uint srcoffset;
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun     START_OF_INSTR();
796*4882a593Smuzhiyun     DECODE_PRINTF("OR\t");
797*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
798*4882a593Smuzhiyun     switch (mod) {
799*4882a593Smuzhiyun     case 0:
800*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
801*4882a593Smuzhiyun             u32 *destreg;
802*4882a593Smuzhiyun             u32 srcval;
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
805*4882a593Smuzhiyun             DECODE_PRINTF(",");
806*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
807*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
808*4882a593Smuzhiyun             DECODE_PRINTF("\n");
809*4882a593Smuzhiyun             TRACE_AND_STEP();
810*4882a593Smuzhiyun             *destreg = or_long(*destreg, srcval);
811*4882a593Smuzhiyun         }
812*4882a593Smuzhiyun         else {
813*4882a593Smuzhiyun             u16 *destreg;
814*4882a593Smuzhiyun             u16 srcval;
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
817*4882a593Smuzhiyun             DECODE_PRINTF(",");
818*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
819*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
820*4882a593Smuzhiyun             DECODE_PRINTF("\n");
821*4882a593Smuzhiyun             TRACE_AND_STEP();
822*4882a593Smuzhiyun             *destreg = or_word(*destreg, srcval);
823*4882a593Smuzhiyun         }
824*4882a593Smuzhiyun         break;
825*4882a593Smuzhiyun     case 1:
826*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
827*4882a593Smuzhiyun             u32 *destreg;
828*4882a593Smuzhiyun             u32 srcval;
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
831*4882a593Smuzhiyun             DECODE_PRINTF(",");
832*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
833*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
834*4882a593Smuzhiyun             DECODE_PRINTF("\n");
835*4882a593Smuzhiyun             TRACE_AND_STEP();
836*4882a593Smuzhiyun             *destreg = or_long(*destreg, srcval);
837*4882a593Smuzhiyun         }
838*4882a593Smuzhiyun         else {
839*4882a593Smuzhiyun             u16 *destreg;
840*4882a593Smuzhiyun             u16 srcval;
841*4882a593Smuzhiyun 
842*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
843*4882a593Smuzhiyun             DECODE_PRINTF(",");
844*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
845*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
846*4882a593Smuzhiyun             DECODE_PRINTF("\n");
847*4882a593Smuzhiyun             TRACE_AND_STEP();
848*4882a593Smuzhiyun             *destreg = or_word(*destreg, srcval);
849*4882a593Smuzhiyun         }
850*4882a593Smuzhiyun         break;
851*4882a593Smuzhiyun     case 2:
852*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
853*4882a593Smuzhiyun             u32 *destreg;
854*4882a593Smuzhiyun             u32 srcval;
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
857*4882a593Smuzhiyun             DECODE_PRINTF(",");
858*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
859*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
860*4882a593Smuzhiyun             DECODE_PRINTF("\n");
861*4882a593Smuzhiyun             TRACE_AND_STEP();
862*4882a593Smuzhiyun             *destreg = or_long(*destreg, srcval);
863*4882a593Smuzhiyun         }
864*4882a593Smuzhiyun         else {
865*4882a593Smuzhiyun             u16 *destreg;
866*4882a593Smuzhiyun             u16 srcval;
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
869*4882a593Smuzhiyun             DECODE_PRINTF(",");
870*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
871*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
872*4882a593Smuzhiyun             DECODE_PRINTF("\n");
873*4882a593Smuzhiyun             TRACE_AND_STEP();
874*4882a593Smuzhiyun             *destreg = or_word(*destreg, srcval);
875*4882a593Smuzhiyun         }
876*4882a593Smuzhiyun         break;
877*4882a593Smuzhiyun     case 3:                    /* register to register */
878*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
879*4882a593Smuzhiyun             u32 *destreg, *srcreg;
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
882*4882a593Smuzhiyun             DECODE_PRINTF(",");
883*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
884*4882a593Smuzhiyun             DECODE_PRINTF("\n");
885*4882a593Smuzhiyun             TRACE_AND_STEP();
886*4882a593Smuzhiyun             *destreg = or_long(*destreg, *srcreg);
887*4882a593Smuzhiyun         }
888*4882a593Smuzhiyun         else {
889*4882a593Smuzhiyun             u16 *destreg, *srcreg;
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
892*4882a593Smuzhiyun             DECODE_PRINTF(",");
893*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
894*4882a593Smuzhiyun             DECODE_PRINTF("\n");
895*4882a593Smuzhiyun             TRACE_AND_STEP();
896*4882a593Smuzhiyun             *destreg = or_word(*destreg, *srcreg);
897*4882a593Smuzhiyun         }
898*4882a593Smuzhiyun         break;
899*4882a593Smuzhiyun     }
900*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
901*4882a593Smuzhiyun     END_OF_INSTR();
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun /****************************************************************************
905*4882a593Smuzhiyun REMARKS:
906*4882a593Smuzhiyun Handles opcode 0x0c
907*4882a593Smuzhiyun ****************************************************************************/
908*4882a593Smuzhiyun static void
x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED (op1))909*4882a593Smuzhiyun x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
910*4882a593Smuzhiyun {
911*4882a593Smuzhiyun     u8 srcval;
912*4882a593Smuzhiyun 
913*4882a593Smuzhiyun     START_OF_INSTR();
914*4882a593Smuzhiyun     DECODE_PRINTF("OR\tAL,");
915*4882a593Smuzhiyun     srcval = fetch_byte_imm();
916*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
917*4882a593Smuzhiyun     TRACE_AND_STEP();
918*4882a593Smuzhiyun     M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
919*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
920*4882a593Smuzhiyun     END_OF_INSTR();
921*4882a593Smuzhiyun }
922*4882a593Smuzhiyun 
923*4882a593Smuzhiyun /****************************************************************************
924*4882a593Smuzhiyun REMARKS:
925*4882a593Smuzhiyun Handles opcode 0x0d
926*4882a593Smuzhiyun ****************************************************************************/
927*4882a593Smuzhiyun static void
x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED (op1))928*4882a593Smuzhiyun x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
929*4882a593Smuzhiyun {
930*4882a593Smuzhiyun     u32 srcval;
931*4882a593Smuzhiyun 
932*4882a593Smuzhiyun     START_OF_INSTR();
933*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
934*4882a593Smuzhiyun         DECODE_PRINTF("OR\tEAX,");
935*4882a593Smuzhiyun         srcval = fetch_long_imm();
936*4882a593Smuzhiyun     }
937*4882a593Smuzhiyun     else {
938*4882a593Smuzhiyun         DECODE_PRINTF("OR\tAX,");
939*4882a593Smuzhiyun         srcval = fetch_word_imm();
940*4882a593Smuzhiyun     }
941*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
942*4882a593Smuzhiyun     TRACE_AND_STEP();
943*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
944*4882a593Smuzhiyun         M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
945*4882a593Smuzhiyun     }
946*4882a593Smuzhiyun     else {
947*4882a593Smuzhiyun         M.x86.R_AX = or_word(M.x86.R_AX, (u16) srcval);
948*4882a593Smuzhiyun     }
949*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
950*4882a593Smuzhiyun     END_OF_INSTR();
951*4882a593Smuzhiyun }
952*4882a593Smuzhiyun 
953*4882a593Smuzhiyun /****************************************************************************
954*4882a593Smuzhiyun REMARKS:
955*4882a593Smuzhiyun Handles opcode 0x0e
956*4882a593Smuzhiyun ****************************************************************************/
957*4882a593Smuzhiyun static void
x86emuOp_push_CS(u8 X86EMU_UNUSED (op1))958*4882a593Smuzhiyun x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
959*4882a593Smuzhiyun {
960*4882a593Smuzhiyun     START_OF_INSTR();
961*4882a593Smuzhiyun     DECODE_PRINTF("PUSH\tCS\n");
962*4882a593Smuzhiyun     TRACE_AND_STEP();
963*4882a593Smuzhiyun     push_word(M.x86.R_CS);
964*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
965*4882a593Smuzhiyun     END_OF_INSTR();
966*4882a593Smuzhiyun }
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun /****************************************************************************
969*4882a593Smuzhiyun REMARKS:
970*4882a593Smuzhiyun Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
971*4882a593Smuzhiyun ****************************************************************************/
972*4882a593Smuzhiyun static void
x86emuOp_two_byte(u8 X86EMU_UNUSED (op1))973*4882a593Smuzhiyun x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
974*4882a593Smuzhiyun {
975*4882a593Smuzhiyun     u8 op2 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
976*4882a593Smuzhiyun 
977*4882a593Smuzhiyun     INC_DECODED_INST_LEN(1);
978*4882a593Smuzhiyun     (*x86emu_optab2[op2]) (op2);
979*4882a593Smuzhiyun }
980*4882a593Smuzhiyun 
981*4882a593Smuzhiyun /****************************************************************************
982*4882a593Smuzhiyun REMARKS:
983*4882a593Smuzhiyun Handles opcode 0x10
984*4882a593Smuzhiyun ****************************************************************************/
985*4882a593Smuzhiyun static void
x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED (op1))986*4882a593Smuzhiyun x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
987*4882a593Smuzhiyun {
988*4882a593Smuzhiyun     int mod, rl, rh;
989*4882a593Smuzhiyun     u8 *destreg, *srcreg;
990*4882a593Smuzhiyun     uint destoffset;
991*4882a593Smuzhiyun     u8 destval;
992*4882a593Smuzhiyun 
993*4882a593Smuzhiyun     START_OF_INSTR();
994*4882a593Smuzhiyun     DECODE_PRINTF("ADC\t");
995*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
996*4882a593Smuzhiyun     switch (mod) {
997*4882a593Smuzhiyun     case 0:
998*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
999*4882a593Smuzhiyun         DECODE_PRINTF(",");
1000*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
1001*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1002*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1003*4882a593Smuzhiyun         TRACE_AND_STEP();
1004*4882a593Smuzhiyun         destval = adc_byte(destval, *srcreg);
1005*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
1006*4882a593Smuzhiyun         break;
1007*4882a593Smuzhiyun     case 1:
1008*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
1009*4882a593Smuzhiyun         DECODE_PRINTF(",");
1010*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
1011*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1012*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1013*4882a593Smuzhiyun         TRACE_AND_STEP();
1014*4882a593Smuzhiyun         destval = adc_byte(destval, *srcreg);
1015*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
1016*4882a593Smuzhiyun         break;
1017*4882a593Smuzhiyun     case 2:
1018*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
1019*4882a593Smuzhiyun         DECODE_PRINTF(",");
1020*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
1021*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1022*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1023*4882a593Smuzhiyun         TRACE_AND_STEP();
1024*4882a593Smuzhiyun         destval = adc_byte(destval, *srcreg);
1025*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
1026*4882a593Smuzhiyun         break;
1027*4882a593Smuzhiyun     case 3:                    /* register to register */
1028*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
1029*4882a593Smuzhiyun         DECODE_PRINTF(",");
1030*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1031*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1032*4882a593Smuzhiyun         TRACE_AND_STEP();
1033*4882a593Smuzhiyun         *destreg = adc_byte(*destreg, *srcreg);
1034*4882a593Smuzhiyun         break;
1035*4882a593Smuzhiyun     }
1036*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1037*4882a593Smuzhiyun     END_OF_INSTR();
1038*4882a593Smuzhiyun }
1039*4882a593Smuzhiyun 
1040*4882a593Smuzhiyun /****************************************************************************
1041*4882a593Smuzhiyun REMARKS:
1042*4882a593Smuzhiyun Handles opcode 0x11
1043*4882a593Smuzhiyun ****************************************************************************/
1044*4882a593Smuzhiyun static void
x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED (op1))1045*4882a593Smuzhiyun x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1046*4882a593Smuzhiyun {
1047*4882a593Smuzhiyun     int mod, rl, rh;
1048*4882a593Smuzhiyun     uint destoffset;
1049*4882a593Smuzhiyun 
1050*4882a593Smuzhiyun     START_OF_INSTR();
1051*4882a593Smuzhiyun     DECODE_PRINTF("ADC\t");
1052*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
1053*4882a593Smuzhiyun     switch (mod) {
1054*4882a593Smuzhiyun     case 0:
1055*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1056*4882a593Smuzhiyun             u32 destval;
1057*4882a593Smuzhiyun             u32 *srcreg;
1058*4882a593Smuzhiyun 
1059*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
1060*4882a593Smuzhiyun             DECODE_PRINTF(",");
1061*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
1062*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1063*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1064*4882a593Smuzhiyun             TRACE_AND_STEP();
1065*4882a593Smuzhiyun             destval = adc_long(destval, *srcreg);
1066*4882a593Smuzhiyun             store_data_long(destoffset, destval);
1067*4882a593Smuzhiyun         }
1068*4882a593Smuzhiyun         else {
1069*4882a593Smuzhiyun             u16 destval;
1070*4882a593Smuzhiyun             u16 *srcreg;
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
1073*4882a593Smuzhiyun             DECODE_PRINTF(",");
1074*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
1075*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
1076*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1077*4882a593Smuzhiyun             TRACE_AND_STEP();
1078*4882a593Smuzhiyun             destval = adc_word(destval, *srcreg);
1079*4882a593Smuzhiyun             store_data_word(destoffset, destval);
1080*4882a593Smuzhiyun         }
1081*4882a593Smuzhiyun         break;
1082*4882a593Smuzhiyun     case 1:
1083*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1084*4882a593Smuzhiyun             u32 destval;
1085*4882a593Smuzhiyun             u32 *srcreg;
1086*4882a593Smuzhiyun 
1087*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
1088*4882a593Smuzhiyun             DECODE_PRINTF(",");
1089*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
1090*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1091*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1092*4882a593Smuzhiyun             TRACE_AND_STEP();
1093*4882a593Smuzhiyun             destval = adc_long(destval, *srcreg);
1094*4882a593Smuzhiyun             store_data_long(destoffset, destval);
1095*4882a593Smuzhiyun         }
1096*4882a593Smuzhiyun         else {
1097*4882a593Smuzhiyun             u16 destval;
1098*4882a593Smuzhiyun             u16 *srcreg;
1099*4882a593Smuzhiyun 
1100*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
1101*4882a593Smuzhiyun             DECODE_PRINTF(",");
1102*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
1103*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
1104*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1105*4882a593Smuzhiyun             TRACE_AND_STEP();
1106*4882a593Smuzhiyun             destval = adc_word(destval, *srcreg);
1107*4882a593Smuzhiyun             store_data_word(destoffset, destval);
1108*4882a593Smuzhiyun         }
1109*4882a593Smuzhiyun         break;
1110*4882a593Smuzhiyun     case 2:
1111*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1112*4882a593Smuzhiyun             u32 destval;
1113*4882a593Smuzhiyun             u32 *srcreg;
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
1116*4882a593Smuzhiyun             DECODE_PRINTF(",");
1117*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
1118*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1119*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1120*4882a593Smuzhiyun             TRACE_AND_STEP();
1121*4882a593Smuzhiyun             destval = adc_long(destval, *srcreg);
1122*4882a593Smuzhiyun             store_data_long(destoffset, destval);
1123*4882a593Smuzhiyun         }
1124*4882a593Smuzhiyun         else {
1125*4882a593Smuzhiyun             u16 destval;
1126*4882a593Smuzhiyun             u16 *srcreg;
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
1129*4882a593Smuzhiyun             DECODE_PRINTF(",");
1130*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
1131*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
1132*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1133*4882a593Smuzhiyun             TRACE_AND_STEP();
1134*4882a593Smuzhiyun             destval = adc_word(destval, *srcreg);
1135*4882a593Smuzhiyun             store_data_word(destoffset, destval);
1136*4882a593Smuzhiyun         }
1137*4882a593Smuzhiyun         break;
1138*4882a593Smuzhiyun     case 3:                    /* register to register */
1139*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1140*4882a593Smuzhiyun             u32 *destreg, *srcreg;
1141*4882a593Smuzhiyun 
1142*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
1143*4882a593Smuzhiyun             DECODE_PRINTF(",");
1144*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1145*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1146*4882a593Smuzhiyun             TRACE_AND_STEP();
1147*4882a593Smuzhiyun             *destreg = adc_long(*destreg, *srcreg);
1148*4882a593Smuzhiyun         }
1149*4882a593Smuzhiyun         else {
1150*4882a593Smuzhiyun             u16 *destreg, *srcreg;
1151*4882a593Smuzhiyun 
1152*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
1153*4882a593Smuzhiyun             DECODE_PRINTF(",");
1154*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
1155*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1156*4882a593Smuzhiyun             TRACE_AND_STEP();
1157*4882a593Smuzhiyun             *destreg = adc_word(*destreg, *srcreg);
1158*4882a593Smuzhiyun         }
1159*4882a593Smuzhiyun         break;
1160*4882a593Smuzhiyun     }
1161*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1162*4882a593Smuzhiyun     END_OF_INSTR();
1163*4882a593Smuzhiyun }
1164*4882a593Smuzhiyun 
1165*4882a593Smuzhiyun /****************************************************************************
1166*4882a593Smuzhiyun REMARKS:
1167*4882a593Smuzhiyun Handles opcode 0x12
1168*4882a593Smuzhiyun ****************************************************************************/
1169*4882a593Smuzhiyun static void
x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED (op1))1170*4882a593Smuzhiyun x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1171*4882a593Smuzhiyun {
1172*4882a593Smuzhiyun     int mod, rl, rh;
1173*4882a593Smuzhiyun     u8 *destreg, *srcreg;
1174*4882a593Smuzhiyun     uint srcoffset;
1175*4882a593Smuzhiyun     u8 srcval;
1176*4882a593Smuzhiyun 
1177*4882a593Smuzhiyun     START_OF_INSTR();
1178*4882a593Smuzhiyun     DECODE_PRINTF("ADC\t");
1179*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
1180*4882a593Smuzhiyun     switch (mod) {
1181*4882a593Smuzhiyun     case 0:
1182*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
1183*4882a593Smuzhiyun         DECODE_PRINTF(",");
1184*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
1185*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
1186*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1187*4882a593Smuzhiyun         TRACE_AND_STEP();
1188*4882a593Smuzhiyun         *destreg = adc_byte(*destreg, srcval);
1189*4882a593Smuzhiyun         break;
1190*4882a593Smuzhiyun     case 1:
1191*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
1192*4882a593Smuzhiyun         DECODE_PRINTF(",");
1193*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
1194*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
1195*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1196*4882a593Smuzhiyun         TRACE_AND_STEP();
1197*4882a593Smuzhiyun         *destreg = adc_byte(*destreg, srcval);
1198*4882a593Smuzhiyun         break;
1199*4882a593Smuzhiyun     case 2:
1200*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
1201*4882a593Smuzhiyun         DECODE_PRINTF(",");
1202*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
1203*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
1204*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1205*4882a593Smuzhiyun         TRACE_AND_STEP();
1206*4882a593Smuzhiyun         *destreg = adc_byte(*destreg, srcval);
1207*4882a593Smuzhiyun         break;
1208*4882a593Smuzhiyun     case 3:                    /* register to register */
1209*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
1210*4882a593Smuzhiyun         DECODE_PRINTF(",");
1211*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rl);
1212*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1213*4882a593Smuzhiyun         TRACE_AND_STEP();
1214*4882a593Smuzhiyun         *destreg = adc_byte(*destreg, *srcreg);
1215*4882a593Smuzhiyun         break;
1216*4882a593Smuzhiyun     }
1217*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1218*4882a593Smuzhiyun     END_OF_INSTR();
1219*4882a593Smuzhiyun }
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun /****************************************************************************
1222*4882a593Smuzhiyun REMARKS:
1223*4882a593Smuzhiyun Handles opcode 0x13
1224*4882a593Smuzhiyun ****************************************************************************/
1225*4882a593Smuzhiyun static void
x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED (op1))1226*4882a593Smuzhiyun x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1227*4882a593Smuzhiyun {
1228*4882a593Smuzhiyun     int mod, rl, rh;
1229*4882a593Smuzhiyun     uint srcoffset;
1230*4882a593Smuzhiyun 
1231*4882a593Smuzhiyun     START_OF_INSTR();
1232*4882a593Smuzhiyun     DECODE_PRINTF("ADC\t");
1233*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
1234*4882a593Smuzhiyun     switch (mod) {
1235*4882a593Smuzhiyun     case 0:
1236*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1237*4882a593Smuzhiyun             u32 *destreg;
1238*4882a593Smuzhiyun             u32 srcval;
1239*4882a593Smuzhiyun 
1240*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
1241*4882a593Smuzhiyun             DECODE_PRINTF(",");
1242*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
1243*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
1244*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1245*4882a593Smuzhiyun             TRACE_AND_STEP();
1246*4882a593Smuzhiyun             *destreg = adc_long(*destreg, srcval);
1247*4882a593Smuzhiyun         }
1248*4882a593Smuzhiyun         else {
1249*4882a593Smuzhiyun             u16 *destreg;
1250*4882a593Smuzhiyun             u16 srcval;
1251*4882a593Smuzhiyun 
1252*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
1253*4882a593Smuzhiyun             DECODE_PRINTF(",");
1254*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
1255*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
1256*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1257*4882a593Smuzhiyun             TRACE_AND_STEP();
1258*4882a593Smuzhiyun             *destreg = adc_word(*destreg, srcval);
1259*4882a593Smuzhiyun         }
1260*4882a593Smuzhiyun         break;
1261*4882a593Smuzhiyun     case 1:
1262*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1263*4882a593Smuzhiyun             u32 *destreg;
1264*4882a593Smuzhiyun             u32 srcval;
1265*4882a593Smuzhiyun 
1266*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
1267*4882a593Smuzhiyun             DECODE_PRINTF(",");
1268*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
1269*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
1270*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1271*4882a593Smuzhiyun             TRACE_AND_STEP();
1272*4882a593Smuzhiyun             *destreg = adc_long(*destreg, srcval);
1273*4882a593Smuzhiyun         }
1274*4882a593Smuzhiyun         else {
1275*4882a593Smuzhiyun             u16 *destreg;
1276*4882a593Smuzhiyun             u16 srcval;
1277*4882a593Smuzhiyun 
1278*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
1279*4882a593Smuzhiyun             DECODE_PRINTF(",");
1280*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
1281*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
1282*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1283*4882a593Smuzhiyun             TRACE_AND_STEP();
1284*4882a593Smuzhiyun             *destreg = adc_word(*destreg, srcval);
1285*4882a593Smuzhiyun         }
1286*4882a593Smuzhiyun         break;
1287*4882a593Smuzhiyun     case 2:
1288*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1289*4882a593Smuzhiyun             u32 *destreg;
1290*4882a593Smuzhiyun             u32 srcval;
1291*4882a593Smuzhiyun 
1292*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
1293*4882a593Smuzhiyun             DECODE_PRINTF(",");
1294*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
1295*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
1296*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1297*4882a593Smuzhiyun             TRACE_AND_STEP();
1298*4882a593Smuzhiyun             *destreg = adc_long(*destreg, srcval);
1299*4882a593Smuzhiyun         }
1300*4882a593Smuzhiyun         else {
1301*4882a593Smuzhiyun             u16 *destreg;
1302*4882a593Smuzhiyun             u16 srcval;
1303*4882a593Smuzhiyun 
1304*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
1305*4882a593Smuzhiyun             DECODE_PRINTF(",");
1306*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
1307*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
1308*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1309*4882a593Smuzhiyun             TRACE_AND_STEP();
1310*4882a593Smuzhiyun             *destreg = adc_word(*destreg, srcval);
1311*4882a593Smuzhiyun         }
1312*4882a593Smuzhiyun         break;
1313*4882a593Smuzhiyun     case 3:                    /* register to register */
1314*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1315*4882a593Smuzhiyun             u32 *destreg, *srcreg;
1316*4882a593Smuzhiyun 
1317*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
1318*4882a593Smuzhiyun             DECODE_PRINTF(",");
1319*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
1320*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1321*4882a593Smuzhiyun             TRACE_AND_STEP();
1322*4882a593Smuzhiyun             *destreg = adc_long(*destreg, *srcreg);
1323*4882a593Smuzhiyun         }
1324*4882a593Smuzhiyun         else {
1325*4882a593Smuzhiyun             u16 *destreg, *srcreg;
1326*4882a593Smuzhiyun 
1327*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
1328*4882a593Smuzhiyun             DECODE_PRINTF(",");
1329*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
1330*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1331*4882a593Smuzhiyun             TRACE_AND_STEP();
1332*4882a593Smuzhiyun             *destreg = adc_word(*destreg, *srcreg);
1333*4882a593Smuzhiyun         }
1334*4882a593Smuzhiyun         break;
1335*4882a593Smuzhiyun     }
1336*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1337*4882a593Smuzhiyun     END_OF_INSTR();
1338*4882a593Smuzhiyun }
1339*4882a593Smuzhiyun 
1340*4882a593Smuzhiyun /****************************************************************************
1341*4882a593Smuzhiyun REMARKS:
1342*4882a593Smuzhiyun Handles opcode 0x14
1343*4882a593Smuzhiyun ****************************************************************************/
1344*4882a593Smuzhiyun static void
x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED (op1))1345*4882a593Smuzhiyun x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1346*4882a593Smuzhiyun {
1347*4882a593Smuzhiyun     u8 srcval;
1348*4882a593Smuzhiyun 
1349*4882a593Smuzhiyun     START_OF_INSTR();
1350*4882a593Smuzhiyun     DECODE_PRINTF("ADC\tAL,");
1351*4882a593Smuzhiyun     srcval = fetch_byte_imm();
1352*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
1353*4882a593Smuzhiyun     TRACE_AND_STEP();
1354*4882a593Smuzhiyun     M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1355*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1356*4882a593Smuzhiyun     END_OF_INSTR();
1357*4882a593Smuzhiyun }
1358*4882a593Smuzhiyun 
1359*4882a593Smuzhiyun /****************************************************************************
1360*4882a593Smuzhiyun REMARKS:
1361*4882a593Smuzhiyun Handles opcode 0x15
1362*4882a593Smuzhiyun ****************************************************************************/
1363*4882a593Smuzhiyun static void
x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED (op1))1364*4882a593Smuzhiyun x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1365*4882a593Smuzhiyun {
1366*4882a593Smuzhiyun     u32 srcval;
1367*4882a593Smuzhiyun 
1368*4882a593Smuzhiyun     START_OF_INSTR();
1369*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1370*4882a593Smuzhiyun         DECODE_PRINTF("ADC\tEAX,");
1371*4882a593Smuzhiyun         srcval = fetch_long_imm();
1372*4882a593Smuzhiyun     }
1373*4882a593Smuzhiyun     else {
1374*4882a593Smuzhiyun         DECODE_PRINTF("ADC\tAX,");
1375*4882a593Smuzhiyun         srcval = fetch_word_imm();
1376*4882a593Smuzhiyun     }
1377*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
1378*4882a593Smuzhiyun     TRACE_AND_STEP();
1379*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1380*4882a593Smuzhiyun         M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1381*4882a593Smuzhiyun     }
1382*4882a593Smuzhiyun     else {
1383*4882a593Smuzhiyun         M.x86.R_AX = adc_word(M.x86.R_AX, (u16) srcval);
1384*4882a593Smuzhiyun     }
1385*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1386*4882a593Smuzhiyun     END_OF_INSTR();
1387*4882a593Smuzhiyun }
1388*4882a593Smuzhiyun 
1389*4882a593Smuzhiyun /****************************************************************************
1390*4882a593Smuzhiyun REMARKS:
1391*4882a593Smuzhiyun Handles opcode 0x16
1392*4882a593Smuzhiyun ****************************************************************************/
1393*4882a593Smuzhiyun static void
x86emuOp_push_SS(u8 X86EMU_UNUSED (op1))1394*4882a593Smuzhiyun x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1395*4882a593Smuzhiyun {
1396*4882a593Smuzhiyun     START_OF_INSTR();
1397*4882a593Smuzhiyun     DECODE_PRINTF("PUSH\tSS\n");
1398*4882a593Smuzhiyun     TRACE_AND_STEP();
1399*4882a593Smuzhiyun     push_word(M.x86.R_SS);
1400*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1401*4882a593Smuzhiyun     END_OF_INSTR();
1402*4882a593Smuzhiyun }
1403*4882a593Smuzhiyun 
1404*4882a593Smuzhiyun /****************************************************************************
1405*4882a593Smuzhiyun REMARKS:
1406*4882a593Smuzhiyun Handles opcode 0x17
1407*4882a593Smuzhiyun ****************************************************************************/
1408*4882a593Smuzhiyun static void
x86emuOp_pop_SS(u8 X86EMU_UNUSED (op1))1409*4882a593Smuzhiyun x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1410*4882a593Smuzhiyun {
1411*4882a593Smuzhiyun     START_OF_INSTR();
1412*4882a593Smuzhiyun     DECODE_PRINTF("POP\tSS\n");
1413*4882a593Smuzhiyun     TRACE_AND_STEP();
1414*4882a593Smuzhiyun     M.x86.R_SS = pop_word();
1415*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1416*4882a593Smuzhiyun     END_OF_INSTR();
1417*4882a593Smuzhiyun }
1418*4882a593Smuzhiyun 
1419*4882a593Smuzhiyun /****************************************************************************
1420*4882a593Smuzhiyun REMARKS:
1421*4882a593Smuzhiyun Handles opcode 0x18
1422*4882a593Smuzhiyun ****************************************************************************/
1423*4882a593Smuzhiyun static void
x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED (op1))1424*4882a593Smuzhiyun x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1425*4882a593Smuzhiyun {
1426*4882a593Smuzhiyun     int mod, rl, rh;
1427*4882a593Smuzhiyun     u8 *destreg, *srcreg;
1428*4882a593Smuzhiyun     uint destoffset;
1429*4882a593Smuzhiyun     u8 destval;
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun     START_OF_INSTR();
1432*4882a593Smuzhiyun     DECODE_PRINTF("SBB\t");
1433*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
1434*4882a593Smuzhiyun     switch (mod) {
1435*4882a593Smuzhiyun     case 0:
1436*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
1437*4882a593Smuzhiyun         DECODE_PRINTF(",");
1438*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
1439*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1440*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1441*4882a593Smuzhiyun         TRACE_AND_STEP();
1442*4882a593Smuzhiyun         destval = sbb_byte(destval, *srcreg);
1443*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
1444*4882a593Smuzhiyun         break;
1445*4882a593Smuzhiyun     case 1:
1446*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
1447*4882a593Smuzhiyun         DECODE_PRINTF(",");
1448*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
1449*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1450*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1451*4882a593Smuzhiyun         TRACE_AND_STEP();
1452*4882a593Smuzhiyun         destval = sbb_byte(destval, *srcreg);
1453*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
1454*4882a593Smuzhiyun         break;
1455*4882a593Smuzhiyun     case 2:
1456*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
1457*4882a593Smuzhiyun         DECODE_PRINTF(",");
1458*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
1459*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1460*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1461*4882a593Smuzhiyun         TRACE_AND_STEP();
1462*4882a593Smuzhiyun         destval = sbb_byte(destval, *srcreg);
1463*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
1464*4882a593Smuzhiyun         break;
1465*4882a593Smuzhiyun     case 3:                    /* register to register */
1466*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
1467*4882a593Smuzhiyun         DECODE_PRINTF(",");
1468*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1469*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1470*4882a593Smuzhiyun         TRACE_AND_STEP();
1471*4882a593Smuzhiyun         *destreg = sbb_byte(*destreg, *srcreg);
1472*4882a593Smuzhiyun         break;
1473*4882a593Smuzhiyun     }
1474*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1475*4882a593Smuzhiyun     END_OF_INSTR();
1476*4882a593Smuzhiyun }
1477*4882a593Smuzhiyun 
1478*4882a593Smuzhiyun /****************************************************************************
1479*4882a593Smuzhiyun REMARKS:
1480*4882a593Smuzhiyun Handles opcode 0x19
1481*4882a593Smuzhiyun ****************************************************************************/
1482*4882a593Smuzhiyun static void
x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED (op1))1483*4882a593Smuzhiyun x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1484*4882a593Smuzhiyun {
1485*4882a593Smuzhiyun     int mod, rl, rh;
1486*4882a593Smuzhiyun     uint destoffset;
1487*4882a593Smuzhiyun 
1488*4882a593Smuzhiyun     START_OF_INSTR();
1489*4882a593Smuzhiyun     DECODE_PRINTF("SBB\t");
1490*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
1491*4882a593Smuzhiyun     switch (mod) {
1492*4882a593Smuzhiyun     case 0:
1493*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1494*4882a593Smuzhiyun             u32 destval;
1495*4882a593Smuzhiyun             u32 *srcreg;
1496*4882a593Smuzhiyun 
1497*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
1498*4882a593Smuzhiyun             DECODE_PRINTF(",");
1499*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
1500*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1501*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1502*4882a593Smuzhiyun             TRACE_AND_STEP();
1503*4882a593Smuzhiyun             destval = sbb_long(destval, *srcreg);
1504*4882a593Smuzhiyun             store_data_long(destoffset, destval);
1505*4882a593Smuzhiyun         }
1506*4882a593Smuzhiyun         else {
1507*4882a593Smuzhiyun             u16 destval;
1508*4882a593Smuzhiyun             u16 *srcreg;
1509*4882a593Smuzhiyun 
1510*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
1511*4882a593Smuzhiyun             DECODE_PRINTF(",");
1512*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
1513*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
1514*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1515*4882a593Smuzhiyun             TRACE_AND_STEP();
1516*4882a593Smuzhiyun             destval = sbb_word(destval, *srcreg);
1517*4882a593Smuzhiyun             store_data_word(destoffset, destval);
1518*4882a593Smuzhiyun         }
1519*4882a593Smuzhiyun         break;
1520*4882a593Smuzhiyun     case 1:
1521*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1522*4882a593Smuzhiyun             u32 destval;
1523*4882a593Smuzhiyun             u32 *srcreg;
1524*4882a593Smuzhiyun 
1525*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
1526*4882a593Smuzhiyun             DECODE_PRINTF(",");
1527*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
1528*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1529*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1530*4882a593Smuzhiyun             TRACE_AND_STEP();
1531*4882a593Smuzhiyun             destval = sbb_long(destval, *srcreg);
1532*4882a593Smuzhiyun             store_data_long(destoffset, destval);
1533*4882a593Smuzhiyun         }
1534*4882a593Smuzhiyun         else {
1535*4882a593Smuzhiyun             u16 destval;
1536*4882a593Smuzhiyun             u16 *srcreg;
1537*4882a593Smuzhiyun 
1538*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
1539*4882a593Smuzhiyun             DECODE_PRINTF(",");
1540*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
1541*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
1542*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1543*4882a593Smuzhiyun             TRACE_AND_STEP();
1544*4882a593Smuzhiyun             destval = sbb_word(destval, *srcreg);
1545*4882a593Smuzhiyun             store_data_word(destoffset, destval);
1546*4882a593Smuzhiyun         }
1547*4882a593Smuzhiyun         break;
1548*4882a593Smuzhiyun     case 2:
1549*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1550*4882a593Smuzhiyun             u32 destval;
1551*4882a593Smuzhiyun             u32 *srcreg;
1552*4882a593Smuzhiyun 
1553*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
1554*4882a593Smuzhiyun             DECODE_PRINTF(",");
1555*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
1556*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1557*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1558*4882a593Smuzhiyun             TRACE_AND_STEP();
1559*4882a593Smuzhiyun             destval = sbb_long(destval, *srcreg);
1560*4882a593Smuzhiyun             store_data_long(destoffset, destval);
1561*4882a593Smuzhiyun         }
1562*4882a593Smuzhiyun         else {
1563*4882a593Smuzhiyun             u16 destval;
1564*4882a593Smuzhiyun             u16 *srcreg;
1565*4882a593Smuzhiyun 
1566*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
1567*4882a593Smuzhiyun             DECODE_PRINTF(",");
1568*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
1569*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
1570*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1571*4882a593Smuzhiyun             TRACE_AND_STEP();
1572*4882a593Smuzhiyun             destval = sbb_word(destval, *srcreg);
1573*4882a593Smuzhiyun             store_data_word(destoffset, destval);
1574*4882a593Smuzhiyun         }
1575*4882a593Smuzhiyun         break;
1576*4882a593Smuzhiyun     case 3:                    /* register to register */
1577*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1578*4882a593Smuzhiyun             u32 *destreg, *srcreg;
1579*4882a593Smuzhiyun 
1580*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
1581*4882a593Smuzhiyun             DECODE_PRINTF(",");
1582*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1583*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1584*4882a593Smuzhiyun             TRACE_AND_STEP();
1585*4882a593Smuzhiyun             *destreg = sbb_long(*destreg, *srcreg);
1586*4882a593Smuzhiyun         }
1587*4882a593Smuzhiyun         else {
1588*4882a593Smuzhiyun             u16 *destreg, *srcreg;
1589*4882a593Smuzhiyun 
1590*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
1591*4882a593Smuzhiyun             DECODE_PRINTF(",");
1592*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
1593*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1594*4882a593Smuzhiyun             TRACE_AND_STEP();
1595*4882a593Smuzhiyun             *destreg = sbb_word(*destreg, *srcreg);
1596*4882a593Smuzhiyun         }
1597*4882a593Smuzhiyun         break;
1598*4882a593Smuzhiyun     }
1599*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1600*4882a593Smuzhiyun     END_OF_INSTR();
1601*4882a593Smuzhiyun }
1602*4882a593Smuzhiyun 
1603*4882a593Smuzhiyun /****************************************************************************
1604*4882a593Smuzhiyun REMARKS:
1605*4882a593Smuzhiyun Handles opcode 0x1a
1606*4882a593Smuzhiyun ****************************************************************************/
1607*4882a593Smuzhiyun static void
x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED (op1))1608*4882a593Smuzhiyun x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1609*4882a593Smuzhiyun {
1610*4882a593Smuzhiyun     int mod, rl, rh;
1611*4882a593Smuzhiyun     u8 *destreg, *srcreg;
1612*4882a593Smuzhiyun     uint srcoffset;
1613*4882a593Smuzhiyun     u8 srcval;
1614*4882a593Smuzhiyun 
1615*4882a593Smuzhiyun     START_OF_INSTR();
1616*4882a593Smuzhiyun     DECODE_PRINTF("SBB\t");
1617*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
1618*4882a593Smuzhiyun     switch (mod) {
1619*4882a593Smuzhiyun     case 0:
1620*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
1621*4882a593Smuzhiyun         DECODE_PRINTF(",");
1622*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
1623*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
1624*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1625*4882a593Smuzhiyun         TRACE_AND_STEP();
1626*4882a593Smuzhiyun         *destreg = sbb_byte(*destreg, srcval);
1627*4882a593Smuzhiyun         break;
1628*4882a593Smuzhiyun     case 1:
1629*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
1630*4882a593Smuzhiyun         DECODE_PRINTF(",");
1631*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
1632*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
1633*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1634*4882a593Smuzhiyun         TRACE_AND_STEP();
1635*4882a593Smuzhiyun         *destreg = sbb_byte(*destreg, srcval);
1636*4882a593Smuzhiyun         break;
1637*4882a593Smuzhiyun     case 2:
1638*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
1639*4882a593Smuzhiyun         DECODE_PRINTF(",");
1640*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
1641*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
1642*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1643*4882a593Smuzhiyun         TRACE_AND_STEP();
1644*4882a593Smuzhiyun         *destreg = sbb_byte(*destreg, srcval);
1645*4882a593Smuzhiyun         break;
1646*4882a593Smuzhiyun     case 3:                    /* register to register */
1647*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
1648*4882a593Smuzhiyun         DECODE_PRINTF(",");
1649*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rl);
1650*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1651*4882a593Smuzhiyun         TRACE_AND_STEP();
1652*4882a593Smuzhiyun         *destreg = sbb_byte(*destreg, *srcreg);
1653*4882a593Smuzhiyun         break;
1654*4882a593Smuzhiyun     }
1655*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1656*4882a593Smuzhiyun     END_OF_INSTR();
1657*4882a593Smuzhiyun }
1658*4882a593Smuzhiyun 
1659*4882a593Smuzhiyun /****************************************************************************
1660*4882a593Smuzhiyun REMARKS:
1661*4882a593Smuzhiyun Handles opcode 0x1b
1662*4882a593Smuzhiyun ****************************************************************************/
1663*4882a593Smuzhiyun static void
x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED (op1))1664*4882a593Smuzhiyun x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1665*4882a593Smuzhiyun {
1666*4882a593Smuzhiyun     int mod, rl, rh;
1667*4882a593Smuzhiyun     uint srcoffset;
1668*4882a593Smuzhiyun 
1669*4882a593Smuzhiyun     START_OF_INSTR();
1670*4882a593Smuzhiyun     DECODE_PRINTF("SBB\t");
1671*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
1672*4882a593Smuzhiyun     switch (mod) {
1673*4882a593Smuzhiyun     case 0:
1674*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1675*4882a593Smuzhiyun             u32 *destreg;
1676*4882a593Smuzhiyun             u32 srcval;
1677*4882a593Smuzhiyun 
1678*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
1679*4882a593Smuzhiyun             DECODE_PRINTF(",");
1680*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
1681*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
1682*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1683*4882a593Smuzhiyun             TRACE_AND_STEP();
1684*4882a593Smuzhiyun             *destreg = sbb_long(*destreg, srcval);
1685*4882a593Smuzhiyun         }
1686*4882a593Smuzhiyun         else {
1687*4882a593Smuzhiyun             u16 *destreg;
1688*4882a593Smuzhiyun             u16 srcval;
1689*4882a593Smuzhiyun 
1690*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
1691*4882a593Smuzhiyun             DECODE_PRINTF(",");
1692*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
1693*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
1694*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1695*4882a593Smuzhiyun             TRACE_AND_STEP();
1696*4882a593Smuzhiyun             *destreg = sbb_word(*destreg, srcval);
1697*4882a593Smuzhiyun         }
1698*4882a593Smuzhiyun         break;
1699*4882a593Smuzhiyun     case 1:
1700*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1701*4882a593Smuzhiyun             u32 *destreg;
1702*4882a593Smuzhiyun             u32 srcval;
1703*4882a593Smuzhiyun 
1704*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
1705*4882a593Smuzhiyun             DECODE_PRINTF(",");
1706*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
1707*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
1708*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1709*4882a593Smuzhiyun             TRACE_AND_STEP();
1710*4882a593Smuzhiyun             *destreg = sbb_long(*destreg, srcval);
1711*4882a593Smuzhiyun         }
1712*4882a593Smuzhiyun         else {
1713*4882a593Smuzhiyun             u16 *destreg;
1714*4882a593Smuzhiyun             u16 srcval;
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
1717*4882a593Smuzhiyun             DECODE_PRINTF(",");
1718*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
1719*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
1720*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1721*4882a593Smuzhiyun             TRACE_AND_STEP();
1722*4882a593Smuzhiyun             *destreg = sbb_word(*destreg, srcval);
1723*4882a593Smuzhiyun         }
1724*4882a593Smuzhiyun         break;
1725*4882a593Smuzhiyun     case 2:
1726*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1727*4882a593Smuzhiyun             u32 *destreg;
1728*4882a593Smuzhiyun             u32 srcval;
1729*4882a593Smuzhiyun 
1730*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
1731*4882a593Smuzhiyun             DECODE_PRINTF(",");
1732*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
1733*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
1734*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1735*4882a593Smuzhiyun             TRACE_AND_STEP();
1736*4882a593Smuzhiyun             *destreg = sbb_long(*destreg, srcval);
1737*4882a593Smuzhiyun         }
1738*4882a593Smuzhiyun         else {
1739*4882a593Smuzhiyun             u16 *destreg;
1740*4882a593Smuzhiyun             u16 srcval;
1741*4882a593Smuzhiyun 
1742*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
1743*4882a593Smuzhiyun             DECODE_PRINTF(",");
1744*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
1745*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
1746*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1747*4882a593Smuzhiyun             TRACE_AND_STEP();
1748*4882a593Smuzhiyun             *destreg = sbb_word(*destreg, srcval);
1749*4882a593Smuzhiyun         }
1750*4882a593Smuzhiyun         break;
1751*4882a593Smuzhiyun     case 3:                    /* register to register */
1752*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1753*4882a593Smuzhiyun             u32 *destreg, *srcreg;
1754*4882a593Smuzhiyun 
1755*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
1756*4882a593Smuzhiyun             DECODE_PRINTF(",");
1757*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
1758*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1759*4882a593Smuzhiyun             TRACE_AND_STEP();
1760*4882a593Smuzhiyun             *destreg = sbb_long(*destreg, *srcreg);
1761*4882a593Smuzhiyun         }
1762*4882a593Smuzhiyun         else {
1763*4882a593Smuzhiyun             u16 *destreg, *srcreg;
1764*4882a593Smuzhiyun 
1765*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
1766*4882a593Smuzhiyun             DECODE_PRINTF(",");
1767*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
1768*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1769*4882a593Smuzhiyun             TRACE_AND_STEP();
1770*4882a593Smuzhiyun             *destreg = sbb_word(*destreg, *srcreg);
1771*4882a593Smuzhiyun         }
1772*4882a593Smuzhiyun         break;
1773*4882a593Smuzhiyun     }
1774*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1775*4882a593Smuzhiyun     END_OF_INSTR();
1776*4882a593Smuzhiyun }
1777*4882a593Smuzhiyun 
1778*4882a593Smuzhiyun /****************************************************************************
1779*4882a593Smuzhiyun REMARKS:
1780*4882a593Smuzhiyun Handles opcode 0x1c
1781*4882a593Smuzhiyun ****************************************************************************/
1782*4882a593Smuzhiyun static void
x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED (op1))1783*4882a593Smuzhiyun x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1784*4882a593Smuzhiyun {
1785*4882a593Smuzhiyun     u8 srcval;
1786*4882a593Smuzhiyun 
1787*4882a593Smuzhiyun     START_OF_INSTR();
1788*4882a593Smuzhiyun     DECODE_PRINTF("SBB\tAL,");
1789*4882a593Smuzhiyun     srcval = fetch_byte_imm();
1790*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
1791*4882a593Smuzhiyun     TRACE_AND_STEP();
1792*4882a593Smuzhiyun     M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1793*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1794*4882a593Smuzhiyun     END_OF_INSTR();
1795*4882a593Smuzhiyun }
1796*4882a593Smuzhiyun 
1797*4882a593Smuzhiyun /****************************************************************************
1798*4882a593Smuzhiyun REMARKS:
1799*4882a593Smuzhiyun Handles opcode 0x1d
1800*4882a593Smuzhiyun ****************************************************************************/
1801*4882a593Smuzhiyun static void
x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED (op1))1802*4882a593Smuzhiyun x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1803*4882a593Smuzhiyun {
1804*4882a593Smuzhiyun     u32 srcval;
1805*4882a593Smuzhiyun 
1806*4882a593Smuzhiyun     START_OF_INSTR();
1807*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1808*4882a593Smuzhiyun         DECODE_PRINTF("SBB\tEAX,");
1809*4882a593Smuzhiyun         srcval = fetch_long_imm();
1810*4882a593Smuzhiyun     }
1811*4882a593Smuzhiyun     else {
1812*4882a593Smuzhiyun         DECODE_PRINTF("SBB\tAX,");
1813*4882a593Smuzhiyun         srcval = fetch_word_imm();
1814*4882a593Smuzhiyun     }
1815*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
1816*4882a593Smuzhiyun     TRACE_AND_STEP();
1817*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1818*4882a593Smuzhiyun         M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1819*4882a593Smuzhiyun     }
1820*4882a593Smuzhiyun     else {
1821*4882a593Smuzhiyun         M.x86.R_AX = sbb_word(M.x86.R_AX, (u16) srcval);
1822*4882a593Smuzhiyun     }
1823*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1824*4882a593Smuzhiyun     END_OF_INSTR();
1825*4882a593Smuzhiyun }
1826*4882a593Smuzhiyun 
1827*4882a593Smuzhiyun /****************************************************************************
1828*4882a593Smuzhiyun REMARKS:
1829*4882a593Smuzhiyun Handles opcode 0x1e
1830*4882a593Smuzhiyun ****************************************************************************/
1831*4882a593Smuzhiyun static void
x86emuOp_push_DS(u8 X86EMU_UNUSED (op1))1832*4882a593Smuzhiyun x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1833*4882a593Smuzhiyun {
1834*4882a593Smuzhiyun     START_OF_INSTR();
1835*4882a593Smuzhiyun     DECODE_PRINTF("PUSH\tDS\n");
1836*4882a593Smuzhiyun     TRACE_AND_STEP();
1837*4882a593Smuzhiyun     push_word(M.x86.R_DS);
1838*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1839*4882a593Smuzhiyun     END_OF_INSTR();
1840*4882a593Smuzhiyun }
1841*4882a593Smuzhiyun 
1842*4882a593Smuzhiyun /****************************************************************************
1843*4882a593Smuzhiyun REMARKS:
1844*4882a593Smuzhiyun Handles opcode 0x1f
1845*4882a593Smuzhiyun ****************************************************************************/
1846*4882a593Smuzhiyun static void
x86emuOp_pop_DS(u8 X86EMU_UNUSED (op1))1847*4882a593Smuzhiyun x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1848*4882a593Smuzhiyun {
1849*4882a593Smuzhiyun     START_OF_INSTR();
1850*4882a593Smuzhiyun     DECODE_PRINTF("POP\tDS\n");
1851*4882a593Smuzhiyun     TRACE_AND_STEP();
1852*4882a593Smuzhiyun     M.x86.R_DS = pop_word();
1853*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1854*4882a593Smuzhiyun     END_OF_INSTR();
1855*4882a593Smuzhiyun }
1856*4882a593Smuzhiyun 
1857*4882a593Smuzhiyun /****************************************************************************
1858*4882a593Smuzhiyun REMARKS:
1859*4882a593Smuzhiyun Handles opcode 0x20
1860*4882a593Smuzhiyun ****************************************************************************/
1861*4882a593Smuzhiyun static void
x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED (op1))1862*4882a593Smuzhiyun x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1863*4882a593Smuzhiyun {
1864*4882a593Smuzhiyun     int mod, rl, rh;
1865*4882a593Smuzhiyun     u8 *destreg, *srcreg;
1866*4882a593Smuzhiyun     uint destoffset;
1867*4882a593Smuzhiyun     u8 destval;
1868*4882a593Smuzhiyun 
1869*4882a593Smuzhiyun     START_OF_INSTR();
1870*4882a593Smuzhiyun     DECODE_PRINTF("AND\t");
1871*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
1872*4882a593Smuzhiyun 
1873*4882a593Smuzhiyun     switch (mod) {
1874*4882a593Smuzhiyun     case 0:
1875*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
1876*4882a593Smuzhiyun         DECODE_PRINTF(",");
1877*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
1878*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1879*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1880*4882a593Smuzhiyun         TRACE_AND_STEP();
1881*4882a593Smuzhiyun         destval = and_byte(destval, *srcreg);
1882*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
1883*4882a593Smuzhiyun         break;
1884*4882a593Smuzhiyun 
1885*4882a593Smuzhiyun     case 1:
1886*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
1887*4882a593Smuzhiyun         DECODE_PRINTF(",");
1888*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
1889*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1890*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1891*4882a593Smuzhiyun         TRACE_AND_STEP();
1892*4882a593Smuzhiyun         destval = and_byte(destval, *srcreg);
1893*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
1894*4882a593Smuzhiyun         break;
1895*4882a593Smuzhiyun 
1896*4882a593Smuzhiyun     case 2:
1897*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
1898*4882a593Smuzhiyun         DECODE_PRINTF(",");
1899*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
1900*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1901*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1902*4882a593Smuzhiyun         TRACE_AND_STEP();
1903*4882a593Smuzhiyun         destval = and_byte(destval, *srcreg);
1904*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
1905*4882a593Smuzhiyun         break;
1906*4882a593Smuzhiyun 
1907*4882a593Smuzhiyun     case 3:                    /* register to register */
1908*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
1909*4882a593Smuzhiyun         DECODE_PRINTF(",");
1910*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1911*4882a593Smuzhiyun         DECODE_PRINTF("\n");
1912*4882a593Smuzhiyun         TRACE_AND_STEP();
1913*4882a593Smuzhiyun         *destreg = and_byte(*destreg, *srcreg);
1914*4882a593Smuzhiyun         break;
1915*4882a593Smuzhiyun     }
1916*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
1917*4882a593Smuzhiyun     END_OF_INSTR();
1918*4882a593Smuzhiyun }
1919*4882a593Smuzhiyun 
1920*4882a593Smuzhiyun /****************************************************************************
1921*4882a593Smuzhiyun REMARKS:
1922*4882a593Smuzhiyun Handles opcode 0x21
1923*4882a593Smuzhiyun ****************************************************************************/
1924*4882a593Smuzhiyun static void
x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED (op1))1925*4882a593Smuzhiyun x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1926*4882a593Smuzhiyun {
1927*4882a593Smuzhiyun     int mod, rl, rh;
1928*4882a593Smuzhiyun     uint destoffset;
1929*4882a593Smuzhiyun 
1930*4882a593Smuzhiyun     START_OF_INSTR();
1931*4882a593Smuzhiyun     DECODE_PRINTF("AND\t");
1932*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
1933*4882a593Smuzhiyun     switch (mod) {
1934*4882a593Smuzhiyun     case 0:
1935*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1936*4882a593Smuzhiyun             u32 destval;
1937*4882a593Smuzhiyun             u32 *srcreg;
1938*4882a593Smuzhiyun 
1939*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
1940*4882a593Smuzhiyun             DECODE_PRINTF(",");
1941*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
1942*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1943*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1944*4882a593Smuzhiyun             TRACE_AND_STEP();
1945*4882a593Smuzhiyun             destval = and_long(destval, *srcreg);
1946*4882a593Smuzhiyun             store_data_long(destoffset, destval);
1947*4882a593Smuzhiyun         }
1948*4882a593Smuzhiyun         else {
1949*4882a593Smuzhiyun             u16 destval;
1950*4882a593Smuzhiyun             u16 *srcreg;
1951*4882a593Smuzhiyun 
1952*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
1953*4882a593Smuzhiyun             DECODE_PRINTF(",");
1954*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
1955*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
1956*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1957*4882a593Smuzhiyun             TRACE_AND_STEP();
1958*4882a593Smuzhiyun             destval = and_word(destval, *srcreg);
1959*4882a593Smuzhiyun             store_data_word(destoffset, destval);
1960*4882a593Smuzhiyun         }
1961*4882a593Smuzhiyun         break;
1962*4882a593Smuzhiyun     case 1:
1963*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1964*4882a593Smuzhiyun             u32 destval;
1965*4882a593Smuzhiyun             u32 *srcreg;
1966*4882a593Smuzhiyun 
1967*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
1968*4882a593Smuzhiyun             DECODE_PRINTF(",");
1969*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
1970*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1971*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1972*4882a593Smuzhiyun             TRACE_AND_STEP();
1973*4882a593Smuzhiyun             destval = and_long(destval, *srcreg);
1974*4882a593Smuzhiyun             store_data_long(destoffset, destval);
1975*4882a593Smuzhiyun         }
1976*4882a593Smuzhiyun         else {
1977*4882a593Smuzhiyun             u16 destval;
1978*4882a593Smuzhiyun             u16 *srcreg;
1979*4882a593Smuzhiyun 
1980*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
1981*4882a593Smuzhiyun             DECODE_PRINTF(",");
1982*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
1983*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
1984*4882a593Smuzhiyun             DECODE_PRINTF("\n");
1985*4882a593Smuzhiyun             TRACE_AND_STEP();
1986*4882a593Smuzhiyun             destval = and_word(destval, *srcreg);
1987*4882a593Smuzhiyun             store_data_word(destoffset, destval);
1988*4882a593Smuzhiyun         }
1989*4882a593Smuzhiyun         break;
1990*4882a593Smuzhiyun     case 2:
1991*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1992*4882a593Smuzhiyun             u32 destval;
1993*4882a593Smuzhiyun             u32 *srcreg;
1994*4882a593Smuzhiyun 
1995*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
1996*4882a593Smuzhiyun             DECODE_PRINTF(",");
1997*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
1998*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
1999*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2000*4882a593Smuzhiyun             TRACE_AND_STEP();
2001*4882a593Smuzhiyun             destval = and_long(destval, *srcreg);
2002*4882a593Smuzhiyun             store_data_long(destoffset, destval);
2003*4882a593Smuzhiyun         }
2004*4882a593Smuzhiyun         else {
2005*4882a593Smuzhiyun             u16 destval;
2006*4882a593Smuzhiyun             u16 *srcreg;
2007*4882a593Smuzhiyun 
2008*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
2009*4882a593Smuzhiyun             DECODE_PRINTF(",");
2010*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
2011*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
2012*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2013*4882a593Smuzhiyun             TRACE_AND_STEP();
2014*4882a593Smuzhiyun             destval = and_word(destval, *srcreg);
2015*4882a593Smuzhiyun             store_data_word(destoffset, destval);
2016*4882a593Smuzhiyun         }
2017*4882a593Smuzhiyun         break;
2018*4882a593Smuzhiyun     case 3:                    /* register to register */
2019*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2020*4882a593Smuzhiyun             u32 *destreg, *srcreg;
2021*4882a593Smuzhiyun 
2022*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
2023*4882a593Smuzhiyun             DECODE_PRINTF(",");
2024*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
2025*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2026*4882a593Smuzhiyun             TRACE_AND_STEP();
2027*4882a593Smuzhiyun             *destreg = and_long(*destreg, *srcreg);
2028*4882a593Smuzhiyun         }
2029*4882a593Smuzhiyun         else {
2030*4882a593Smuzhiyun             u16 *destreg, *srcreg;
2031*4882a593Smuzhiyun 
2032*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
2033*4882a593Smuzhiyun             DECODE_PRINTF(",");
2034*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
2035*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2036*4882a593Smuzhiyun             TRACE_AND_STEP();
2037*4882a593Smuzhiyun             *destreg = and_word(*destreg, *srcreg);
2038*4882a593Smuzhiyun         }
2039*4882a593Smuzhiyun         break;
2040*4882a593Smuzhiyun     }
2041*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2042*4882a593Smuzhiyun     END_OF_INSTR();
2043*4882a593Smuzhiyun }
2044*4882a593Smuzhiyun 
2045*4882a593Smuzhiyun /****************************************************************************
2046*4882a593Smuzhiyun REMARKS:
2047*4882a593Smuzhiyun Handles opcode 0x22
2048*4882a593Smuzhiyun ****************************************************************************/
2049*4882a593Smuzhiyun static void
x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED (op1))2050*4882a593Smuzhiyun x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
2051*4882a593Smuzhiyun {
2052*4882a593Smuzhiyun     int mod, rl, rh;
2053*4882a593Smuzhiyun     u8 *destreg, *srcreg;
2054*4882a593Smuzhiyun     uint srcoffset;
2055*4882a593Smuzhiyun     u8 srcval;
2056*4882a593Smuzhiyun 
2057*4882a593Smuzhiyun     START_OF_INSTR();
2058*4882a593Smuzhiyun     DECODE_PRINTF("AND\t");
2059*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
2060*4882a593Smuzhiyun     switch (mod) {
2061*4882a593Smuzhiyun     case 0:
2062*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2063*4882a593Smuzhiyun         DECODE_PRINTF(",");
2064*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
2065*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
2066*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2067*4882a593Smuzhiyun         TRACE_AND_STEP();
2068*4882a593Smuzhiyun         *destreg = and_byte(*destreg, srcval);
2069*4882a593Smuzhiyun         break;
2070*4882a593Smuzhiyun     case 1:
2071*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2072*4882a593Smuzhiyun         DECODE_PRINTF(",");
2073*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
2074*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
2075*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2076*4882a593Smuzhiyun         TRACE_AND_STEP();
2077*4882a593Smuzhiyun         *destreg = and_byte(*destreg, srcval);
2078*4882a593Smuzhiyun         break;
2079*4882a593Smuzhiyun     case 2:
2080*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2081*4882a593Smuzhiyun         DECODE_PRINTF(",");
2082*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
2083*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
2084*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2085*4882a593Smuzhiyun         TRACE_AND_STEP();
2086*4882a593Smuzhiyun         *destreg = and_byte(*destreg, srcval);
2087*4882a593Smuzhiyun         break;
2088*4882a593Smuzhiyun     case 3:                    /* register to register */
2089*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2090*4882a593Smuzhiyun         DECODE_PRINTF(",");
2091*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2092*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2093*4882a593Smuzhiyun         TRACE_AND_STEP();
2094*4882a593Smuzhiyun         *destreg = and_byte(*destreg, *srcreg);
2095*4882a593Smuzhiyun         break;
2096*4882a593Smuzhiyun     }
2097*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2098*4882a593Smuzhiyun     END_OF_INSTR();
2099*4882a593Smuzhiyun }
2100*4882a593Smuzhiyun 
2101*4882a593Smuzhiyun /****************************************************************************
2102*4882a593Smuzhiyun REMARKS:
2103*4882a593Smuzhiyun Handles opcode 0x23
2104*4882a593Smuzhiyun ****************************************************************************/
2105*4882a593Smuzhiyun static void
x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED (op1))2106*4882a593Smuzhiyun x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2107*4882a593Smuzhiyun {
2108*4882a593Smuzhiyun     int mod, rl, rh;
2109*4882a593Smuzhiyun     uint srcoffset;
2110*4882a593Smuzhiyun 
2111*4882a593Smuzhiyun     START_OF_INSTR();
2112*4882a593Smuzhiyun     DECODE_PRINTF("AND\t");
2113*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
2114*4882a593Smuzhiyun     switch (mod) {
2115*4882a593Smuzhiyun     case 0:
2116*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2117*4882a593Smuzhiyun             u32 *destreg;
2118*4882a593Smuzhiyun             u32 srcval;
2119*4882a593Smuzhiyun 
2120*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
2121*4882a593Smuzhiyun             DECODE_PRINTF(",");
2122*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
2123*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
2124*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2125*4882a593Smuzhiyun             TRACE_AND_STEP();
2126*4882a593Smuzhiyun             *destreg = and_long(*destreg, srcval);
2127*4882a593Smuzhiyun         }
2128*4882a593Smuzhiyun         else {
2129*4882a593Smuzhiyun             u16 *destreg;
2130*4882a593Smuzhiyun             u16 srcval;
2131*4882a593Smuzhiyun 
2132*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
2133*4882a593Smuzhiyun             DECODE_PRINTF(",");
2134*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
2135*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
2136*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2137*4882a593Smuzhiyun             TRACE_AND_STEP();
2138*4882a593Smuzhiyun             *destreg = and_word(*destreg, srcval);
2139*4882a593Smuzhiyun         }
2140*4882a593Smuzhiyun         break;
2141*4882a593Smuzhiyun     case 1:
2142*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2143*4882a593Smuzhiyun             u32 *destreg;
2144*4882a593Smuzhiyun             u32 srcval;
2145*4882a593Smuzhiyun 
2146*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
2147*4882a593Smuzhiyun             DECODE_PRINTF(",");
2148*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
2149*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
2150*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2151*4882a593Smuzhiyun             TRACE_AND_STEP();
2152*4882a593Smuzhiyun             *destreg = and_long(*destreg, srcval);
2153*4882a593Smuzhiyun             break;
2154*4882a593Smuzhiyun         }
2155*4882a593Smuzhiyun         else {
2156*4882a593Smuzhiyun             u16 *destreg;
2157*4882a593Smuzhiyun             u16 srcval;
2158*4882a593Smuzhiyun 
2159*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
2160*4882a593Smuzhiyun             DECODE_PRINTF(",");
2161*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
2162*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
2163*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2164*4882a593Smuzhiyun             TRACE_AND_STEP();
2165*4882a593Smuzhiyun             *destreg = and_word(*destreg, srcval);
2166*4882a593Smuzhiyun             break;
2167*4882a593Smuzhiyun         }
2168*4882a593Smuzhiyun     case 2:
2169*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2170*4882a593Smuzhiyun             u32 *destreg;
2171*4882a593Smuzhiyun             u32 srcval;
2172*4882a593Smuzhiyun 
2173*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
2174*4882a593Smuzhiyun             DECODE_PRINTF(",");
2175*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
2176*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
2177*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2178*4882a593Smuzhiyun             TRACE_AND_STEP();
2179*4882a593Smuzhiyun             *destreg = and_long(*destreg, srcval);
2180*4882a593Smuzhiyun         }
2181*4882a593Smuzhiyun         else {
2182*4882a593Smuzhiyun             u16 *destreg;
2183*4882a593Smuzhiyun             u16 srcval;
2184*4882a593Smuzhiyun 
2185*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
2186*4882a593Smuzhiyun             DECODE_PRINTF(",");
2187*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
2188*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
2189*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2190*4882a593Smuzhiyun             TRACE_AND_STEP();
2191*4882a593Smuzhiyun             *destreg = and_word(*destreg, srcval);
2192*4882a593Smuzhiyun         }
2193*4882a593Smuzhiyun         break;
2194*4882a593Smuzhiyun     case 3:                    /* register to register */
2195*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2196*4882a593Smuzhiyun             u32 *destreg, *srcreg;
2197*4882a593Smuzhiyun 
2198*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
2199*4882a593Smuzhiyun             DECODE_PRINTF(",");
2200*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
2201*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2202*4882a593Smuzhiyun             TRACE_AND_STEP();
2203*4882a593Smuzhiyun             *destreg = and_long(*destreg, *srcreg);
2204*4882a593Smuzhiyun         }
2205*4882a593Smuzhiyun         else {
2206*4882a593Smuzhiyun             u16 *destreg, *srcreg;
2207*4882a593Smuzhiyun 
2208*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
2209*4882a593Smuzhiyun             DECODE_PRINTF(",");
2210*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
2211*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2212*4882a593Smuzhiyun             TRACE_AND_STEP();
2213*4882a593Smuzhiyun             *destreg = and_word(*destreg, *srcreg);
2214*4882a593Smuzhiyun         }
2215*4882a593Smuzhiyun         break;
2216*4882a593Smuzhiyun     }
2217*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2218*4882a593Smuzhiyun     END_OF_INSTR();
2219*4882a593Smuzhiyun }
2220*4882a593Smuzhiyun 
2221*4882a593Smuzhiyun /****************************************************************************
2222*4882a593Smuzhiyun REMARKS:
2223*4882a593Smuzhiyun Handles opcode 0x24
2224*4882a593Smuzhiyun ****************************************************************************/
2225*4882a593Smuzhiyun static void
x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2226*4882a593Smuzhiyun x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2227*4882a593Smuzhiyun {
2228*4882a593Smuzhiyun     u8 srcval;
2229*4882a593Smuzhiyun 
2230*4882a593Smuzhiyun     START_OF_INSTR();
2231*4882a593Smuzhiyun     DECODE_PRINTF("AND\tAL,");
2232*4882a593Smuzhiyun     srcval = fetch_byte_imm();
2233*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
2234*4882a593Smuzhiyun     TRACE_AND_STEP();
2235*4882a593Smuzhiyun     M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2236*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2237*4882a593Smuzhiyun     END_OF_INSTR();
2238*4882a593Smuzhiyun }
2239*4882a593Smuzhiyun 
2240*4882a593Smuzhiyun /****************************************************************************
2241*4882a593Smuzhiyun REMARKS:
2242*4882a593Smuzhiyun Handles opcode 0x25
2243*4882a593Smuzhiyun ****************************************************************************/
2244*4882a593Smuzhiyun static void
x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED (op1))2245*4882a593Smuzhiyun x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2246*4882a593Smuzhiyun {
2247*4882a593Smuzhiyun     u32 srcval;
2248*4882a593Smuzhiyun 
2249*4882a593Smuzhiyun     START_OF_INSTR();
2250*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2251*4882a593Smuzhiyun         DECODE_PRINTF("AND\tEAX,");
2252*4882a593Smuzhiyun         srcval = fetch_long_imm();
2253*4882a593Smuzhiyun     }
2254*4882a593Smuzhiyun     else {
2255*4882a593Smuzhiyun         DECODE_PRINTF("AND\tAX,");
2256*4882a593Smuzhiyun         srcval = fetch_word_imm();
2257*4882a593Smuzhiyun     }
2258*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
2259*4882a593Smuzhiyun     TRACE_AND_STEP();
2260*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2261*4882a593Smuzhiyun         M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2262*4882a593Smuzhiyun     }
2263*4882a593Smuzhiyun     else {
2264*4882a593Smuzhiyun         M.x86.R_AX = and_word(M.x86.R_AX, (u16) srcval);
2265*4882a593Smuzhiyun     }
2266*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2267*4882a593Smuzhiyun     END_OF_INSTR();
2268*4882a593Smuzhiyun }
2269*4882a593Smuzhiyun 
2270*4882a593Smuzhiyun /****************************************************************************
2271*4882a593Smuzhiyun REMARKS:
2272*4882a593Smuzhiyun Handles opcode 0x26
2273*4882a593Smuzhiyun ****************************************************************************/
2274*4882a593Smuzhiyun static void
x86emuOp_segovr_ES(u8 X86EMU_UNUSED (op1))2275*4882a593Smuzhiyun x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2276*4882a593Smuzhiyun {
2277*4882a593Smuzhiyun     START_OF_INSTR();
2278*4882a593Smuzhiyun     DECODE_PRINTF("ES:\n");
2279*4882a593Smuzhiyun     TRACE_AND_STEP();
2280*4882a593Smuzhiyun     M.x86.mode |= SYSMODE_SEGOVR_ES;
2281*4882a593Smuzhiyun     /*
2282*4882a593Smuzhiyun      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2283*4882a593Smuzhiyun      * opcode subroutines we do not want to do this.
2284*4882a593Smuzhiyun      */
2285*4882a593Smuzhiyun     END_OF_INSTR();
2286*4882a593Smuzhiyun }
2287*4882a593Smuzhiyun 
2288*4882a593Smuzhiyun /****************************************************************************
2289*4882a593Smuzhiyun REMARKS:
2290*4882a593Smuzhiyun Handles opcode 0x27
2291*4882a593Smuzhiyun ****************************************************************************/
2292*4882a593Smuzhiyun static void
x86emuOp_daa(u8 X86EMU_UNUSED (op1))2293*4882a593Smuzhiyun x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2294*4882a593Smuzhiyun {
2295*4882a593Smuzhiyun     START_OF_INSTR();
2296*4882a593Smuzhiyun     DECODE_PRINTF("DAA\n");
2297*4882a593Smuzhiyun     TRACE_AND_STEP();
2298*4882a593Smuzhiyun     M.x86.R_AL = daa_byte(M.x86.R_AL);
2299*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2300*4882a593Smuzhiyun     END_OF_INSTR();
2301*4882a593Smuzhiyun }
2302*4882a593Smuzhiyun 
2303*4882a593Smuzhiyun /****************************************************************************
2304*4882a593Smuzhiyun REMARKS:
2305*4882a593Smuzhiyun Handles opcode 0x28
2306*4882a593Smuzhiyun ****************************************************************************/
2307*4882a593Smuzhiyun static void
x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED (op1))2308*4882a593Smuzhiyun x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2309*4882a593Smuzhiyun {
2310*4882a593Smuzhiyun     int mod, rl, rh;
2311*4882a593Smuzhiyun     u8 *destreg, *srcreg;
2312*4882a593Smuzhiyun     uint destoffset;
2313*4882a593Smuzhiyun     u8 destval;
2314*4882a593Smuzhiyun 
2315*4882a593Smuzhiyun     START_OF_INSTR();
2316*4882a593Smuzhiyun     DECODE_PRINTF("SUB\t");
2317*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
2318*4882a593Smuzhiyun     switch (mod) {
2319*4882a593Smuzhiyun     case 0:
2320*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
2321*4882a593Smuzhiyun         DECODE_PRINTF(",");
2322*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
2323*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2324*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2325*4882a593Smuzhiyun         TRACE_AND_STEP();
2326*4882a593Smuzhiyun         destval = sub_byte(destval, *srcreg);
2327*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
2328*4882a593Smuzhiyun         break;
2329*4882a593Smuzhiyun     case 1:
2330*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
2331*4882a593Smuzhiyun         DECODE_PRINTF(",");
2332*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
2333*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2334*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2335*4882a593Smuzhiyun         TRACE_AND_STEP();
2336*4882a593Smuzhiyun         destval = sub_byte(destval, *srcreg);
2337*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
2338*4882a593Smuzhiyun         break;
2339*4882a593Smuzhiyun     case 2:
2340*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
2341*4882a593Smuzhiyun         DECODE_PRINTF(",");
2342*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
2343*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2344*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2345*4882a593Smuzhiyun         TRACE_AND_STEP();
2346*4882a593Smuzhiyun         destval = sub_byte(destval, *srcreg);
2347*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
2348*4882a593Smuzhiyun         break;
2349*4882a593Smuzhiyun     case 3:                    /* register to register */
2350*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
2351*4882a593Smuzhiyun         DECODE_PRINTF(",");
2352*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2353*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2354*4882a593Smuzhiyun         TRACE_AND_STEP();
2355*4882a593Smuzhiyun         *destreg = sub_byte(*destreg, *srcreg);
2356*4882a593Smuzhiyun         break;
2357*4882a593Smuzhiyun     }
2358*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2359*4882a593Smuzhiyun     END_OF_INSTR();
2360*4882a593Smuzhiyun }
2361*4882a593Smuzhiyun 
2362*4882a593Smuzhiyun /****************************************************************************
2363*4882a593Smuzhiyun REMARKS:
2364*4882a593Smuzhiyun Handles opcode 0x29
2365*4882a593Smuzhiyun ****************************************************************************/
2366*4882a593Smuzhiyun static void
x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED (op1))2367*4882a593Smuzhiyun x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2368*4882a593Smuzhiyun {
2369*4882a593Smuzhiyun     int mod, rl, rh;
2370*4882a593Smuzhiyun     uint destoffset;
2371*4882a593Smuzhiyun 
2372*4882a593Smuzhiyun     START_OF_INSTR();
2373*4882a593Smuzhiyun     DECODE_PRINTF("SUB\t");
2374*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
2375*4882a593Smuzhiyun     switch (mod) {
2376*4882a593Smuzhiyun     case 0:
2377*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2378*4882a593Smuzhiyun             u32 destval;
2379*4882a593Smuzhiyun             u32 *srcreg;
2380*4882a593Smuzhiyun 
2381*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
2382*4882a593Smuzhiyun             DECODE_PRINTF(",");
2383*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
2384*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
2385*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2386*4882a593Smuzhiyun             TRACE_AND_STEP();
2387*4882a593Smuzhiyun             destval = sub_long(destval, *srcreg);
2388*4882a593Smuzhiyun             store_data_long(destoffset, destval);
2389*4882a593Smuzhiyun         }
2390*4882a593Smuzhiyun         else {
2391*4882a593Smuzhiyun             u16 destval;
2392*4882a593Smuzhiyun             u16 *srcreg;
2393*4882a593Smuzhiyun 
2394*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
2395*4882a593Smuzhiyun             DECODE_PRINTF(",");
2396*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
2397*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
2398*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2399*4882a593Smuzhiyun             TRACE_AND_STEP();
2400*4882a593Smuzhiyun             destval = sub_word(destval, *srcreg);
2401*4882a593Smuzhiyun             store_data_word(destoffset, destval);
2402*4882a593Smuzhiyun         }
2403*4882a593Smuzhiyun         break;
2404*4882a593Smuzhiyun     case 1:
2405*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2406*4882a593Smuzhiyun             u32 destval;
2407*4882a593Smuzhiyun             u32 *srcreg;
2408*4882a593Smuzhiyun 
2409*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
2410*4882a593Smuzhiyun             DECODE_PRINTF(",");
2411*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
2412*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
2413*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2414*4882a593Smuzhiyun             TRACE_AND_STEP();
2415*4882a593Smuzhiyun             destval = sub_long(destval, *srcreg);
2416*4882a593Smuzhiyun             store_data_long(destoffset, destval);
2417*4882a593Smuzhiyun         }
2418*4882a593Smuzhiyun         else {
2419*4882a593Smuzhiyun             u16 destval;
2420*4882a593Smuzhiyun             u16 *srcreg;
2421*4882a593Smuzhiyun 
2422*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
2423*4882a593Smuzhiyun             DECODE_PRINTF(",");
2424*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
2425*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
2426*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2427*4882a593Smuzhiyun             TRACE_AND_STEP();
2428*4882a593Smuzhiyun             destval = sub_word(destval, *srcreg);
2429*4882a593Smuzhiyun             store_data_word(destoffset, destval);
2430*4882a593Smuzhiyun         }
2431*4882a593Smuzhiyun         break;
2432*4882a593Smuzhiyun     case 2:
2433*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2434*4882a593Smuzhiyun             u32 destval;
2435*4882a593Smuzhiyun             u32 *srcreg;
2436*4882a593Smuzhiyun 
2437*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
2438*4882a593Smuzhiyun             DECODE_PRINTF(",");
2439*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
2440*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
2441*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2442*4882a593Smuzhiyun             TRACE_AND_STEP();
2443*4882a593Smuzhiyun             destval = sub_long(destval, *srcreg);
2444*4882a593Smuzhiyun             store_data_long(destoffset, destval);
2445*4882a593Smuzhiyun         }
2446*4882a593Smuzhiyun         else {
2447*4882a593Smuzhiyun             u16 destval;
2448*4882a593Smuzhiyun             u16 *srcreg;
2449*4882a593Smuzhiyun 
2450*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
2451*4882a593Smuzhiyun             DECODE_PRINTF(",");
2452*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
2453*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
2454*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2455*4882a593Smuzhiyun             TRACE_AND_STEP();
2456*4882a593Smuzhiyun             destval = sub_word(destval, *srcreg);
2457*4882a593Smuzhiyun             store_data_word(destoffset, destval);
2458*4882a593Smuzhiyun         }
2459*4882a593Smuzhiyun         break;
2460*4882a593Smuzhiyun     case 3:                    /* register to register */
2461*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2462*4882a593Smuzhiyun             u32 *destreg, *srcreg;
2463*4882a593Smuzhiyun 
2464*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
2465*4882a593Smuzhiyun             DECODE_PRINTF(",");
2466*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
2467*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2468*4882a593Smuzhiyun             TRACE_AND_STEP();
2469*4882a593Smuzhiyun             *destreg = sub_long(*destreg, *srcreg);
2470*4882a593Smuzhiyun         }
2471*4882a593Smuzhiyun         else {
2472*4882a593Smuzhiyun             u16 *destreg, *srcreg;
2473*4882a593Smuzhiyun 
2474*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
2475*4882a593Smuzhiyun             DECODE_PRINTF(",");
2476*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
2477*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2478*4882a593Smuzhiyun             TRACE_AND_STEP();
2479*4882a593Smuzhiyun             *destreg = sub_word(*destreg, *srcreg);
2480*4882a593Smuzhiyun         }
2481*4882a593Smuzhiyun         break;
2482*4882a593Smuzhiyun     }
2483*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2484*4882a593Smuzhiyun     END_OF_INSTR();
2485*4882a593Smuzhiyun }
2486*4882a593Smuzhiyun 
2487*4882a593Smuzhiyun /****************************************************************************
2488*4882a593Smuzhiyun REMARKS:
2489*4882a593Smuzhiyun Handles opcode 0x2a
2490*4882a593Smuzhiyun ****************************************************************************/
2491*4882a593Smuzhiyun static void
x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED (op1))2492*4882a593Smuzhiyun x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2493*4882a593Smuzhiyun {
2494*4882a593Smuzhiyun     int mod, rl, rh;
2495*4882a593Smuzhiyun     u8 *destreg, *srcreg;
2496*4882a593Smuzhiyun     uint srcoffset;
2497*4882a593Smuzhiyun     u8 srcval;
2498*4882a593Smuzhiyun 
2499*4882a593Smuzhiyun     START_OF_INSTR();
2500*4882a593Smuzhiyun     DECODE_PRINTF("SUB\t");
2501*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
2502*4882a593Smuzhiyun     switch (mod) {
2503*4882a593Smuzhiyun     case 0:
2504*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2505*4882a593Smuzhiyun         DECODE_PRINTF(",");
2506*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
2507*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
2508*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2509*4882a593Smuzhiyun         TRACE_AND_STEP();
2510*4882a593Smuzhiyun         *destreg = sub_byte(*destreg, srcval);
2511*4882a593Smuzhiyun         break;
2512*4882a593Smuzhiyun     case 1:
2513*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2514*4882a593Smuzhiyun         DECODE_PRINTF(",");
2515*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
2516*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
2517*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2518*4882a593Smuzhiyun         TRACE_AND_STEP();
2519*4882a593Smuzhiyun         *destreg = sub_byte(*destreg, srcval);
2520*4882a593Smuzhiyun         break;
2521*4882a593Smuzhiyun     case 2:
2522*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2523*4882a593Smuzhiyun         DECODE_PRINTF(",");
2524*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
2525*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
2526*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2527*4882a593Smuzhiyun         TRACE_AND_STEP();
2528*4882a593Smuzhiyun         *destreg = sub_byte(*destreg, srcval);
2529*4882a593Smuzhiyun         break;
2530*4882a593Smuzhiyun     case 3:                    /* register to register */
2531*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2532*4882a593Smuzhiyun         DECODE_PRINTF(",");
2533*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2534*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2535*4882a593Smuzhiyun         TRACE_AND_STEP();
2536*4882a593Smuzhiyun         *destreg = sub_byte(*destreg, *srcreg);
2537*4882a593Smuzhiyun         break;
2538*4882a593Smuzhiyun     }
2539*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2540*4882a593Smuzhiyun     END_OF_INSTR();
2541*4882a593Smuzhiyun }
2542*4882a593Smuzhiyun 
2543*4882a593Smuzhiyun /****************************************************************************
2544*4882a593Smuzhiyun REMARKS:
2545*4882a593Smuzhiyun Handles opcode 0x2b
2546*4882a593Smuzhiyun ****************************************************************************/
2547*4882a593Smuzhiyun static void
x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED (op1))2548*4882a593Smuzhiyun x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2549*4882a593Smuzhiyun {
2550*4882a593Smuzhiyun     int mod, rl, rh;
2551*4882a593Smuzhiyun     uint srcoffset;
2552*4882a593Smuzhiyun 
2553*4882a593Smuzhiyun     START_OF_INSTR();
2554*4882a593Smuzhiyun     DECODE_PRINTF("SUB\t");
2555*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
2556*4882a593Smuzhiyun     switch (mod) {
2557*4882a593Smuzhiyun     case 0:
2558*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2559*4882a593Smuzhiyun             u32 *destreg;
2560*4882a593Smuzhiyun             u32 srcval;
2561*4882a593Smuzhiyun 
2562*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
2563*4882a593Smuzhiyun             DECODE_PRINTF(",");
2564*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
2565*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
2566*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2567*4882a593Smuzhiyun             TRACE_AND_STEP();
2568*4882a593Smuzhiyun             *destreg = sub_long(*destreg, srcval);
2569*4882a593Smuzhiyun         }
2570*4882a593Smuzhiyun         else {
2571*4882a593Smuzhiyun             u16 *destreg;
2572*4882a593Smuzhiyun             u16 srcval;
2573*4882a593Smuzhiyun 
2574*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
2575*4882a593Smuzhiyun             DECODE_PRINTF(",");
2576*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
2577*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
2578*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2579*4882a593Smuzhiyun             TRACE_AND_STEP();
2580*4882a593Smuzhiyun             *destreg = sub_word(*destreg, srcval);
2581*4882a593Smuzhiyun         }
2582*4882a593Smuzhiyun         break;
2583*4882a593Smuzhiyun     case 1:
2584*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2585*4882a593Smuzhiyun             u32 *destreg;
2586*4882a593Smuzhiyun             u32 srcval;
2587*4882a593Smuzhiyun 
2588*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
2589*4882a593Smuzhiyun             DECODE_PRINTF(",");
2590*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
2591*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
2592*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2593*4882a593Smuzhiyun             TRACE_AND_STEP();
2594*4882a593Smuzhiyun             *destreg = sub_long(*destreg, srcval);
2595*4882a593Smuzhiyun         }
2596*4882a593Smuzhiyun         else {
2597*4882a593Smuzhiyun             u16 *destreg;
2598*4882a593Smuzhiyun             u16 srcval;
2599*4882a593Smuzhiyun 
2600*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
2601*4882a593Smuzhiyun             DECODE_PRINTF(",");
2602*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
2603*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
2604*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2605*4882a593Smuzhiyun             TRACE_AND_STEP();
2606*4882a593Smuzhiyun             *destreg = sub_word(*destreg, srcval);
2607*4882a593Smuzhiyun         }
2608*4882a593Smuzhiyun         break;
2609*4882a593Smuzhiyun     case 2:
2610*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2611*4882a593Smuzhiyun             u32 *destreg;
2612*4882a593Smuzhiyun             u32 srcval;
2613*4882a593Smuzhiyun 
2614*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
2615*4882a593Smuzhiyun             DECODE_PRINTF(",");
2616*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
2617*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
2618*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2619*4882a593Smuzhiyun             TRACE_AND_STEP();
2620*4882a593Smuzhiyun             *destreg = sub_long(*destreg, srcval);
2621*4882a593Smuzhiyun         }
2622*4882a593Smuzhiyun         else {
2623*4882a593Smuzhiyun             u16 *destreg;
2624*4882a593Smuzhiyun             u16 srcval;
2625*4882a593Smuzhiyun 
2626*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
2627*4882a593Smuzhiyun             DECODE_PRINTF(",");
2628*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
2629*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
2630*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2631*4882a593Smuzhiyun             TRACE_AND_STEP();
2632*4882a593Smuzhiyun             *destreg = sub_word(*destreg, srcval);
2633*4882a593Smuzhiyun         }
2634*4882a593Smuzhiyun         break;
2635*4882a593Smuzhiyun     case 3:                    /* register to register */
2636*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2637*4882a593Smuzhiyun             u32 *destreg, *srcreg;
2638*4882a593Smuzhiyun 
2639*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
2640*4882a593Smuzhiyun             DECODE_PRINTF(",");
2641*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
2642*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2643*4882a593Smuzhiyun             TRACE_AND_STEP();
2644*4882a593Smuzhiyun             *destreg = sub_long(*destreg, *srcreg);
2645*4882a593Smuzhiyun         }
2646*4882a593Smuzhiyun         else {
2647*4882a593Smuzhiyun             u16 *destreg, *srcreg;
2648*4882a593Smuzhiyun 
2649*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
2650*4882a593Smuzhiyun             DECODE_PRINTF(",");
2651*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
2652*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2653*4882a593Smuzhiyun             TRACE_AND_STEP();
2654*4882a593Smuzhiyun             *destreg = sub_word(*destreg, *srcreg);
2655*4882a593Smuzhiyun         }
2656*4882a593Smuzhiyun         break;
2657*4882a593Smuzhiyun     }
2658*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2659*4882a593Smuzhiyun     END_OF_INSTR();
2660*4882a593Smuzhiyun }
2661*4882a593Smuzhiyun 
2662*4882a593Smuzhiyun /****************************************************************************
2663*4882a593Smuzhiyun REMARKS:
2664*4882a593Smuzhiyun Handles opcode 0x2c
2665*4882a593Smuzhiyun ****************************************************************************/
2666*4882a593Smuzhiyun static void
x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2667*4882a593Smuzhiyun x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2668*4882a593Smuzhiyun {
2669*4882a593Smuzhiyun     u8 srcval;
2670*4882a593Smuzhiyun 
2671*4882a593Smuzhiyun     START_OF_INSTR();
2672*4882a593Smuzhiyun     DECODE_PRINTF("SUB\tAL,");
2673*4882a593Smuzhiyun     srcval = fetch_byte_imm();
2674*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
2675*4882a593Smuzhiyun     TRACE_AND_STEP();
2676*4882a593Smuzhiyun     M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2677*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2678*4882a593Smuzhiyun     END_OF_INSTR();
2679*4882a593Smuzhiyun }
2680*4882a593Smuzhiyun 
2681*4882a593Smuzhiyun /****************************************************************************
2682*4882a593Smuzhiyun REMARKS:
2683*4882a593Smuzhiyun Handles opcode 0x2d
2684*4882a593Smuzhiyun ****************************************************************************/
2685*4882a593Smuzhiyun static void
x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED (op1))2686*4882a593Smuzhiyun x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2687*4882a593Smuzhiyun {
2688*4882a593Smuzhiyun     u32 srcval;
2689*4882a593Smuzhiyun 
2690*4882a593Smuzhiyun     START_OF_INSTR();
2691*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2692*4882a593Smuzhiyun         DECODE_PRINTF("SUB\tEAX,");
2693*4882a593Smuzhiyun         srcval = fetch_long_imm();
2694*4882a593Smuzhiyun     }
2695*4882a593Smuzhiyun     else {
2696*4882a593Smuzhiyun         DECODE_PRINTF("SUB\tAX,");
2697*4882a593Smuzhiyun         srcval = fetch_word_imm();
2698*4882a593Smuzhiyun     }
2699*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
2700*4882a593Smuzhiyun     TRACE_AND_STEP();
2701*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2702*4882a593Smuzhiyun         M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2703*4882a593Smuzhiyun     }
2704*4882a593Smuzhiyun     else {
2705*4882a593Smuzhiyun         M.x86.R_AX = sub_word(M.x86.R_AX, (u16) srcval);
2706*4882a593Smuzhiyun     }
2707*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2708*4882a593Smuzhiyun     END_OF_INSTR();
2709*4882a593Smuzhiyun }
2710*4882a593Smuzhiyun 
2711*4882a593Smuzhiyun /****************************************************************************
2712*4882a593Smuzhiyun REMARKS:
2713*4882a593Smuzhiyun Handles opcode 0x2e
2714*4882a593Smuzhiyun ****************************************************************************/
2715*4882a593Smuzhiyun static void
x86emuOp_segovr_CS(u8 X86EMU_UNUSED (op1))2716*4882a593Smuzhiyun x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2717*4882a593Smuzhiyun {
2718*4882a593Smuzhiyun     START_OF_INSTR();
2719*4882a593Smuzhiyun     DECODE_PRINTF("CS:\n");
2720*4882a593Smuzhiyun     TRACE_AND_STEP();
2721*4882a593Smuzhiyun     M.x86.mode |= SYSMODE_SEGOVR_CS;
2722*4882a593Smuzhiyun     /* note no DECODE_CLEAR_SEGOVR here. */
2723*4882a593Smuzhiyun     END_OF_INSTR();
2724*4882a593Smuzhiyun }
2725*4882a593Smuzhiyun 
2726*4882a593Smuzhiyun /****************************************************************************
2727*4882a593Smuzhiyun REMARKS:
2728*4882a593Smuzhiyun Handles opcode 0x2f
2729*4882a593Smuzhiyun ****************************************************************************/
2730*4882a593Smuzhiyun static void
x86emuOp_das(u8 X86EMU_UNUSED (op1))2731*4882a593Smuzhiyun x86emuOp_das(u8 X86EMU_UNUSED(op1))
2732*4882a593Smuzhiyun {
2733*4882a593Smuzhiyun     START_OF_INSTR();
2734*4882a593Smuzhiyun     DECODE_PRINTF("DAS\n");
2735*4882a593Smuzhiyun     TRACE_AND_STEP();
2736*4882a593Smuzhiyun     M.x86.R_AL = das_byte(M.x86.R_AL);
2737*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2738*4882a593Smuzhiyun     END_OF_INSTR();
2739*4882a593Smuzhiyun }
2740*4882a593Smuzhiyun 
2741*4882a593Smuzhiyun /****************************************************************************
2742*4882a593Smuzhiyun REMARKS:
2743*4882a593Smuzhiyun Handles opcode 0x30
2744*4882a593Smuzhiyun ****************************************************************************/
2745*4882a593Smuzhiyun static void
x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED (op1))2746*4882a593Smuzhiyun x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2747*4882a593Smuzhiyun {
2748*4882a593Smuzhiyun     int mod, rl, rh;
2749*4882a593Smuzhiyun     u8 *destreg, *srcreg;
2750*4882a593Smuzhiyun     uint destoffset;
2751*4882a593Smuzhiyun     u8 destval;
2752*4882a593Smuzhiyun 
2753*4882a593Smuzhiyun     START_OF_INSTR();
2754*4882a593Smuzhiyun     DECODE_PRINTF("XOR\t");
2755*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
2756*4882a593Smuzhiyun     switch (mod) {
2757*4882a593Smuzhiyun     case 0:
2758*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
2759*4882a593Smuzhiyun         DECODE_PRINTF(",");
2760*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
2761*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2762*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2763*4882a593Smuzhiyun         TRACE_AND_STEP();
2764*4882a593Smuzhiyun         destval = xor_byte(destval, *srcreg);
2765*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
2766*4882a593Smuzhiyun         break;
2767*4882a593Smuzhiyun     case 1:
2768*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
2769*4882a593Smuzhiyun         DECODE_PRINTF(",");
2770*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
2771*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2772*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2773*4882a593Smuzhiyun         TRACE_AND_STEP();
2774*4882a593Smuzhiyun         destval = xor_byte(destval, *srcreg);
2775*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
2776*4882a593Smuzhiyun         break;
2777*4882a593Smuzhiyun     case 2:
2778*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
2779*4882a593Smuzhiyun         DECODE_PRINTF(",");
2780*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
2781*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2782*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2783*4882a593Smuzhiyun         TRACE_AND_STEP();
2784*4882a593Smuzhiyun         destval = xor_byte(destval, *srcreg);
2785*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
2786*4882a593Smuzhiyun         break;
2787*4882a593Smuzhiyun     case 3:                    /* register to register */
2788*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
2789*4882a593Smuzhiyun         DECODE_PRINTF(",");
2790*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2791*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2792*4882a593Smuzhiyun         TRACE_AND_STEP();
2793*4882a593Smuzhiyun         *destreg = xor_byte(*destreg, *srcreg);
2794*4882a593Smuzhiyun         break;
2795*4882a593Smuzhiyun     }
2796*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2797*4882a593Smuzhiyun     END_OF_INSTR();
2798*4882a593Smuzhiyun }
2799*4882a593Smuzhiyun 
2800*4882a593Smuzhiyun /****************************************************************************
2801*4882a593Smuzhiyun REMARKS:
2802*4882a593Smuzhiyun Handles opcode 0x31
2803*4882a593Smuzhiyun ****************************************************************************/
2804*4882a593Smuzhiyun static void
x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED (op1))2805*4882a593Smuzhiyun x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2806*4882a593Smuzhiyun {
2807*4882a593Smuzhiyun     int mod, rl, rh;
2808*4882a593Smuzhiyun     uint destoffset;
2809*4882a593Smuzhiyun 
2810*4882a593Smuzhiyun     START_OF_INSTR();
2811*4882a593Smuzhiyun     DECODE_PRINTF("XOR\t");
2812*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
2813*4882a593Smuzhiyun     switch (mod) {
2814*4882a593Smuzhiyun     case 0:
2815*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2816*4882a593Smuzhiyun             u32 destval;
2817*4882a593Smuzhiyun             u32 *srcreg;
2818*4882a593Smuzhiyun 
2819*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
2820*4882a593Smuzhiyun             DECODE_PRINTF(",");
2821*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
2822*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
2823*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2824*4882a593Smuzhiyun             TRACE_AND_STEP();
2825*4882a593Smuzhiyun             destval = xor_long(destval, *srcreg);
2826*4882a593Smuzhiyun             store_data_long(destoffset, destval);
2827*4882a593Smuzhiyun         }
2828*4882a593Smuzhiyun         else {
2829*4882a593Smuzhiyun             u16 destval;
2830*4882a593Smuzhiyun             u16 *srcreg;
2831*4882a593Smuzhiyun 
2832*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
2833*4882a593Smuzhiyun             DECODE_PRINTF(",");
2834*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
2835*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
2836*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2837*4882a593Smuzhiyun             TRACE_AND_STEP();
2838*4882a593Smuzhiyun             destval = xor_word(destval, *srcreg);
2839*4882a593Smuzhiyun             store_data_word(destoffset, destval);
2840*4882a593Smuzhiyun         }
2841*4882a593Smuzhiyun         break;
2842*4882a593Smuzhiyun     case 1:
2843*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2844*4882a593Smuzhiyun             u32 destval;
2845*4882a593Smuzhiyun             u32 *srcreg;
2846*4882a593Smuzhiyun 
2847*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
2848*4882a593Smuzhiyun             DECODE_PRINTF(",");
2849*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
2850*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
2851*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2852*4882a593Smuzhiyun             TRACE_AND_STEP();
2853*4882a593Smuzhiyun             destval = xor_long(destval, *srcreg);
2854*4882a593Smuzhiyun             store_data_long(destoffset, destval);
2855*4882a593Smuzhiyun         }
2856*4882a593Smuzhiyun         else {
2857*4882a593Smuzhiyun             u16 destval;
2858*4882a593Smuzhiyun             u16 *srcreg;
2859*4882a593Smuzhiyun 
2860*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
2861*4882a593Smuzhiyun             DECODE_PRINTF(",");
2862*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
2863*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
2864*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2865*4882a593Smuzhiyun             TRACE_AND_STEP();
2866*4882a593Smuzhiyun             destval = xor_word(destval, *srcreg);
2867*4882a593Smuzhiyun             store_data_word(destoffset, destval);
2868*4882a593Smuzhiyun         }
2869*4882a593Smuzhiyun         break;
2870*4882a593Smuzhiyun     case 2:
2871*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2872*4882a593Smuzhiyun             u32 destval;
2873*4882a593Smuzhiyun             u32 *srcreg;
2874*4882a593Smuzhiyun 
2875*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
2876*4882a593Smuzhiyun             DECODE_PRINTF(",");
2877*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
2878*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
2879*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2880*4882a593Smuzhiyun             TRACE_AND_STEP();
2881*4882a593Smuzhiyun             destval = xor_long(destval, *srcreg);
2882*4882a593Smuzhiyun             store_data_long(destoffset, destval);
2883*4882a593Smuzhiyun         }
2884*4882a593Smuzhiyun         else {
2885*4882a593Smuzhiyun             u16 destval;
2886*4882a593Smuzhiyun             u16 *srcreg;
2887*4882a593Smuzhiyun 
2888*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
2889*4882a593Smuzhiyun             DECODE_PRINTF(",");
2890*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
2891*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
2892*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2893*4882a593Smuzhiyun             TRACE_AND_STEP();
2894*4882a593Smuzhiyun             destval = xor_word(destval, *srcreg);
2895*4882a593Smuzhiyun             store_data_word(destoffset, destval);
2896*4882a593Smuzhiyun         }
2897*4882a593Smuzhiyun         break;
2898*4882a593Smuzhiyun     case 3:                    /* register to register */
2899*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2900*4882a593Smuzhiyun             u32 *destreg, *srcreg;
2901*4882a593Smuzhiyun 
2902*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
2903*4882a593Smuzhiyun             DECODE_PRINTF(",");
2904*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
2905*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2906*4882a593Smuzhiyun             TRACE_AND_STEP();
2907*4882a593Smuzhiyun             *destreg = xor_long(*destreg, *srcreg);
2908*4882a593Smuzhiyun         }
2909*4882a593Smuzhiyun         else {
2910*4882a593Smuzhiyun             u16 *destreg, *srcreg;
2911*4882a593Smuzhiyun 
2912*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
2913*4882a593Smuzhiyun             DECODE_PRINTF(",");
2914*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
2915*4882a593Smuzhiyun             DECODE_PRINTF("\n");
2916*4882a593Smuzhiyun             TRACE_AND_STEP();
2917*4882a593Smuzhiyun             *destreg = xor_word(*destreg, *srcreg);
2918*4882a593Smuzhiyun         }
2919*4882a593Smuzhiyun         break;
2920*4882a593Smuzhiyun     }
2921*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2922*4882a593Smuzhiyun     END_OF_INSTR();
2923*4882a593Smuzhiyun }
2924*4882a593Smuzhiyun 
2925*4882a593Smuzhiyun /****************************************************************************
2926*4882a593Smuzhiyun REMARKS:
2927*4882a593Smuzhiyun Handles opcode 0x32
2928*4882a593Smuzhiyun ****************************************************************************/
2929*4882a593Smuzhiyun static void
x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED (op1))2930*4882a593Smuzhiyun x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2931*4882a593Smuzhiyun {
2932*4882a593Smuzhiyun     int mod, rl, rh;
2933*4882a593Smuzhiyun     u8 *destreg, *srcreg;
2934*4882a593Smuzhiyun     uint srcoffset;
2935*4882a593Smuzhiyun     u8 srcval;
2936*4882a593Smuzhiyun 
2937*4882a593Smuzhiyun     START_OF_INSTR();
2938*4882a593Smuzhiyun     DECODE_PRINTF("XOR\t");
2939*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
2940*4882a593Smuzhiyun     switch (mod) {
2941*4882a593Smuzhiyun     case 0:
2942*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2943*4882a593Smuzhiyun         DECODE_PRINTF(",");
2944*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
2945*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
2946*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2947*4882a593Smuzhiyun         TRACE_AND_STEP();
2948*4882a593Smuzhiyun         *destreg = xor_byte(*destreg, srcval);
2949*4882a593Smuzhiyun         break;
2950*4882a593Smuzhiyun     case 1:
2951*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2952*4882a593Smuzhiyun         DECODE_PRINTF(",");
2953*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
2954*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
2955*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2956*4882a593Smuzhiyun         TRACE_AND_STEP();
2957*4882a593Smuzhiyun         *destreg = xor_byte(*destreg, srcval);
2958*4882a593Smuzhiyun         break;
2959*4882a593Smuzhiyun     case 2:
2960*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2961*4882a593Smuzhiyun         DECODE_PRINTF(",");
2962*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
2963*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
2964*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2965*4882a593Smuzhiyun         TRACE_AND_STEP();
2966*4882a593Smuzhiyun         *destreg = xor_byte(*destreg, srcval);
2967*4882a593Smuzhiyun         break;
2968*4882a593Smuzhiyun     case 3:                    /* register to register */
2969*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
2970*4882a593Smuzhiyun         DECODE_PRINTF(",");
2971*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2972*4882a593Smuzhiyun         DECODE_PRINTF("\n");
2973*4882a593Smuzhiyun         TRACE_AND_STEP();
2974*4882a593Smuzhiyun         *destreg = xor_byte(*destreg, *srcreg);
2975*4882a593Smuzhiyun         break;
2976*4882a593Smuzhiyun     }
2977*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
2978*4882a593Smuzhiyun     END_OF_INSTR();
2979*4882a593Smuzhiyun }
2980*4882a593Smuzhiyun 
2981*4882a593Smuzhiyun /****************************************************************************
2982*4882a593Smuzhiyun REMARKS:
2983*4882a593Smuzhiyun Handles opcode 0x33
2984*4882a593Smuzhiyun ****************************************************************************/
2985*4882a593Smuzhiyun static void
x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED (op1))2986*4882a593Smuzhiyun x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2987*4882a593Smuzhiyun {
2988*4882a593Smuzhiyun     int mod, rl, rh;
2989*4882a593Smuzhiyun     uint srcoffset;
2990*4882a593Smuzhiyun 
2991*4882a593Smuzhiyun     START_OF_INSTR();
2992*4882a593Smuzhiyun     DECODE_PRINTF("XOR\t");
2993*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
2994*4882a593Smuzhiyun     switch (mod) {
2995*4882a593Smuzhiyun     case 0:
2996*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2997*4882a593Smuzhiyun             u32 *destreg;
2998*4882a593Smuzhiyun             u32 srcval;
2999*4882a593Smuzhiyun 
3000*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
3001*4882a593Smuzhiyun             DECODE_PRINTF(",");
3002*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
3003*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
3004*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3005*4882a593Smuzhiyun             TRACE_AND_STEP();
3006*4882a593Smuzhiyun             *destreg = xor_long(*destreg, srcval);
3007*4882a593Smuzhiyun         }
3008*4882a593Smuzhiyun         else {
3009*4882a593Smuzhiyun             u16 *destreg;
3010*4882a593Smuzhiyun             u16 srcval;
3011*4882a593Smuzhiyun 
3012*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
3013*4882a593Smuzhiyun             DECODE_PRINTF(",");
3014*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
3015*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
3016*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3017*4882a593Smuzhiyun             TRACE_AND_STEP();
3018*4882a593Smuzhiyun             *destreg = xor_word(*destreg, srcval);
3019*4882a593Smuzhiyun         }
3020*4882a593Smuzhiyun         break;
3021*4882a593Smuzhiyun     case 1:
3022*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3023*4882a593Smuzhiyun             u32 *destreg;
3024*4882a593Smuzhiyun             u32 srcval;
3025*4882a593Smuzhiyun 
3026*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
3027*4882a593Smuzhiyun             DECODE_PRINTF(",");
3028*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
3029*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
3030*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3031*4882a593Smuzhiyun             TRACE_AND_STEP();
3032*4882a593Smuzhiyun             *destreg = xor_long(*destreg, srcval);
3033*4882a593Smuzhiyun         }
3034*4882a593Smuzhiyun         else {
3035*4882a593Smuzhiyun             u16 *destreg;
3036*4882a593Smuzhiyun             u16 srcval;
3037*4882a593Smuzhiyun 
3038*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
3039*4882a593Smuzhiyun             DECODE_PRINTF(",");
3040*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
3041*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
3042*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3043*4882a593Smuzhiyun             TRACE_AND_STEP();
3044*4882a593Smuzhiyun             *destreg = xor_word(*destreg, srcval);
3045*4882a593Smuzhiyun         }
3046*4882a593Smuzhiyun         break;
3047*4882a593Smuzhiyun     case 2:
3048*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3049*4882a593Smuzhiyun             u32 *destreg;
3050*4882a593Smuzhiyun             u32 srcval;
3051*4882a593Smuzhiyun 
3052*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
3053*4882a593Smuzhiyun             DECODE_PRINTF(",");
3054*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
3055*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
3056*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3057*4882a593Smuzhiyun             TRACE_AND_STEP();
3058*4882a593Smuzhiyun             *destreg = xor_long(*destreg, srcval);
3059*4882a593Smuzhiyun         }
3060*4882a593Smuzhiyun         else {
3061*4882a593Smuzhiyun             u16 *destreg;
3062*4882a593Smuzhiyun             u16 srcval;
3063*4882a593Smuzhiyun 
3064*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
3065*4882a593Smuzhiyun             DECODE_PRINTF(",");
3066*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
3067*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
3068*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3069*4882a593Smuzhiyun             TRACE_AND_STEP();
3070*4882a593Smuzhiyun             *destreg = xor_word(*destreg, srcval);
3071*4882a593Smuzhiyun         }
3072*4882a593Smuzhiyun         break;
3073*4882a593Smuzhiyun     case 3:                    /* register to register */
3074*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3075*4882a593Smuzhiyun             u32 *destreg, *srcreg;
3076*4882a593Smuzhiyun 
3077*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
3078*4882a593Smuzhiyun             DECODE_PRINTF(",");
3079*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
3080*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3081*4882a593Smuzhiyun             TRACE_AND_STEP();
3082*4882a593Smuzhiyun             *destreg = xor_long(*destreg, *srcreg);
3083*4882a593Smuzhiyun         }
3084*4882a593Smuzhiyun         else {
3085*4882a593Smuzhiyun             u16 *destreg, *srcreg;
3086*4882a593Smuzhiyun 
3087*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
3088*4882a593Smuzhiyun             DECODE_PRINTF(",");
3089*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
3090*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3091*4882a593Smuzhiyun             TRACE_AND_STEP();
3092*4882a593Smuzhiyun             *destreg = xor_word(*destreg, *srcreg);
3093*4882a593Smuzhiyun         }
3094*4882a593Smuzhiyun         break;
3095*4882a593Smuzhiyun     }
3096*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3097*4882a593Smuzhiyun     END_OF_INSTR();
3098*4882a593Smuzhiyun }
3099*4882a593Smuzhiyun 
3100*4882a593Smuzhiyun /****************************************************************************
3101*4882a593Smuzhiyun REMARKS:
3102*4882a593Smuzhiyun Handles opcode 0x34
3103*4882a593Smuzhiyun ****************************************************************************/
3104*4882a593Smuzhiyun static void
x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED (op1))3105*4882a593Smuzhiyun x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3106*4882a593Smuzhiyun {
3107*4882a593Smuzhiyun     u8 srcval;
3108*4882a593Smuzhiyun 
3109*4882a593Smuzhiyun     START_OF_INSTR();
3110*4882a593Smuzhiyun     DECODE_PRINTF("XOR\tAL,");
3111*4882a593Smuzhiyun     srcval = fetch_byte_imm();
3112*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
3113*4882a593Smuzhiyun     TRACE_AND_STEP();
3114*4882a593Smuzhiyun     M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
3115*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3116*4882a593Smuzhiyun     END_OF_INSTR();
3117*4882a593Smuzhiyun }
3118*4882a593Smuzhiyun 
3119*4882a593Smuzhiyun /****************************************************************************
3120*4882a593Smuzhiyun REMARKS:
3121*4882a593Smuzhiyun Handles opcode 0x35
3122*4882a593Smuzhiyun ****************************************************************************/
3123*4882a593Smuzhiyun static void
x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED (op1))3124*4882a593Smuzhiyun x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3125*4882a593Smuzhiyun {
3126*4882a593Smuzhiyun     u32 srcval;
3127*4882a593Smuzhiyun 
3128*4882a593Smuzhiyun     START_OF_INSTR();
3129*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3130*4882a593Smuzhiyun         DECODE_PRINTF("XOR\tEAX,");
3131*4882a593Smuzhiyun         srcval = fetch_long_imm();
3132*4882a593Smuzhiyun     }
3133*4882a593Smuzhiyun     else {
3134*4882a593Smuzhiyun         DECODE_PRINTF("XOR\tAX,");
3135*4882a593Smuzhiyun         srcval = fetch_word_imm();
3136*4882a593Smuzhiyun     }
3137*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
3138*4882a593Smuzhiyun     TRACE_AND_STEP();
3139*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3140*4882a593Smuzhiyun         M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3141*4882a593Smuzhiyun     }
3142*4882a593Smuzhiyun     else {
3143*4882a593Smuzhiyun         M.x86.R_AX = xor_word(M.x86.R_AX, (u16) srcval);
3144*4882a593Smuzhiyun     }
3145*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3146*4882a593Smuzhiyun     END_OF_INSTR();
3147*4882a593Smuzhiyun }
3148*4882a593Smuzhiyun 
3149*4882a593Smuzhiyun /****************************************************************************
3150*4882a593Smuzhiyun REMARKS:
3151*4882a593Smuzhiyun Handles opcode 0x36
3152*4882a593Smuzhiyun ****************************************************************************/
3153*4882a593Smuzhiyun static void
x86emuOp_segovr_SS(u8 X86EMU_UNUSED (op1))3154*4882a593Smuzhiyun x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3155*4882a593Smuzhiyun {
3156*4882a593Smuzhiyun     START_OF_INSTR();
3157*4882a593Smuzhiyun     DECODE_PRINTF("SS:\n");
3158*4882a593Smuzhiyun     TRACE_AND_STEP();
3159*4882a593Smuzhiyun     M.x86.mode |= SYSMODE_SEGOVR_SS;
3160*4882a593Smuzhiyun     /* no DECODE_CLEAR_SEGOVR ! */
3161*4882a593Smuzhiyun     END_OF_INSTR();
3162*4882a593Smuzhiyun }
3163*4882a593Smuzhiyun 
3164*4882a593Smuzhiyun /****************************************************************************
3165*4882a593Smuzhiyun REMARKS:
3166*4882a593Smuzhiyun Handles opcode 0x37
3167*4882a593Smuzhiyun ****************************************************************************/
3168*4882a593Smuzhiyun static void
x86emuOp_aaa(u8 X86EMU_UNUSED (op1))3169*4882a593Smuzhiyun x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3170*4882a593Smuzhiyun {
3171*4882a593Smuzhiyun     START_OF_INSTR();
3172*4882a593Smuzhiyun     DECODE_PRINTF("AAA\n");
3173*4882a593Smuzhiyun     TRACE_AND_STEP();
3174*4882a593Smuzhiyun     M.x86.R_AX = aaa_word(M.x86.R_AX);
3175*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3176*4882a593Smuzhiyun     END_OF_INSTR();
3177*4882a593Smuzhiyun }
3178*4882a593Smuzhiyun 
3179*4882a593Smuzhiyun /****************************************************************************
3180*4882a593Smuzhiyun REMARKS:
3181*4882a593Smuzhiyun Handles opcode 0x38
3182*4882a593Smuzhiyun ****************************************************************************/
3183*4882a593Smuzhiyun static void
x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED (op1))3184*4882a593Smuzhiyun x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3185*4882a593Smuzhiyun {
3186*4882a593Smuzhiyun     int mod, rl, rh;
3187*4882a593Smuzhiyun     uint destoffset;
3188*4882a593Smuzhiyun     u8 *destreg, *srcreg;
3189*4882a593Smuzhiyun     u8 destval;
3190*4882a593Smuzhiyun 
3191*4882a593Smuzhiyun     START_OF_INSTR();
3192*4882a593Smuzhiyun     DECODE_PRINTF("CMP\t");
3193*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
3194*4882a593Smuzhiyun     switch (mod) {
3195*4882a593Smuzhiyun     case 0:
3196*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
3197*4882a593Smuzhiyun         DECODE_PRINTF(",");
3198*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
3199*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3200*4882a593Smuzhiyun         DECODE_PRINTF("\n");
3201*4882a593Smuzhiyun         TRACE_AND_STEP();
3202*4882a593Smuzhiyun         cmp_byte(destval, *srcreg);
3203*4882a593Smuzhiyun         break;
3204*4882a593Smuzhiyun     case 1:
3205*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
3206*4882a593Smuzhiyun         DECODE_PRINTF(",");
3207*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
3208*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3209*4882a593Smuzhiyun         DECODE_PRINTF("\n");
3210*4882a593Smuzhiyun         TRACE_AND_STEP();
3211*4882a593Smuzhiyun         cmp_byte(destval, *srcreg);
3212*4882a593Smuzhiyun         break;
3213*4882a593Smuzhiyun     case 2:
3214*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
3215*4882a593Smuzhiyun         DECODE_PRINTF(",");
3216*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
3217*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3218*4882a593Smuzhiyun         DECODE_PRINTF("\n");
3219*4882a593Smuzhiyun         TRACE_AND_STEP();
3220*4882a593Smuzhiyun         cmp_byte(destval, *srcreg);
3221*4882a593Smuzhiyun         break;
3222*4882a593Smuzhiyun     case 3:                    /* register to register */
3223*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
3224*4882a593Smuzhiyun         DECODE_PRINTF(",");
3225*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3226*4882a593Smuzhiyun         DECODE_PRINTF("\n");
3227*4882a593Smuzhiyun         TRACE_AND_STEP();
3228*4882a593Smuzhiyun         cmp_byte(*destreg, *srcreg);
3229*4882a593Smuzhiyun         break;
3230*4882a593Smuzhiyun     }
3231*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3232*4882a593Smuzhiyun     END_OF_INSTR();
3233*4882a593Smuzhiyun }
3234*4882a593Smuzhiyun 
3235*4882a593Smuzhiyun /****************************************************************************
3236*4882a593Smuzhiyun REMARKS:
3237*4882a593Smuzhiyun Handles opcode 0x39
3238*4882a593Smuzhiyun ****************************************************************************/
3239*4882a593Smuzhiyun static void
x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED (op1))3240*4882a593Smuzhiyun x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3241*4882a593Smuzhiyun {
3242*4882a593Smuzhiyun     int mod, rl, rh;
3243*4882a593Smuzhiyun     uint destoffset;
3244*4882a593Smuzhiyun 
3245*4882a593Smuzhiyun     START_OF_INSTR();
3246*4882a593Smuzhiyun     DECODE_PRINTF("CMP\t");
3247*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
3248*4882a593Smuzhiyun     switch (mod) {
3249*4882a593Smuzhiyun     case 0:
3250*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3251*4882a593Smuzhiyun             u32 destval;
3252*4882a593Smuzhiyun             u32 *srcreg;
3253*4882a593Smuzhiyun 
3254*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
3255*4882a593Smuzhiyun             DECODE_PRINTF(",");
3256*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
3257*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
3258*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3259*4882a593Smuzhiyun             TRACE_AND_STEP();
3260*4882a593Smuzhiyun             cmp_long(destval, *srcreg);
3261*4882a593Smuzhiyun         }
3262*4882a593Smuzhiyun         else {
3263*4882a593Smuzhiyun             u16 destval;
3264*4882a593Smuzhiyun             u16 *srcreg;
3265*4882a593Smuzhiyun 
3266*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
3267*4882a593Smuzhiyun             DECODE_PRINTF(",");
3268*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
3269*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
3270*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3271*4882a593Smuzhiyun             TRACE_AND_STEP();
3272*4882a593Smuzhiyun             cmp_word(destval, *srcreg);
3273*4882a593Smuzhiyun         }
3274*4882a593Smuzhiyun         break;
3275*4882a593Smuzhiyun     case 1:
3276*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3277*4882a593Smuzhiyun             u32 destval;
3278*4882a593Smuzhiyun             u32 *srcreg;
3279*4882a593Smuzhiyun 
3280*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
3281*4882a593Smuzhiyun             DECODE_PRINTF(",");
3282*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
3283*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
3284*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3285*4882a593Smuzhiyun             TRACE_AND_STEP();
3286*4882a593Smuzhiyun             cmp_long(destval, *srcreg);
3287*4882a593Smuzhiyun         }
3288*4882a593Smuzhiyun         else {
3289*4882a593Smuzhiyun             u16 destval;
3290*4882a593Smuzhiyun             u16 *srcreg;
3291*4882a593Smuzhiyun 
3292*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
3293*4882a593Smuzhiyun             DECODE_PRINTF(",");
3294*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
3295*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
3296*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3297*4882a593Smuzhiyun             TRACE_AND_STEP();
3298*4882a593Smuzhiyun             cmp_word(destval, *srcreg);
3299*4882a593Smuzhiyun         }
3300*4882a593Smuzhiyun         break;
3301*4882a593Smuzhiyun     case 2:
3302*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3303*4882a593Smuzhiyun             u32 destval;
3304*4882a593Smuzhiyun             u32 *srcreg;
3305*4882a593Smuzhiyun 
3306*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
3307*4882a593Smuzhiyun             DECODE_PRINTF(",");
3308*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
3309*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
3310*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3311*4882a593Smuzhiyun             TRACE_AND_STEP();
3312*4882a593Smuzhiyun             cmp_long(destval, *srcreg);
3313*4882a593Smuzhiyun         }
3314*4882a593Smuzhiyun         else {
3315*4882a593Smuzhiyun             u16 destval;
3316*4882a593Smuzhiyun             u16 *srcreg;
3317*4882a593Smuzhiyun 
3318*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
3319*4882a593Smuzhiyun             DECODE_PRINTF(",");
3320*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
3321*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
3322*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3323*4882a593Smuzhiyun             TRACE_AND_STEP();
3324*4882a593Smuzhiyun             cmp_word(destval, *srcreg);
3325*4882a593Smuzhiyun         }
3326*4882a593Smuzhiyun         break;
3327*4882a593Smuzhiyun     case 3:                    /* register to register */
3328*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3329*4882a593Smuzhiyun             u32 *destreg, *srcreg;
3330*4882a593Smuzhiyun 
3331*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
3332*4882a593Smuzhiyun             DECODE_PRINTF(",");
3333*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
3334*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3335*4882a593Smuzhiyun             TRACE_AND_STEP();
3336*4882a593Smuzhiyun             cmp_long(*destreg, *srcreg);
3337*4882a593Smuzhiyun         }
3338*4882a593Smuzhiyun         else {
3339*4882a593Smuzhiyun             u16 *destreg, *srcreg;
3340*4882a593Smuzhiyun 
3341*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
3342*4882a593Smuzhiyun             DECODE_PRINTF(",");
3343*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
3344*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3345*4882a593Smuzhiyun             TRACE_AND_STEP();
3346*4882a593Smuzhiyun             cmp_word(*destreg, *srcreg);
3347*4882a593Smuzhiyun         }
3348*4882a593Smuzhiyun         break;
3349*4882a593Smuzhiyun     }
3350*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3351*4882a593Smuzhiyun     END_OF_INSTR();
3352*4882a593Smuzhiyun }
3353*4882a593Smuzhiyun 
3354*4882a593Smuzhiyun /****************************************************************************
3355*4882a593Smuzhiyun REMARKS:
3356*4882a593Smuzhiyun Handles opcode 0x3a
3357*4882a593Smuzhiyun ****************************************************************************/
3358*4882a593Smuzhiyun static void
x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED (op1))3359*4882a593Smuzhiyun x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3360*4882a593Smuzhiyun {
3361*4882a593Smuzhiyun     int mod, rl, rh;
3362*4882a593Smuzhiyun     u8 *destreg, *srcreg;
3363*4882a593Smuzhiyun     uint srcoffset;
3364*4882a593Smuzhiyun     u8 srcval;
3365*4882a593Smuzhiyun 
3366*4882a593Smuzhiyun     START_OF_INSTR();
3367*4882a593Smuzhiyun     DECODE_PRINTF("CMP\t");
3368*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
3369*4882a593Smuzhiyun     switch (mod) {
3370*4882a593Smuzhiyun     case 0:
3371*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
3372*4882a593Smuzhiyun         DECODE_PRINTF(",");
3373*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
3374*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
3375*4882a593Smuzhiyun         DECODE_PRINTF("\n");
3376*4882a593Smuzhiyun         TRACE_AND_STEP();
3377*4882a593Smuzhiyun         cmp_byte(*destreg, srcval);
3378*4882a593Smuzhiyun         break;
3379*4882a593Smuzhiyun     case 1:
3380*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
3381*4882a593Smuzhiyun         DECODE_PRINTF(",");
3382*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
3383*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
3384*4882a593Smuzhiyun         DECODE_PRINTF("\n");
3385*4882a593Smuzhiyun         TRACE_AND_STEP();
3386*4882a593Smuzhiyun         cmp_byte(*destreg, srcval);
3387*4882a593Smuzhiyun         break;
3388*4882a593Smuzhiyun     case 2:
3389*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
3390*4882a593Smuzhiyun         DECODE_PRINTF(",");
3391*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
3392*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
3393*4882a593Smuzhiyun         DECODE_PRINTF("\n");
3394*4882a593Smuzhiyun         TRACE_AND_STEP();
3395*4882a593Smuzhiyun         cmp_byte(*destreg, srcval);
3396*4882a593Smuzhiyun         break;
3397*4882a593Smuzhiyun     case 3:                    /* register to register */
3398*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
3399*4882a593Smuzhiyun         DECODE_PRINTF(",");
3400*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rl);
3401*4882a593Smuzhiyun         DECODE_PRINTF("\n");
3402*4882a593Smuzhiyun         TRACE_AND_STEP();
3403*4882a593Smuzhiyun         cmp_byte(*destreg, *srcreg);
3404*4882a593Smuzhiyun         break;
3405*4882a593Smuzhiyun     }
3406*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3407*4882a593Smuzhiyun     END_OF_INSTR();
3408*4882a593Smuzhiyun }
3409*4882a593Smuzhiyun 
3410*4882a593Smuzhiyun /****************************************************************************
3411*4882a593Smuzhiyun REMARKS:
3412*4882a593Smuzhiyun Handles opcode 0x3b
3413*4882a593Smuzhiyun ****************************************************************************/
3414*4882a593Smuzhiyun static void
x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED (op1))3415*4882a593Smuzhiyun x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3416*4882a593Smuzhiyun {
3417*4882a593Smuzhiyun     int mod, rl, rh;
3418*4882a593Smuzhiyun     uint srcoffset;
3419*4882a593Smuzhiyun 
3420*4882a593Smuzhiyun     START_OF_INSTR();
3421*4882a593Smuzhiyun     DECODE_PRINTF("CMP\t");
3422*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
3423*4882a593Smuzhiyun     switch (mod) {
3424*4882a593Smuzhiyun     case 0:
3425*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3426*4882a593Smuzhiyun             u32 *destreg;
3427*4882a593Smuzhiyun             u32 srcval;
3428*4882a593Smuzhiyun 
3429*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
3430*4882a593Smuzhiyun             DECODE_PRINTF(",");
3431*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
3432*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
3433*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3434*4882a593Smuzhiyun             TRACE_AND_STEP();
3435*4882a593Smuzhiyun             cmp_long(*destreg, srcval);
3436*4882a593Smuzhiyun         }
3437*4882a593Smuzhiyun         else {
3438*4882a593Smuzhiyun             u16 *destreg;
3439*4882a593Smuzhiyun             u16 srcval;
3440*4882a593Smuzhiyun 
3441*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
3442*4882a593Smuzhiyun             DECODE_PRINTF(",");
3443*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
3444*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
3445*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3446*4882a593Smuzhiyun             TRACE_AND_STEP();
3447*4882a593Smuzhiyun             cmp_word(*destreg, srcval);
3448*4882a593Smuzhiyun         }
3449*4882a593Smuzhiyun         break;
3450*4882a593Smuzhiyun     case 1:
3451*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3452*4882a593Smuzhiyun             u32 *destreg;
3453*4882a593Smuzhiyun             u32 srcval;
3454*4882a593Smuzhiyun 
3455*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
3456*4882a593Smuzhiyun             DECODE_PRINTF(",");
3457*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
3458*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
3459*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3460*4882a593Smuzhiyun             TRACE_AND_STEP();
3461*4882a593Smuzhiyun             cmp_long(*destreg, srcval);
3462*4882a593Smuzhiyun         }
3463*4882a593Smuzhiyun         else {
3464*4882a593Smuzhiyun             u16 *destreg;
3465*4882a593Smuzhiyun             u16 srcval;
3466*4882a593Smuzhiyun 
3467*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
3468*4882a593Smuzhiyun             DECODE_PRINTF(",");
3469*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
3470*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
3471*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3472*4882a593Smuzhiyun             TRACE_AND_STEP();
3473*4882a593Smuzhiyun             cmp_word(*destreg, srcval);
3474*4882a593Smuzhiyun         }
3475*4882a593Smuzhiyun         break;
3476*4882a593Smuzhiyun     case 2:
3477*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3478*4882a593Smuzhiyun             u32 *destreg;
3479*4882a593Smuzhiyun             u32 srcval;
3480*4882a593Smuzhiyun 
3481*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
3482*4882a593Smuzhiyun             DECODE_PRINTF(",");
3483*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
3484*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
3485*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3486*4882a593Smuzhiyun             TRACE_AND_STEP();
3487*4882a593Smuzhiyun             cmp_long(*destreg, srcval);
3488*4882a593Smuzhiyun         }
3489*4882a593Smuzhiyun         else {
3490*4882a593Smuzhiyun             u16 *destreg;
3491*4882a593Smuzhiyun             u16 srcval;
3492*4882a593Smuzhiyun 
3493*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
3494*4882a593Smuzhiyun             DECODE_PRINTF(",");
3495*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
3496*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
3497*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3498*4882a593Smuzhiyun             TRACE_AND_STEP();
3499*4882a593Smuzhiyun             cmp_word(*destreg, srcval);
3500*4882a593Smuzhiyun         }
3501*4882a593Smuzhiyun         break;
3502*4882a593Smuzhiyun     case 3:                    /* register to register */
3503*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3504*4882a593Smuzhiyun             u32 *destreg, *srcreg;
3505*4882a593Smuzhiyun 
3506*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
3507*4882a593Smuzhiyun             DECODE_PRINTF(",");
3508*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
3509*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3510*4882a593Smuzhiyun             TRACE_AND_STEP();
3511*4882a593Smuzhiyun             cmp_long(*destreg, *srcreg);
3512*4882a593Smuzhiyun         }
3513*4882a593Smuzhiyun         else {
3514*4882a593Smuzhiyun             u16 *destreg, *srcreg;
3515*4882a593Smuzhiyun 
3516*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
3517*4882a593Smuzhiyun             DECODE_PRINTF(",");
3518*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
3519*4882a593Smuzhiyun             DECODE_PRINTF("\n");
3520*4882a593Smuzhiyun             TRACE_AND_STEP();
3521*4882a593Smuzhiyun             cmp_word(*destreg, *srcreg);
3522*4882a593Smuzhiyun         }
3523*4882a593Smuzhiyun         break;
3524*4882a593Smuzhiyun     }
3525*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3526*4882a593Smuzhiyun     END_OF_INSTR();
3527*4882a593Smuzhiyun }
3528*4882a593Smuzhiyun 
3529*4882a593Smuzhiyun /****************************************************************************
3530*4882a593Smuzhiyun REMARKS:
3531*4882a593Smuzhiyun Handles opcode 0x3c
3532*4882a593Smuzhiyun ****************************************************************************/
3533*4882a593Smuzhiyun static void
x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED (op1))3534*4882a593Smuzhiyun x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3535*4882a593Smuzhiyun {
3536*4882a593Smuzhiyun     u8 srcval;
3537*4882a593Smuzhiyun 
3538*4882a593Smuzhiyun     START_OF_INSTR();
3539*4882a593Smuzhiyun     DECODE_PRINTF("CMP\tAL,");
3540*4882a593Smuzhiyun     srcval = fetch_byte_imm();
3541*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
3542*4882a593Smuzhiyun     TRACE_AND_STEP();
3543*4882a593Smuzhiyun     cmp_byte(M.x86.R_AL, srcval);
3544*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3545*4882a593Smuzhiyun     END_OF_INSTR();
3546*4882a593Smuzhiyun }
3547*4882a593Smuzhiyun 
3548*4882a593Smuzhiyun /****************************************************************************
3549*4882a593Smuzhiyun REMARKS:
3550*4882a593Smuzhiyun Handles opcode 0x3d
3551*4882a593Smuzhiyun ****************************************************************************/
3552*4882a593Smuzhiyun static void
x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED (op1))3553*4882a593Smuzhiyun x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3554*4882a593Smuzhiyun {
3555*4882a593Smuzhiyun     u32 srcval;
3556*4882a593Smuzhiyun 
3557*4882a593Smuzhiyun     START_OF_INSTR();
3558*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3559*4882a593Smuzhiyun         DECODE_PRINTF("CMP\tEAX,");
3560*4882a593Smuzhiyun         srcval = fetch_long_imm();
3561*4882a593Smuzhiyun     }
3562*4882a593Smuzhiyun     else {
3563*4882a593Smuzhiyun         DECODE_PRINTF("CMP\tAX,");
3564*4882a593Smuzhiyun         srcval = fetch_word_imm();
3565*4882a593Smuzhiyun     }
3566*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
3567*4882a593Smuzhiyun     TRACE_AND_STEP();
3568*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3569*4882a593Smuzhiyun         cmp_long(M.x86.R_EAX, srcval);
3570*4882a593Smuzhiyun     }
3571*4882a593Smuzhiyun     else {
3572*4882a593Smuzhiyun         cmp_word(M.x86.R_AX, (u16) srcval);
3573*4882a593Smuzhiyun     }
3574*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3575*4882a593Smuzhiyun     END_OF_INSTR();
3576*4882a593Smuzhiyun }
3577*4882a593Smuzhiyun 
3578*4882a593Smuzhiyun /****************************************************************************
3579*4882a593Smuzhiyun REMARKS:
3580*4882a593Smuzhiyun Handles opcode 0x3e
3581*4882a593Smuzhiyun ****************************************************************************/
3582*4882a593Smuzhiyun static void
x86emuOp_segovr_DS(u8 X86EMU_UNUSED (op1))3583*4882a593Smuzhiyun x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3584*4882a593Smuzhiyun {
3585*4882a593Smuzhiyun     START_OF_INSTR();
3586*4882a593Smuzhiyun     DECODE_PRINTF("DS:\n");
3587*4882a593Smuzhiyun     TRACE_AND_STEP();
3588*4882a593Smuzhiyun     M.x86.mode |= SYSMODE_SEGOVR_DS;
3589*4882a593Smuzhiyun     /* NO DECODE_CLEAR_SEGOVR! */
3590*4882a593Smuzhiyun     END_OF_INSTR();
3591*4882a593Smuzhiyun }
3592*4882a593Smuzhiyun 
3593*4882a593Smuzhiyun /****************************************************************************
3594*4882a593Smuzhiyun REMARKS:
3595*4882a593Smuzhiyun Handles opcode 0x3f
3596*4882a593Smuzhiyun ****************************************************************************/
3597*4882a593Smuzhiyun static void
x86emuOp_aas(u8 X86EMU_UNUSED (op1))3598*4882a593Smuzhiyun x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3599*4882a593Smuzhiyun {
3600*4882a593Smuzhiyun     START_OF_INSTR();
3601*4882a593Smuzhiyun     DECODE_PRINTF("AAS\n");
3602*4882a593Smuzhiyun     TRACE_AND_STEP();
3603*4882a593Smuzhiyun     M.x86.R_AX = aas_word(M.x86.R_AX);
3604*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3605*4882a593Smuzhiyun     END_OF_INSTR();
3606*4882a593Smuzhiyun }
3607*4882a593Smuzhiyun 
3608*4882a593Smuzhiyun /****************************************************************************
3609*4882a593Smuzhiyun REMARKS:
3610*4882a593Smuzhiyun Handles opcode 0x40
3611*4882a593Smuzhiyun ****************************************************************************/
3612*4882a593Smuzhiyun static void
x86emuOp_inc_AX(u8 X86EMU_UNUSED (op1))3613*4882a593Smuzhiyun x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3614*4882a593Smuzhiyun {
3615*4882a593Smuzhiyun     START_OF_INSTR();
3616*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3617*4882a593Smuzhiyun         DECODE_PRINTF("INC\tEAX\n");
3618*4882a593Smuzhiyun     }
3619*4882a593Smuzhiyun     else {
3620*4882a593Smuzhiyun         DECODE_PRINTF("INC\tAX\n");
3621*4882a593Smuzhiyun     }
3622*4882a593Smuzhiyun     TRACE_AND_STEP();
3623*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3624*4882a593Smuzhiyun         M.x86.R_EAX = inc_long(M.x86.R_EAX);
3625*4882a593Smuzhiyun     }
3626*4882a593Smuzhiyun     else {
3627*4882a593Smuzhiyun         M.x86.R_AX = inc_word(M.x86.R_AX);
3628*4882a593Smuzhiyun     }
3629*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3630*4882a593Smuzhiyun     END_OF_INSTR();
3631*4882a593Smuzhiyun }
3632*4882a593Smuzhiyun 
3633*4882a593Smuzhiyun /****************************************************************************
3634*4882a593Smuzhiyun REMARKS:
3635*4882a593Smuzhiyun Handles opcode 0x41
3636*4882a593Smuzhiyun ****************************************************************************/
3637*4882a593Smuzhiyun static void
x86emuOp_inc_CX(u8 X86EMU_UNUSED (op1))3638*4882a593Smuzhiyun x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3639*4882a593Smuzhiyun {
3640*4882a593Smuzhiyun     START_OF_INSTR();
3641*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3642*4882a593Smuzhiyun         DECODE_PRINTF("INC\tECX\n");
3643*4882a593Smuzhiyun     }
3644*4882a593Smuzhiyun     else {
3645*4882a593Smuzhiyun         DECODE_PRINTF("INC\tCX\n");
3646*4882a593Smuzhiyun     }
3647*4882a593Smuzhiyun     TRACE_AND_STEP();
3648*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3649*4882a593Smuzhiyun         M.x86.R_ECX = inc_long(M.x86.R_ECX);
3650*4882a593Smuzhiyun     }
3651*4882a593Smuzhiyun     else {
3652*4882a593Smuzhiyun         M.x86.R_CX = inc_word(M.x86.R_CX);
3653*4882a593Smuzhiyun     }
3654*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3655*4882a593Smuzhiyun     END_OF_INSTR();
3656*4882a593Smuzhiyun }
3657*4882a593Smuzhiyun 
3658*4882a593Smuzhiyun /****************************************************************************
3659*4882a593Smuzhiyun REMARKS:
3660*4882a593Smuzhiyun Handles opcode 0x42
3661*4882a593Smuzhiyun ****************************************************************************/
3662*4882a593Smuzhiyun static void
x86emuOp_inc_DX(u8 X86EMU_UNUSED (op1))3663*4882a593Smuzhiyun x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3664*4882a593Smuzhiyun {
3665*4882a593Smuzhiyun     START_OF_INSTR();
3666*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3667*4882a593Smuzhiyun         DECODE_PRINTF("INC\tEDX\n");
3668*4882a593Smuzhiyun     }
3669*4882a593Smuzhiyun     else {
3670*4882a593Smuzhiyun         DECODE_PRINTF("INC\tDX\n");
3671*4882a593Smuzhiyun     }
3672*4882a593Smuzhiyun     TRACE_AND_STEP();
3673*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3674*4882a593Smuzhiyun         M.x86.R_EDX = inc_long(M.x86.R_EDX);
3675*4882a593Smuzhiyun     }
3676*4882a593Smuzhiyun     else {
3677*4882a593Smuzhiyun         M.x86.R_DX = inc_word(M.x86.R_DX);
3678*4882a593Smuzhiyun     }
3679*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3680*4882a593Smuzhiyun     END_OF_INSTR();
3681*4882a593Smuzhiyun }
3682*4882a593Smuzhiyun 
3683*4882a593Smuzhiyun /****************************************************************************
3684*4882a593Smuzhiyun REMARKS:
3685*4882a593Smuzhiyun Handles opcode 0x43
3686*4882a593Smuzhiyun ****************************************************************************/
3687*4882a593Smuzhiyun static void
x86emuOp_inc_BX(u8 X86EMU_UNUSED (op1))3688*4882a593Smuzhiyun x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3689*4882a593Smuzhiyun {
3690*4882a593Smuzhiyun     START_OF_INSTR();
3691*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3692*4882a593Smuzhiyun         DECODE_PRINTF("INC\tEBX\n");
3693*4882a593Smuzhiyun     }
3694*4882a593Smuzhiyun     else {
3695*4882a593Smuzhiyun         DECODE_PRINTF("INC\tBX\n");
3696*4882a593Smuzhiyun     }
3697*4882a593Smuzhiyun     TRACE_AND_STEP();
3698*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3699*4882a593Smuzhiyun         M.x86.R_EBX = inc_long(M.x86.R_EBX);
3700*4882a593Smuzhiyun     }
3701*4882a593Smuzhiyun     else {
3702*4882a593Smuzhiyun         M.x86.R_BX = inc_word(M.x86.R_BX);
3703*4882a593Smuzhiyun     }
3704*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3705*4882a593Smuzhiyun     END_OF_INSTR();
3706*4882a593Smuzhiyun }
3707*4882a593Smuzhiyun 
3708*4882a593Smuzhiyun /****************************************************************************
3709*4882a593Smuzhiyun REMARKS:
3710*4882a593Smuzhiyun Handles opcode 0x44
3711*4882a593Smuzhiyun ****************************************************************************/
3712*4882a593Smuzhiyun static void
x86emuOp_inc_SP(u8 X86EMU_UNUSED (op1))3713*4882a593Smuzhiyun x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3714*4882a593Smuzhiyun {
3715*4882a593Smuzhiyun     START_OF_INSTR();
3716*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3717*4882a593Smuzhiyun         DECODE_PRINTF("INC\tESP\n");
3718*4882a593Smuzhiyun     }
3719*4882a593Smuzhiyun     else {
3720*4882a593Smuzhiyun         DECODE_PRINTF("INC\tSP\n");
3721*4882a593Smuzhiyun     }
3722*4882a593Smuzhiyun     TRACE_AND_STEP();
3723*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3724*4882a593Smuzhiyun         M.x86.R_ESP = inc_long(M.x86.R_ESP);
3725*4882a593Smuzhiyun     }
3726*4882a593Smuzhiyun     else {
3727*4882a593Smuzhiyun         M.x86.R_SP = inc_word(M.x86.R_SP);
3728*4882a593Smuzhiyun     }
3729*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3730*4882a593Smuzhiyun     END_OF_INSTR();
3731*4882a593Smuzhiyun }
3732*4882a593Smuzhiyun 
3733*4882a593Smuzhiyun /****************************************************************************
3734*4882a593Smuzhiyun REMARKS:
3735*4882a593Smuzhiyun Handles opcode 0x45
3736*4882a593Smuzhiyun ****************************************************************************/
3737*4882a593Smuzhiyun static void
x86emuOp_inc_BP(u8 X86EMU_UNUSED (op1))3738*4882a593Smuzhiyun x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3739*4882a593Smuzhiyun {
3740*4882a593Smuzhiyun     START_OF_INSTR();
3741*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3742*4882a593Smuzhiyun         DECODE_PRINTF("INC\tEBP\n");
3743*4882a593Smuzhiyun     }
3744*4882a593Smuzhiyun     else {
3745*4882a593Smuzhiyun         DECODE_PRINTF("INC\tBP\n");
3746*4882a593Smuzhiyun     }
3747*4882a593Smuzhiyun     TRACE_AND_STEP();
3748*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3749*4882a593Smuzhiyun         M.x86.R_EBP = inc_long(M.x86.R_EBP);
3750*4882a593Smuzhiyun     }
3751*4882a593Smuzhiyun     else {
3752*4882a593Smuzhiyun         M.x86.R_BP = inc_word(M.x86.R_BP);
3753*4882a593Smuzhiyun     }
3754*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3755*4882a593Smuzhiyun     END_OF_INSTR();
3756*4882a593Smuzhiyun }
3757*4882a593Smuzhiyun 
3758*4882a593Smuzhiyun /****************************************************************************
3759*4882a593Smuzhiyun REMARKS:
3760*4882a593Smuzhiyun Handles opcode 0x46
3761*4882a593Smuzhiyun ****************************************************************************/
3762*4882a593Smuzhiyun static void
x86emuOp_inc_SI(u8 X86EMU_UNUSED (op1))3763*4882a593Smuzhiyun x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3764*4882a593Smuzhiyun {
3765*4882a593Smuzhiyun     START_OF_INSTR();
3766*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3767*4882a593Smuzhiyun         DECODE_PRINTF("INC\tESI\n");
3768*4882a593Smuzhiyun     }
3769*4882a593Smuzhiyun     else {
3770*4882a593Smuzhiyun         DECODE_PRINTF("INC\tSI\n");
3771*4882a593Smuzhiyun     }
3772*4882a593Smuzhiyun     TRACE_AND_STEP();
3773*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3774*4882a593Smuzhiyun         M.x86.R_ESI = inc_long(M.x86.R_ESI);
3775*4882a593Smuzhiyun     }
3776*4882a593Smuzhiyun     else {
3777*4882a593Smuzhiyun         M.x86.R_SI = inc_word(M.x86.R_SI);
3778*4882a593Smuzhiyun     }
3779*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3780*4882a593Smuzhiyun     END_OF_INSTR();
3781*4882a593Smuzhiyun }
3782*4882a593Smuzhiyun 
3783*4882a593Smuzhiyun /****************************************************************************
3784*4882a593Smuzhiyun REMARKS:
3785*4882a593Smuzhiyun Handles opcode 0x47
3786*4882a593Smuzhiyun ****************************************************************************/
3787*4882a593Smuzhiyun static void
x86emuOp_inc_DI(u8 X86EMU_UNUSED (op1))3788*4882a593Smuzhiyun x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3789*4882a593Smuzhiyun {
3790*4882a593Smuzhiyun     START_OF_INSTR();
3791*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3792*4882a593Smuzhiyun         DECODE_PRINTF("INC\tEDI\n");
3793*4882a593Smuzhiyun     }
3794*4882a593Smuzhiyun     else {
3795*4882a593Smuzhiyun         DECODE_PRINTF("INC\tDI\n");
3796*4882a593Smuzhiyun     }
3797*4882a593Smuzhiyun     TRACE_AND_STEP();
3798*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3799*4882a593Smuzhiyun         M.x86.R_EDI = inc_long(M.x86.R_EDI);
3800*4882a593Smuzhiyun     }
3801*4882a593Smuzhiyun     else {
3802*4882a593Smuzhiyun         M.x86.R_DI = inc_word(M.x86.R_DI);
3803*4882a593Smuzhiyun     }
3804*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3805*4882a593Smuzhiyun     END_OF_INSTR();
3806*4882a593Smuzhiyun }
3807*4882a593Smuzhiyun 
3808*4882a593Smuzhiyun /****************************************************************************
3809*4882a593Smuzhiyun REMARKS:
3810*4882a593Smuzhiyun Handles opcode 0x48
3811*4882a593Smuzhiyun ****************************************************************************/
3812*4882a593Smuzhiyun static void
x86emuOp_dec_AX(u8 X86EMU_UNUSED (op1))3813*4882a593Smuzhiyun x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3814*4882a593Smuzhiyun {
3815*4882a593Smuzhiyun     START_OF_INSTR();
3816*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3817*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tEAX\n");
3818*4882a593Smuzhiyun     }
3819*4882a593Smuzhiyun     else {
3820*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tAX\n");
3821*4882a593Smuzhiyun     }
3822*4882a593Smuzhiyun     TRACE_AND_STEP();
3823*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3824*4882a593Smuzhiyun         M.x86.R_EAX = dec_long(M.x86.R_EAX);
3825*4882a593Smuzhiyun     }
3826*4882a593Smuzhiyun     else {
3827*4882a593Smuzhiyun         M.x86.R_AX = dec_word(M.x86.R_AX);
3828*4882a593Smuzhiyun     }
3829*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3830*4882a593Smuzhiyun     END_OF_INSTR();
3831*4882a593Smuzhiyun }
3832*4882a593Smuzhiyun 
3833*4882a593Smuzhiyun /****************************************************************************
3834*4882a593Smuzhiyun REMARKS:
3835*4882a593Smuzhiyun Handles opcode 0x49
3836*4882a593Smuzhiyun ****************************************************************************/
3837*4882a593Smuzhiyun static void
x86emuOp_dec_CX(u8 X86EMU_UNUSED (op1))3838*4882a593Smuzhiyun x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3839*4882a593Smuzhiyun {
3840*4882a593Smuzhiyun     START_OF_INSTR();
3841*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3842*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tECX\n");
3843*4882a593Smuzhiyun     }
3844*4882a593Smuzhiyun     else {
3845*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tCX\n");
3846*4882a593Smuzhiyun     }
3847*4882a593Smuzhiyun     TRACE_AND_STEP();
3848*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3849*4882a593Smuzhiyun         M.x86.R_ECX = dec_long(M.x86.R_ECX);
3850*4882a593Smuzhiyun     }
3851*4882a593Smuzhiyun     else {
3852*4882a593Smuzhiyun         M.x86.R_CX = dec_word(M.x86.R_CX);
3853*4882a593Smuzhiyun     }
3854*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3855*4882a593Smuzhiyun     END_OF_INSTR();
3856*4882a593Smuzhiyun }
3857*4882a593Smuzhiyun 
3858*4882a593Smuzhiyun /****************************************************************************
3859*4882a593Smuzhiyun REMARKS:
3860*4882a593Smuzhiyun Handles opcode 0x4a
3861*4882a593Smuzhiyun ****************************************************************************/
3862*4882a593Smuzhiyun static void
x86emuOp_dec_DX(u8 X86EMU_UNUSED (op1))3863*4882a593Smuzhiyun x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3864*4882a593Smuzhiyun {
3865*4882a593Smuzhiyun     START_OF_INSTR();
3866*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3867*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tEDX\n");
3868*4882a593Smuzhiyun     }
3869*4882a593Smuzhiyun     else {
3870*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tDX\n");
3871*4882a593Smuzhiyun     }
3872*4882a593Smuzhiyun     TRACE_AND_STEP();
3873*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3874*4882a593Smuzhiyun         M.x86.R_EDX = dec_long(M.x86.R_EDX);
3875*4882a593Smuzhiyun     }
3876*4882a593Smuzhiyun     else {
3877*4882a593Smuzhiyun         M.x86.R_DX = dec_word(M.x86.R_DX);
3878*4882a593Smuzhiyun     }
3879*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3880*4882a593Smuzhiyun     END_OF_INSTR();
3881*4882a593Smuzhiyun }
3882*4882a593Smuzhiyun 
3883*4882a593Smuzhiyun /****************************************************************************
3884*4882a593Smuzhiyun REMARKS:
3885*4882a593Smuzhiyun Handles opcode 0x4b
3886*4882a593Smuzhiyun ****************************************************************************/
3887*4882a593Smuzhiyun static void
x86emuOp_dec_BX(u8 X86EMU_UNUSED (op1))3888*4882a593Smuzhiyun x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3889*4882a593Smuzhiyun {
3890*4882a593Smuzhiyun     START_OF_INSTR();
3891*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3892*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tEBX\n");
3893*4882a593Smuzhiyun     }
3894*4882a593Smuzhiyun     else {
3895*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tBX\n");
3896*4882a593Smuzhiyun     }
3897*4882a593Smuzhiyun     TRACE_AND_STEP();
3898*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3899*4882a593Smuzhiyun         M.x86.R_EBX = dec_long(M.x86.R_EBX);
3900*4882a593Smuzhiyun     }
3901*4882a593Smuzhiyun     else {
3902*4882a593Smuzhiyun         M.x86.R_BX = dec_word(M.x86.R_BX);
3903*4882a593Smuzhiyun     }
3904*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3905*4882a593Smuzhiyun     END_OF_INSTR();
3906*4882a593Smuzhiyun }
3907*4882a593Smuzhiyun 
3908*4882a593Smuzhiyun /****************************************************************************
3909*4882a593Smuzhiyun REMARKS:
3910*4882a593Smuzhiyun Handles opcode 0x4c
3911*4882a593Smuzhiyun ****************************************************************************/
3912*4882a593Smuzhiyun static void
x86emuOp_dec_SP(u8 X86EMU_UNUSED (op1))3913*4882a593Smuzhiyun x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3914*4882a593Smuzhiyun {
3915*4882a593Smuzhiyun     START_OF_INSTR();
3916*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3917*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tESP\n");
3918*4882a593Smuzhiyun     }
3919*4882a593Smuzhiyun     else {
3920*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tSP\n");
3921*4882a593Smuzhiyun     }
3922*4882a593Smuzhiyun     TRACE_AND_STEP();
3923*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3924*4882a593Smuzhiyun         M.x86.R_ESP = dec_long(M.x86.R_ESP);
3925*4882a593Smuzhiyun     }
3926*4882a593Smuzhiyun     else {
3927*4882a593Smuzhiyun         M.x86.R_SP = dec_word(M.x86.R_SP);
3928*4882a593Smuzhiyun     }
3929*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3930*4882a593Smuzhiyun     END_OF_INSTR();
3931*4882a593Smuzhiyun }
3932*4882a593Smuzhiyun 
3933*4882a593Smuzhiyun /****************************************************************************
3934*4882a593Smuzhiyun REMARKS:
3935*4882a593Smuzhiyun Handles opcode 0x4d
3936*4882a593Smuzhiyun ****************************************************************************/
3937*4882a593Smuzhiyun static void
x86emuOp_dec_BP(u8 X86EMU_UNUSED (op1))3938*4882a593Smuzhiyun x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3939*4882a593Smuzhiyun {
3940*4882a593Smuzhiyun     START_OF_INSTR();
3941*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3942*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tEBP\n");
3943*4882a593Smuzhiyun     }
3944*4882a593Smuzhiyun     else {
3945*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tBP\n");
3946*4882a593Smuzhiyun     }
3947*4882a593Smuzhiyun     TRACE_AND_STEP();
3948*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3949*4882a593Smuzhiyun         M.x86.R_EBP = dec_long(M.x86.R_EBP);
3950*4882a593Smuzhiyun     }
3951*4882a593Smuzhiyun     else {
3952*4882a593Smuzhiyun         M.x86.R_BP = dec_word(M.x86.R_BP);
3953*4882a593Smuzhiyun     }
3954*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3955*4882a593Smuzhiyun     END_OF_INSTR();
3956*4882a593Smuzhiyun }
3957*4882a593Smuzhiyun 
3958*4882a593Smuzhiyun /****************************************************************************
3959*4882a593Smuzhiyun REMARKS:
3960*4882a593Smuzhiyun Handles opcode 0x4e
3961*4882a593Smuzhiyun ****************************************************************************/
3962*4882a593Smuzhiyun static void
x86emuOp_dec_SI(u8 X86EMU_UNUSED (op1))3963*4882a593Smuzhiyun x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3964*4882a593Smuzhiyun {
3965*4882a593Smuzhiyun     START_OF_INSTR();
3966*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3967*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tESI\n");
3968*4882a593Smuzhiyun     }
3969*4882a593Smuzhiyun     else {
3970*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tSI\n");
3971*4882a593Smuzhiyun     }
3972*4882a593Smuzhiyun     TRACE_AND_STEP();
3973*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3974*4882a593Smuzhiyun         M.x86.R_ESI = dec_long(M.x86.R_ESI);
3975*4882a593Smuzhiyun     }
3976*4882a593Smuzhiyun     else {
3977*4882a593Smuzhiyun         M.x86.R_SI = dec_word(M.x86.R_SI);
3978*4882a593Smuzhiyun     }
3979*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
3980*4882a593Smuzhiyun     END_OF_INSTR();
3981*4882a593Smuzhiyun }
3982*4882a593Smuzhiyun 
3983*4882a593Smuzhiyun /****************************************************************************
3984*4882a593Smuzhiyun REMARKS:
3985*4882a593Smuzhiyun Handles opcode 0x4f
3986*4882a593Smuzhiyun ****************************************************************************/
3987*4882a593Smuzhiyun static void
x86emuOp_dec_DI(u8 X86EMU_UNUSED (op1))3988*4882a593Smuzhiyun x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3989*4882a593Smuzhiyun {
3990*4882a593Smuzhiyun     START_OF_INSTR();
3991*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3992*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tEDI\n");
3993*4882a593Smuzhiyun     }
3994*4882a593Smuzhiyun     else {
3995*4882a593Smuzhiyun         DECODE_PRINTF("DEC\tDI\n");
3996*4882a593Smuzhiyun     }
3997*4882a593Smuzhiyun     TRACE_AND_STEP();
3998*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3999*4882a593Smuzhiyun         M.x86.R_EDI = dec_long(M.x86.R_EDI);
4000*4882a593Smuzhiyun     }
4001*4882a593Smuzhiyun     else {
4002*4882a593Smuzhiyun         M.x86.R_DI = dec_word(M.x86.R_DI);
4003*4882a593Smuzhiyun     }
4004*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4005*4882a593Smuzhiyun     END_OF_INSTR();
4006*4882a593Smuzhiyun }
4007*4882a593Smuzhiyun 
4008*4882a593Smuzhiyun /****************************************************************************
4009*4882a593Smuzhiyun REMARKS:
4010*4882a593Smuzhiyun Handles opcode 0x50
4011*4882a593Smuzhiyun ****************************************************************************/
4012*4882a593Smuzhiyun static void
x86emuOp_push_AX(u8 X86EMU_UNUSED (op1))4013*4882a593Smuzhiyun x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
4014*4882a593Smuzhiyun {
4015*4882a593Smuzhiyun     START_OF_INSTR();
4016*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4017*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tEAX\n");
4018*4882a593Smuzhiyun     }
4019*4882a593Smuzhiyun     else {
4020*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tAX\n");
4021*4882a593Smuzhiyun     }
4022*4882a593Smuzhiyun     TRACE_AND_STEP();
4023*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4024*4882a593Smuzhiyun         push_long(M.x86.R_EAX);
4025*4882a593Smuzhiyun     }
4026*4882a593Smuzhiyun     else {
4027*4882a593Smuzhiyun         push_word(M.x86.R_AX);
4028*4882a593Smuzhiyun     }
4029*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4030*4882a593Smuzhiyun     END_OF_INSTR();
4031*4882a593Smuzhiyun }
4032*4882a593Smuzhiyun 
4033*4882a593Smuzhiyun /****************************************************************************
4034*4882a593Smuzhiyun REMARKS:
4035*4882a593Smuzhiyun Handles opcode 0x51
4036*4882a593Smuzhiyun ****************************************************************************/
4037*4882a593Smuzhiyun static void
x86emuOp_push_CX(u8 X86EMU_UNUSED (op1))4038*4882a593Smuzhiyun x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
4039*4882a593Smuzhiyun {
4040*4882a593Smuzhiyun     START_OF_INSTR();
4041*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4042*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tECX\n");
4043*4882a593Smuzhiyun     }
4044*4882a593Smuzhiyun     else {
4045*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tCX\n");
4046*4882a593Smuzhiyun     }
4047*4882a593Smuzhiyun     TRACE_AND_STEP();
4048*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4049*4882a593Smuzhiyun         push_long(M.x86.R_ECX);
4050*4882a593Smuzhiyun     }
4051*4882a593Smuzhiyun     else {
4052*4882a593Smuzhiyun         push_word(M.x86.R_CX);
4053*4882a593Smuzhiyun     }
4054*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4055*4882a593Smuzhiyun     END_OF_INSTR();
4056*4882a593Smuzhiyun }
4057*4882a593Smuzhiyun 
4058*4882a593Smuzhiyun /****************************************************************************
4059*4882a593Smuzhiyun REMARKS:
4060*4882a593Smuzhiyun Handles opcode 0x52
4061*4882a593Smuzhiyun ****************************************************************************/
4062*4882a593Smuzhiyun static void
x86emuOp_push_DX(u8 X86EMU_UNUSED (op1))4063*4882a593Smuzhiyun x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
4064*4882a593Smuzhiyun {
4065*4882a593Smuzhiyun     START_OF_INSTR();
4066*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4067*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tEDX\n");
4068*4882a593Smuzhiyun     }
4069*4882a593Smuzhiyun     else {
4070*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tDX\n");
4071*4882a593Smuzhiyun     }
4072*4882a593Smuzhiyun     TRACE_AND_STEP();
4073*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4074*4882a593Smuzhiyun         push_long(M.x86.R_EDX);
4075*4882a593Smuzhiyun     }
4076*4882a593Smuzhiyun     else {
4077*4882a593Smuzhiyun         push_word(M.x86.R_DX);
4078*4882a593Smuzhiyun     }
4079*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4080*4882a593Smuzhiyun     END_OF_INSTR();
4081*4882a593Smuzhiyun }
4082*4882a593Smuzhiyun 
4083*4882a593Smuzhiyun /****************************************************************************
4084*4882a593Smuzhiyun REMARKS:
4085*4882a593Smuzhiyun Handles opcode 0x53
4086*4882a593Smuzhiyun ****************************************************************************/
4087*4882a593Smuzhiyun static void
x86emuOp_push_BX(u8 X86EMU_UNUSED (op1))4088*4882a593Smuzhiyun x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
4089*4882a593Smuzhiyun {
4090*4882a593Smuzhiyun     START_OF_INSTR();
4091*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4092*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tEBX\n");
4093*4882a593Smuzhiyun     }
4094*4882a593Smuzhiyun     else {
4095*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tBX\n");
4096*4882a593Smuzhiyun     }
4097*4882a593Smuzhiyun     TRACE_AND_STEP();
4098*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4099*4882a593Smuzhiyun         push_long(M.x86.R_EBX);
4100*4882a593Smuzhiyun     }
4101*4882a593Smuzhiyun     else {
4102*4882a593Smuzhiyun         push_word(M.x86.R_BX);
4103*4882a593Smuzhiyun     }
4104*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4105*4882a593Smuzhiyun     END_OF_INSTR();
4106*4882a593Smuzhiyun }
4107*4882a593Smuzhiyun 
4108*4882a593Smuzhiyun /****************************************************************************
4109*4882a593Smuzhiyun REMARKS:
4110*4882a593Smuzhiyun Handles opcode 0x54
4111*4882a593Smuzhiyun ****************************************************************************/
4112*4882a593Smuzhiyun static void
x86emuOp_push_SP(u8 X86EMU_UNUSED (op1))4113*4882a593Smuzhiyun x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
4114*4882a593Smuzhiyun {
4115*4882a593Smuzhiyun     START_OF_INSTR();
4116*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4117*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tESP\n");
4118*4882a593Smuzhiyun     }
4119*4882a593Smuzhiyun     else {
4120*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tSP\n");
4121*4882a593Smuzhiyun     }
4122*4882a593Smuzhiyun     TRACE_AND_STEP();
4123*4882a593Smuzhiyun     /* Always push (E)SP, since we are emulating an i386 and above
4124*4882a593Smuzhiyun      * processor. This is necessary as some BIOS'es use this to check
4125*4882a593Smuzhiyun      * what type of processor is in the system.
4126*4882a593Smuzhiyun      */
4127*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4128*4882a593Smuzhiyun         push_long(M.x86.R_ESP);
4129*4882a593Smuzhiyun     }
4130*4882a593Smuzhiyun     else {
4131*4882a593Smuzhiyun         push_word((u16) (M.x86.R_SP));
4132*4882a593Smuzhiyun     }
4133*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4134*4882a593Smuzhiyun     END_OF_INSTR();
4135*4882a593Smuzhiyun }
4136*4882a593Smuzhiyun 
4137*4882a593Smuzhiyun /****************************************************************************
4138*4882a593Smuzhiyun REMARKS:
4139*4882a593Smuzhiyun Handles opcode 0x55
4140*4882a593Smuzhiyun ****************************************************************************/
4141*4882a593Smuzhiyun static void
x86emuOp_push_BP(u8 X86EMU_UNUSED (op1))4142*4882a593Smuzhiyun x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
4143*4882a593Smuzhiyun {
4144*4882a593Smuzhiyun     START_OF_INSTR();
4145*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4146*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tEBP\n");
4147*4882a593Smuzhiyun     }
4148*4882a593Smuzhiyun     else {
4149*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tBP\n");
4150*4882a593Smuzhiyun     }
4151*4882a593Smuzhiyun     TRACE_AND_STEP();
4152*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4153*4882a593Smuzhiyun         push_long(M.x86.R_EBP);
4154*4882a593Smuzhiyun     }
4155*4882a593Smuzhiyun     else {
4156*4882a593Smuzhiyun         push_word(M.x86.R_BP);
4157*4882a593Smuzhiyun     }
4158*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4159*4882a593Smuzhiyun     END_OF_INSTR();
4160*4882a593Smuzhiyun }
4161*4882a593Smuzhiyun 
4162*4882a593Smuzhiyun /****************************************************************************
4163*4882a593Smuzhiyun REMARKS:
4164*4882a593Smuzhiyun Handles opcode 0x56
4165*4882a593Smuzhiyun ****************************************************************************/
4166*4882a593Smuzhiyun static void
x86emuOp_push_SI(u8 X86EMU_UNUSED (op1))4167*4882a593Smuzhiyun x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
4168*4882a593Smuzhiyun {
4169*4882a593Smuzhiyun     START_OF_INSTR();
4170*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4171*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tESI\n");
4172*4882a593Smuzhiyun     }
4173*4882a593Smuzhiyun     else {
4174*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tSI\n");
4175*4882a593Smuzhiyun     }
4176*4882a593Smuzhiyun     TRACE_AND_STEP();
4177*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4178*4882a593Smuzhiyun         push_long(M.x86.R_ESI);
4179*4882a593Smuzhiyun     }
4180*4882a593Smuzhiyun     else {
4181*4882a593Smuzhiyun         push_word(M.x86.R_SI);
4182*4882a593Smuzhiyun     }
4183*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4184*4882a593Smuzhiyun     END_OF_INSTR();
4185*4882a593Smuzhiyun }
4186*4882a593Smuzhiyun 
4187*4882a593Smuzhiyun /****************************************************************************
4188*4882a593Smuzhiyun REMARKS:
4189*4882a593Smuzhiyun Handles opcode 0x57
4190*4882a593Smuzhiyun ****************************************************************************/
4191*4882a593Smuzhiyun static void
x86emuOp_push_DI(u8 X86EMU_UNUSED (op1))4192*4882a593Smuzhiyun x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
4193*4882a593Smuzhiyun {
4194*4882a593Smuzhiyun     START_OF_INSTR();
4195*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4196*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tEDI\n");
4197*4882a593Smuzhiyun     }
4198*4882a593Smuzhiyun     else {
4199*4882a593Smuzhiyun         DECODE_PRINTF("PUSH\tDI\n");
4200*4882a593Smuzhiyun     }
4201*4882a593Smuzhiyun     TRACE_AND_STEP();
4202*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4203*4882a593Smuzhiyun         push_long(M.x86.R_EDI);
4204*4882a593Smuzhiyun     }
4205*4882a593Smuzhiyun     else {
4206*4882a593Smuzhiyun         push_word(M.x86.R_DI);
4207*4882a593Smuzhiyun     }
4208*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4209*4882a593Smuzhiyun     END_OF_INSTR();
4210*4882a593Smuzhiyun }
4211*4882a593Smuzhiyun 
4212*4882a593Smuzhiyun /****************************************************************************
4213*4882a593Smuzhiyun REMARKS:
4214*4882a593Smuzhiyun Handles opcode 0x58
4215*4882a593Smuzhiyun ****************************************************************************/
4216*4882a593Smuzhiyun static void
x86emuOp_pop_AX(u8 X86EMU_UNUSED (op1))4217*4882a593Smuzhiyun x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4218*4882a593Smuzhiyun {
4219*4882a593Smuzhiyun     START_OF_INSTR();
4220*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4221*4882a593Smuzhiyun         DECODE_PRINTF("POP\tEAX\n");
4222*4882a593Smuzhiyun     }
4223*4882a593Smuzhiyun     else {
4224*4882a593Smuzhiyun         DECODE_PRINTF("POP\tAX\n");
4225*4882a593Smuzhiyun     }
4226*4882a593Smuzhiyun     TRACE_AND_STEP();
4227*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4228*4882a593Smuzhiyun         M.x86.R_EAX = pop_long();
4229*4882a593Smuzhiyun     }
4230*4882a593Smuzhiyun     else {
4231*4882a593Smuzhiyun         M.x86.R_AX = pop_word();
4232*4882a593Smuzhiyun     }
4233*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4234*4882a593Smuzhiyun     END_OF_INSTR();
4235*4882a593Smuzhiyun }
4236*4882a593Smuzhiyun 
4237*4882a593Smuzhiyun /****************************************************************************
4238*4882a593Smuzhiyun REMARKS:
4239*4882a593Smuzhiyun Handles opcode 0x59
4240*4882a593Smuzhiyun ****************************************************************************/
4241*4882a593Smuzhiyun static void
x86emuOp_pop_CX(u8 X86EMU_UNUSED (op1))4242*4882a593Smuzhiyun x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4243*4882a593Smuzhiyun {
4244*4882a593Smuzhiyun     START_OF_INSTR();
4245*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4246*4882a593Smuzhiyun         DECODE_PRINTF("POP\tECX\n");
4247*4882a593Smuzhiyun     }
4248*4882a593Smuzhiyun     else {
4249*4882a593Smuzhiyun         DECODE_PRINTF("POP\tCX\n");
4250*4882a593Smuzhiyun     }
4251*4882a593Smuzhiyun     TRACE_AND_STEP();
4252*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4253*4882a593Smuzhiyun         M.x86.R_ECX = pop_long();
4254*4882a593Smuzhiyun     }
4255*4882a593Smuzhiyun     else {
4256*4882a593Smuzhiyun         M.x86.R_CX = pop_word();
4257*4882a593Smuzhiyun     }
4258*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4259*4882a593Smuzhiyun     END_OF_INSTR();
4260*4882a593Smuzhiyun }
4261*4882a593Smuzhiyun 
4262*4882a593Smuzhiyun /****************************************************************************
4263*4882a593Smuzhiyun REMARKS:
4264*4882a593Smuzhiyun Handles opcode 0x5a
4265*4882a593Smuzhiyun ****************************************************************************/
4266*4882a593Smuzhiyun static void
x86emuOp_pop_DX(u8 X86EMU_UNUSED (op1))4267*4882a593Smuzhiyun x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4268*4882a593Smuzhiyun {
4269*4882a593Smuzhiyun     START_OF_INSTR();
4270*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4271*4882a593Smuzhiyun         DECODE_PRINTF("POP\tEDX\n");
4272*4882a593Smuzhiyun     }
4273*4882a593Smuzhiyun     else {
4274*4882a593Smuzhiyun         DECODE_PRINTF("POP\tDX\n");
4275*4882a593Smuzhiyun     }
4276*4882a593Smuzhiyun     TRACE_AND_STEP();
4277*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4278*4882a593Smuzhiyun         M.x86.R_EDX = pop_long();
4279*4882a593Smuzhiyun     }
4280*4882a593Smuzhiyun     else {
4281*4882a593Smuzhiyun         M.x86.R_DX = pop_word();
4282*4882a593Smuzhiyun     }
4283*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4284*4882a593Smuzhiyun     END_OF_INSTR();
4285*4882a593Smuzhiyun }
4286*4882a593Smuzhiyun 
4287*4882a593Smuzhiyun /****************************************************************************
4288*4882a593Smuzhiyun REMARKS:
4289*4882a593Smuzhiyun Handles opcode 0x5b
4290*4882a593Smuzhiyun ****************************************************************************/
4291*4882a593Smuzhiyun static void
x86emuOp_pop_BX(u8 X86EMU_UNUSED (op1))4292*4882a593Smuzhiyun x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4293*4882a593Smuzhiyun {
4294*4882a593Smuzhiyun     START_OF_INSTR();
4295*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4296*4882a593Smuzhiyun         DECODE_PRINTF("POP\tEBX\n");
4297*4882a593Smuzhiyun     }
4298*4882a593Smuzhiyun     else {
4299*4882a593Smuzhiyun         DECODE_PRINTF("POP\tBX\n");
4300*4882a593Smuzhiyun     }
4301*4882a593Smuzhiyun     TRACE_AND_STEP();
4302*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4303*4882a593Smuzhiyun         M.x86.R_EBX = pop_long();
4304*4882a593Smuzhiyun     }
4305*4882a593Smuzhiyun     else {
4306*4882a593Smuzhiyun         M.x86.R_BX = pop_word();
4307*4882a593Smuzhiyun     }
4308*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4309*4882a593Smuzhiyun     END_OF_INSTR();
4310*4882a593Smuzhiyun }
4311*4882a593Smuzhiyun 
4312*4882a593Smuzhiyun /****************************************************************************
4313*4882a593Smuzhiyun REMARKS:
4314*4882a593Smuzhiyun Handles opcode 0x5c
4315*4882a593Smuzhiyun ****************************************************************************/
4316*4882a593Smuzhiyun static void
x86emuOp_pop_SP(u8 X86EMU_UNUSED (op1))4317*4882a593Smuzhiyun x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4318*4882a593Smuzhiyun {
4319*4882a593Smuzhiyun     START_OF_INSTR();
4320*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4321*4882a593Smuzhiyun         DECODE_PRINTF("POP\tESP\n");
4322*4882a593Smuzhiyun     }
4323*4882a593Smuzhiyun     else {
4324*4882a593Smuzhiyun         DECODE_PRINTF("POP\tSP\n");
4325*4882a593Smuzhiyun     }
4326*4882a593Smuzhiyun     TRACE_AND_STEP();
4327*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4328*4882a593Smuzhiyun         M.x86.R_ESP = pop_long();
4329*4882a593Smuzhiyun     }
4330*4882a593Smuzhiyun     else {
4331*4882a593Smuzhiyun         M.x86.R_SP = pop_word();
4332*4882a593Smuzhiyun     }
4333*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4334*4882a593Smuzhiyun     END_OF_INSTR();
4335*4882a593Smuzhiyun }
4336*4882a593Smuzhiyun 
4337*4882a593Smuzhiyun /****************************************************************************
4338*4882a593Smuzhiyun REMARKS:
4339*4882a593Smuzhiyun Handles opcode 0x5d
4340*4882a593Smuzhiyun ****************************************************************************/
4341*4882a593Smuzhiyun static void
x86emuOp_pop_BP(u8 X86EMU_UNUSED (op1))4342*4882a593Smuzhiyun x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4343*4882a593Smuzhiyun {
4344*4882a593Smuzhiyun     START_OF_INSTR();
4345*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4346*4882a593Smuzhiyun         DECODE_PRINTF("POP\tEBP\n");
4347*4882a593Smuzhiyun     }
4348*4882a593Smuzhiyun     else {
4349*4882a593Smuzhiyun         DECODE_PRINTF("POP\tBP\n");
4350*4882a593Smuzhiyun     }
4351*4882a593Smuzhiyun     TRACE_AND_STEP();
4352*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4353*4882a593Smuzhiyun         M.x86.R_EBP = pop_long();
4354*4882a593Smuzhiyun     }
4355*4882a593Smuzhiyun     else {
4356*4882a593Smuzhiyun         M.x86.R_BP = pop_word();
4357*4882a593Smuzhiyun     }
4358*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4359*4882a593Smuzhiyun     END_OF_INSTR();
4360*4882a593Smuzhiyun }
4361*4882a593Smuzhiyun 
4362*4882a593Smuzhiyun /****************************************************************************
4363*4882a593Smuzhiyun REMARKS:
4364*4882a593Smuzhiyun Handles opcode 0x5e
4365*4882a593Smuzhiyun ****************************************************************************/
4366*4882a593Smuzhiyun static void
x86emuOp_pop_SI(u8 X86EMU_UNUSED (op1))4367*4882a593Smuzhiyun x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4368*4882a593Smuzhiyun {
4369*4882a593Smuzhiyun     START_OF_INSTR();
4370*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4371*4882a593Smuzhiyun         DECODE_PRINTF("POP\tESI\n");
4372*4882a593Smuzhiyun     }
4373*4882a593Smuzhiyun     else {
4374*4882a593Smuzhiyun         DECODE_PRINTF("POP\tSI\n");
4375*4882a593Smuzhiyun     }
4376*4882a593Smuzhiyun     TRACE_AND_STEP();
4377*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4378*4882a593Smuzhiyun         M.x86.R_ESI = pop_long();
4379*4882a593Smuzhiyun     }
4380*4882a593Smuzhiyun     else {
4381*4882a593Smuzhiyun         M.x86.R_SI = pop_word();
4382*4882a593Smuzhiyun     }
4383*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4384*4882a593Smuzhiyun     END_OF_INSTR();
4385*4882a593Smuzhiyun }
4386*4882a593Smuzhiyun 
4387*4882a593Smuzhiyun /****************************************************************************
4388*4882a593Smuzhiyun REMARKS:
4389*4882a593Smuzhiyun Handles opcode 0x5f
4390*4882a593Smuzhiyun ****************************************************************************/
4391*4882a593Smuzhiyun static void
x86emuOp_pop_DI(u8 X86EMU_UNUSED (op1))4392*4882a593Smuzhiyun x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4393*4882a593Smuzhiyun {
4394*4882a593Smuzhiyun     START_OF_INSTR();
4395*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4396*4882a593Smuzhiyun         DECODE_PRINTF("POP\tEDI\n");
4397*4882a593Smuzhiyun     }
4398*4882a593Smuzhiyun     else {
4399*4882a593Smuzhiyun         DECODE_PRINTF("POP\tDI\n");
4400*4882a593Smuzhiyun     }
4401*4882a593Smuzhiyun     TRACE_AND_STEP();
4402*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4403*4882a593Smuzhiyun         M.x86.R_EDI = pop_long();
4404*4882a593Smuzhiyun     }
4405*4882a593Smuzhiyun     else {
4406*4882a593Smuzhiyun         M.x86.R_DI = pop_word();
4407*4882a593Smuzhiyun     }
4408*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4409*4882a593Smuzhiyun     END_OF_INSTR();
4410*4882a593Smuzhiyun }
4411*4882a593Smuzhiyun 
4412*4882a593Smuzhiyun /****************************************************************************
4413*4882a593Smuzhiyun REMARKS:
4414*4882a593Smuzhiyun Handles opcode 0x60
4415*4882a593Smuzhiyun ****************************************************************************/
4416*4882a593Smuzhiyun static void
x86emuOp_push_all(u8 X86EMU_UNUSED (op1))4417*4882a593Smuzhiyun x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4418*4882a593Smuzhiyun {
4419*4882a593Smuzhiyun     START_OF_INSTR();
4420*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4421*4882a593Smuzhiyun         DECODE_PRINTF("PUSHAD\n");
4422*4882a593Smuzhiyun     }
4423*4882a593Smuzhiyun     else {
4424*4882a593Smuzhiyun         DECODE_PRINTF("PUSHA\n");
4425*4882a593Smuzhiyun     }
4426*4882a593Smuzhiyun     TRACE_AND_STEP();
4427*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4428*4882a593Smuzhiyun         u32 old_sp = M.x86.R_ESP;
4429*4882a593Smuzhiyun 
4430*4882a593Smuzhiyun         push_long(M.x86.R_EAX);
4431*4882a593Smuzhiyun         push_long(M.x86.R_ECX);
4432*4882a593Smuzhiyun         push_long(M.x86.R_EDX);
4433*4882a593Smuzhiyun         push_long(M.x86.R_EBX);
4434*4882a593Smuzhiyun         push_long(old_sp);
4435*4882a593Smuzhiyun         push_long(M.x86.R_EBP);
4436*4882a593Smuzhiyun         push_long(M.x86.R_ESI);
4437*4882a593Smuzhiyun         push_long(M.x86.R_EDI);
4438*4882a593Smuzhiyun     }
4439*4882a593Smuzhiyun     else {
4440*4882a593Smuzhiyun         u16 old_sp = M.x86.R_SP;
4441*4882a593Smuzhiyun 
4442*4882a593Smuzhiyun         push_word(M.x86.R_AX);
4443*4882a593Smuzhiyun         push_word(M.x86.R_CX);
4444*4882a593Smuzhiyun         push_word(M.x86.R_DX);
4445*4882a593Smuzhiyun         push_word(M.x86.R_BX);
4446*4882a593Smuzhiyun         push_word(old_sp);
4447*4882a593Smuzhiyun         push_word(M.x86.R_BP);
4448*4882a593Smuzhiyun         push_word(M.x86.R_SI);
4449*4882a593Smuzhiyun         push_word(M.x86.R_DI);
4450*4882a593Smuzhiyun     }
4451*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4452*4882a593Smuzhiyun     END_OF_INSTR();
4453*4882a593Smuzhiyun }
4454*4882a593Smuzhiyun 
4455*4882a593Smuzhiyun /****************************************************************************
4456*4882a593Smuzhiyun REMARKS:
4457*4882a593Smuzhiyun Handles opcode 0x61
4458*4882a593Smuzhiyun ****************************************************************************/
4459*4882a593Smuzhiyun static void
x86emuOp_pop_all(u8 X86EMU_UNUSED (op1))4460*4882a593Smuzhiyun x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4461*4882a593Smuzhiyun {
4462*4882a593Smuzhiyun     START_OF_INSTR();
4463*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4464*4882a593Smuzhiyun         DECODE_PRINTF("POPAD\n");
4465*4882a593Smuzhiyun     }
4466*4882a593Smuzhiyun     else {
4467*4882a593Smuzhiyun         DECODE_PRINTF("POPA\n");
4468*4882a593Smuzhiyun     }
4469*4882a593Smuzhiyun     TRACE_AND_STEP();
4470*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4471*4882a593Smuzhiyun         M.x86.R_EDI = pop_long();
4472*4882a593Smuzhiyun         M.x86.R_ESI = pop_long();
4473*4882a593Smuzhiyun         M.x86.R_EBP = pop_long();
4474*4882a593Smuzhiyun         M.x86.R_ESP += 4;       /* skip ESP */
4475*4882a593Smuzhiyun         M.x86.R_EBX = pop_long();
4476*4882a593Smuzhiyun         M.x86.R_EDX = pop_long();
4477*4882a593Smuzhiyun         M.x86.R_ECX = pop_long();
4478*4882a593Smuzhiyun         M.x86.R_EAX = pop_long();
4479*4882a593Smuzhiyun     }
4480*4882a593Smuzhiyun     else {
4481*4882a593Smuzhiyun         M.x86.R_DI = pop_word();
4482*4882a593Smuzhiyun         M.x86.R_SI = pop_word();
4483*4882a593Smuzhiyun         M.x86.R_BP = pop_word();
4484*4882a593Smuzhiyun         M.x86.R_SP += 2;        /* skip SP */
4485*4882a593Smuzhiyun         M.x86.R_BX = pop_word();
4486*4882a593Smuzhiyun         M.x86.R_DX = pop_word();
4487*4882a593Smuzhiyun         M.x86.R_CX = pop_word();
4488*4882a593Smuzhiyun         M.x86.R_AX = pop_word();
4489*4882a593Smuzhiyun     }
4490*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4491*4882a593Smuzhiyun     END_OF_INSTR();
4492*4882a593Smuzhiyun }
4493*4882a593Smuzhiyun 
4494*4882a593Smuzhiyun /*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
4495*4882a593Smuzhiyun /*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
4496*4882a593Smuzhiyun 
4497*4882a593Smuzhiyun /****************************************************************************
4498*4882a593Smuzhiyun REMARKS:
4499*4882a593Smuzhiyun Handles opcode 0x64
4500*4882a593Smuzhiyun ****************************************************************************/
4501*4882a593Smuzhiyun static void
x86emuOp_segovr_FS(u8 X86EMU_UNUSED (op1))4502*4882a593Smuzhiyun x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4503*4882a593Smuzhiyun {
4504*4882a593Smuzhiyun     START_OF_INSTR();
4505*4882a593Smuzhiyun     DECODE_PRINTF("FS:\n");
4506*4882a593Smuzhiyun     TRACE_AND_STEP();
4507*4882a593Smuzhiyun     M.x86.mode |= SYSMODE_SEGOVR_FS;
4508*4882a593Smuzhiyun     /*
4509*4882a593Smuzhiyun      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4510*4882a593Smuzhiyun      * opcode subroutines we do not want to do this.
4511*4882a593Smuzhiyun      */
4512*4882a593Smuzhiyun     END_OF_INSTR();
4513*4882a593Smuzhiyun }
4514*4882a593Smuzhiyun 
4515*4882a593Smuzhiyun /****************************************************************************
4516*4882a593Smuzhiyun REMARKS:
4517*4882a593Smuzhiyun Handles opcode 0x65
4518*4882a593Smuzhiyun ****************************************************************************/
4519*4882a593Smuzhiyun static void
x86emuOp_segovr_GS(u8 X86EMU_UNUSED (op1))4520*4882a593Smuzhiyun x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4521*4882a593Smuzhiyun {
4522*4882a593Smuzhiyun     START_OF_INSTR();
4523*4882a593Smuzhiyun     DECODE_PRINTF("GS:\n");
4524*4882a593Smuzhiyun     TRACE_AND_STEP();
4525*4882a593Smuzhiyun     M.x86.mode |= SYSMODE_SEGOVR_GS;
4526*4882a593Smuzhiyun     /*
4527*4882a593Smuzhiyun      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4528*4882a593Smuzhiyun      * opcode subroutines we do not want to do this.
4529*4882a593Smuzhiyun      */
4530*4882a593Smuzhiyun     END_OF_INSTR();
4531*4882a593Smuzhiyun }
4532*4882a593Smuzhiyun 
4533*4882a593Smuzhiyun /****************************************************************************
4534*4882a593Smuzhiyun REMARKS:
4535*4882a593Smuzhiyun Handles opcode 0x66 - prefix for 32-bit register
4536*4882a593Smuzhiyun ****************************************************************************/
4537*4882a593Smuzhiyun static void
x86emuOp_prefix_data(u8 X86EMU_UNUSED (op1))4538*4882a593Smuzhiyun x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4539*4882a593Smuzhiyun {
4540*4882a593Smuzhiyun     START_OF_INSTR();
4541*4882a593Smuzhiyun     DECODE_PRINTF("DATA:\n");
4542*4882a593Smuzhiyun     TRACE_AND_STEP();
4543*4882a593Smuzhiyun     M.x86.mode |= SYSMODE_PREFIX_DATA;
4544*4882a593Smuzhiyun     /* note no DECODE_CLEAR_SEGOVR here. */
4545*4882a593Smuzhiyun     END_OF_INSTR();
4546*4882a593Smuzhiyun }
4547*4882a593Smuzhiyun 
4548*4882a593Smuzhiyun /****************************************************************************
4549*4882a593Smuzhiyun REMARKS:
4550*4882a593Smuzhiyun Handles opcode 0x67 - prefix for 32-bit address
4551*4882a593Smuzhiyun ****************************************************************************/
4552*4882a593Smuzhiyun static void
x86emuOp_prefix_addr(u8 X86EMU_UNUSED (op1))4553*4882a593Smuzhiyun x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4554*4882a593Smuzhiyun {
4555*4882a593Smuzhiyun     START_OF_INSTR();
4556*4882a593Smuzhiyun     DECODE_PRINTF("ADDR:\n");
4557*4882a593Smuzhiyun     TRACE_AND_STEP();
4558*4882a593Smuzhiyun     M.x86.mode |= SYSMODE_PREFIX_ADDR;
4559*4882a593Smuzhiyun     /* note no DECODE_CLEAR_SEGOVR here. */
4560*4882a593Smuzhiyun     END_OF_INSTR();
4561*4882a593Smuzhiyun }
4562*4882a593Smuzhiyun 
4563*4882a593Smuzhiyun /****************************************************************************
4564*4882a593Smuzhiyun REMARKS:
4565*4882a593Smuzhiyun Handles opcode 0x68
4566*4882a593Smuzhiyun ****************************************************************************/
4567*4882a593Smuzhiyun static void
x86emuOp_push_word_IMM(u8 X86EMU_UNUSED (op1))4568*4882a593Smuzhiyun x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4569*4882a593Smuzhiyun {
4570*4882a593Smuzhiyun     u32 imm;
4571*4882a593Smuzhiyun 
4572*4882a593Smuzhiyun     START_OF_INSTR();
4573*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4574*4882a593Smuzhiyun         imm = fetch_long_imm();
4575*4882a593Smuzhiyun     }
4576*4882a593Smuzhiyun     else {
4577*4882a593Smuzhiyun         imm = fetch_word_imm();
4578*4882a593Smuzhiyun     }
4579*4882a593Smuzhiyun     DECODE_PRINTF2("PUSH\t%x\n", imm);
4580*4882a593Smuzhiyun     TRACE_AND_STEP();
4581*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4582*4882a593Smuzhiyun         push_long(imm);
4583*4882a593Smuzhiyun     }
4584*4882a593Smuzhiyun     else {
4585*4882a593Smuzhiyun         push_word((u16) imm);
4586*4882a593Smuzhiyun     }
4587*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4588*4882a593Smuzhiyun     END_OF_INSTR();
4589*4882a593Smuzhiyun }
4590*4882a593Smuzhiyun 
4591*4882a593Smuzhiyun /****************************************************************************
4592*4882a593Smuzhiyun REMARKS:
4593*4882a593Smuzhiyun Handles opcode 0x69
4594*4882a593Smuzhiyun ****************************************************************************/
4595*4882a593Smuzhiyun static void
x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED (op1))4596*4882a593Smuzhiyun x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4597*4882a593Smuzhiyun {
4598*4882a593Smuzhiyun     int mod, rl, rh;
4599*4882a593Smuzhiyun     uint srcoffset;
4600*4882a593Smuzhiyun 
4601*4882a593Smuzhiyun     START_OF_INSTR();
4602*4882a593Smuzhiyun     DECODE_PRINTF("IMUL\t");
4603*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
4604*4882a593Smuzhiyun     switch (mod) {
4605*4882a593Smuzhiyun     case 0:
4606*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4607*4882a593Smuzhiyun             u32 *destreg;
4608*4882a593Smuzhiyun             u32 srcval;
4609*4882a593Smuzhiyun             u32 res_lo, res_hi;
4610*4882a593Smuzhiyun             s32 imm;
4611*4882a593Smuzhiyun 
4612*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
4613*4882a593Smuzhiyun             DECODE_PRINTF(",");
4614*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
4615*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
4616*4882a593Smuzhiyun             imm = fetch_long_imm();
4617*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4618*4882a593Smuzhiyun             TRACE_AND_STEP();
4619*4882a593Smuzhiyun             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4620*4882a593Smuzhiyun             if (res_hi != 0) {
4621*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4622*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4623*4882a593Smuzhiyun             }
4624*4882a593Smuzhiyun             else {
4625*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4626*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4627*4882a593Smuzhiyun             }
4628*4882a593Smuzhiyun             *destreg = (u32) res_lo;
4629*4882a593Smuzhiyun         }
4630*4882a593Smuzhiyun         else {
4631*4882a593Smuzhiyun             u16 *destreg;
4632*4882a593Smuzhiyun             u16 srcval;
4633*4882a593Smuzhiyun             u32 res;
4634*4882a593Smuzhiyun             s16 imm;
4635*4882a593Smuzhiyun 
4636*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
4637*4882a593Smuzhiyun             DECODE_PRINTF(",");
4638*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
4639*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
4640*4882a593Smuzhiyun             imm = fetch_word_imm();
4641*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4642*4882a593Smuzhiyun             TRACE_AND_STEP();
4643*4882a593Smuzhiyun             res = (s16) srcval *(s16) imm;
4644*4882a593Smuzhiyun 
4645*4882a593Smuzhiyun             if (res > 0xFFFF) {
4646*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4647*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4648*4882a593Smuzhiyun             }
4649*4882a593Smuzhiyun             else {
4650*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4651*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4652*4882a593Smuzhiyun             }
4653*4882a593Smuzhiyun             *destreg = (u16) res;
4654*4882a593Smuzhiyun         }
4655*4882a593Smuzhiyun         break;
4656*4882a593Smuzhiyun     case 1:
4657*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4658*4882a593Smuzhiyun             u32 *destreg;
4659*4882a593Smuzhiyun             u32 srcval;
4660*4882a593Smuzhiyun             u32 res_lo, res_hi;
4661*4882a593Smuzhiyun             s32 imm;
4662*4882a593Smuzhiyun 
4663*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
4664*4882a593Smuzhiyun             DECODE_PRINTF(",");
4665*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
4666*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
4667*4882a593Smuzhiyun             imm = fetch_long_imm();
4668*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4669*4882a593Smuzhiyun             TRACE_AND_STEP();
4670*4882a593Smuzhiyun             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4671*4882a593Smuzhiyun             if (res_hi != 0) {
4672*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4673*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4674*4882a593Smuzhiyun             }
4675*4882a593Smuzhiyun             else {
4676*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4677*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4678*4882a593Smuzhiyun             }
4679*4882a593Smuzhiyun             *destreg = (u32) res_lo;
4680*4882a593Smuzhiyun         }
4681*4882a593Smuzhiyun         else {
4682*4882a593Smuzhiyun             u16 *destreg;
4683*4882a593Smuzhiyun             u16 srcval;
4684*4882a593Smuzhiyun             u32 res;
4685*4882a593Smuzhiyun             s16 imm;
4686*4882a593Smuzhiyun 
4687*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
4688*4882a593Smuzhiyun             DECODE_PRINTF(",");
4689*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
4690*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
4691*4882a593Smuzhiyun             imm = fetch_word_imm();
4692*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4693*4882a593Smuzhiyun             TRACE_AND_STEP();
4694*4882a593Smuzhiyun             res = (s16) srcval *(s16) imm;
4695*4882a593Smuzhiyun 
4696*4882a593Smuzhiyun             if (res > 0xFFFF) {
4697*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4698*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4699*4882a593Smuzhiyun             }
4700*4882a593Smuzhiyun             else {
4701*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4702*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4703*4882a593Smuzhiyun             }
4704*4882a593Smuzhiyun             *destreg = (u16) res;
4705*4882a593Smuzhiyun         }
4706*4882a593Smuzhiyun         break;
4707*4882a593Smuzhiyun     case 2:
4708*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4709*4882a593Smuzhiyun             u32 *destreg;
4710*4882a593Smuzhiyun             u32 srcval;
4711*4882a593Smuzhiyun             u32 res_lo, res_hi;
4712*4882a593Smuzhiyun             s32 imm;
4713*4882a593Smuzhiyun 
4714*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
4715*4882a593Smuzhiyun             DECODE_PRINTF(",");
4716*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
4717*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
4718*4882a593Smuzhiyun             imm = fetch_long_imm();
4719*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4720*4882a593Smuzhiyun             TRACE_AND_STEP();
4721*4882a593Smuzhiyun             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4722*4882a593Smuzhiyun             if (res_hi != 0) {
4723*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4724*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4725*4882a593Smuzhiyun             }
4726*4882a593Smuzhiyun             else {
4727*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4728*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4729*4882a593Smuzhiyun             }
4730*4882a593Smuzhiyun             *destreg = (u32) res_lo;
4731*4882a593Smuzhiyun         }
4732*4882a593Smuzhiyun         else {
4733*4882a593Smuzhiyun             u16 *destreg;
4734*4882a593Smuzhiyun             u16 srcval;
4735*4882a593Smuzhiyun             u32 res;
4736*4882a593Smuzhiyun             s16 imm;
4737*4882a593Smuzhiyun 
4738*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
4739*4882a593Smuzhiyun             DECODE_PRINTF(",");
4740*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
4741*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
4742*4882a593Smuzhiyun             imm = fetch_word_imm();
4743*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4744*4882a593Smuzhiyun             TRACE_AND_STEP();
4745*4882a593Smuzhiyun             res = (s16) srcval *(s16) imm;
4746*4882a593Smuzhiyun 
4747*4882a593Smuzhiyun             if (res > 0xFFFF) {
4748*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4749*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4750*4882a593Smuzhiyun             }
4751*4882a593Smuzhiyun             else {
4752*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4753*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4754*4882a593Smuzhiyun             }
4755*4882a593Smuzhiyun             *destreg = (u16) res;
4756*4882a593Smuzhiyun         }
4757*4882a593Smuzhiyun         break;
4758*4882a593Smuzhiyun     case 3:                    /* register to register */
4759*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4760*4882a593Smuzhiyun             u32 *destreg, *srcreg;
4761*4882a593Smuzhiyun             u32 res_lo, res_hi;
4762*4882a593Smuzhiyun             s32 imm;
4763*4882a593Smuzhiyun 
4764*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
4765*4882a593Smuzhiyun             DECODE_PRINTF(",");
4766*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
4767*4882a593Smuzhiyun             imm = fetch_long_imm();
4768*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4769*4882a593Smuzhiyun             TRACE_AND_STEP();
4770*4882a593Smuzhiyun             imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
4771*4882a593Smuzhiyun             if (res_hi != 0) {
4772*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4773*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4774*4882a593Smuzhiyun             }
4775*4882a593Smuzhiyun             else {
4776*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4777*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4778*4882a593Smuzhiyun             }
4779*4882a593Smuzhiyun             *destreg = (u32) res_lo;
4780*4882a593Smuzhiyun         }
4781*4882a593Smuzhiyun         else {
4782*4882a593Smuzhiyun             u16 *destreg, *srcreg;
4783*4882a593Smuzhiyun             u32 res;
4784*4882a593Smuzhiyun             s16 imm;
4785*4882a593Smuzhiyun 
4786*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
4787*4882a593Smuzhiyun             DECODE_PRINTF(",");
4788*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
4789*4882a593Smuzhiyun             imm = fetch_word_imm();
4790*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4791*4882a593Smuzhiyun             res = (s16) * srcreg * (s16) imm;
4792*4882a593Smuzhiyun             if (res > 0xFFFF) {
4793*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4794*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4795*4882a593Smuzhiyun             }
4796*4882a593Smuzhiyun             else {
4797*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4798*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4799*4882a593Smuzhiyun             }
4800*4882a593Smuzhiyun             *destreg = (u16) res;
4801*4882a593Smuzhiyun         }
4802*4882a593Smuzhiyun         break;
4803*4882a593Smuzhiyun     }
4804*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4805*4882a593Smuzhiyun     END_OF_INSTR();
4806*4882a593Smuzhiyun }
4807*4882a593Smuzhiyun 
4808*4882a593Smuzhiyun /****************************************************************************
4809*4882a593Smuzhiyun REMARKS:
4810*4882a593Smuzhiyun Handles opcode 0x6a
4811*4882a593Smuzhiyun ****************************************************************************/
4812*4882a593Smuzhiyun static void
x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED (op1))4813*4882a593Smuzhiyun x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4814*4882a593Smuzhiyun {
4815*4882a593Smuzhiyun     s16 imm;
4816*4882a593Smuzhiyun 
4817*4882a593Smuzhiyun     START_OF_INSTR();
4818*4882a593Smuzhiyun     imm = (s8) fetch_byte_imm();
4819*4882a593Smuzhiyun     DECODE_PRINTF2("PUSH\t%d\n", imm);
4820*4882a593Smuzhiyun     TRACE_AND_STEP();
4821*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4822*4882a593Smuzhiyun         push_long((s32) imm);
4823*4882a593Smuzhiyun     }
4824*4882a593Smuzhiyun     else {
4825*4882a593Smuzhiyun         push_word(imm);
4826*4882a593Smuzhiyun     }
4827*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
4828*4882a593Smuzhiyun     END_OF_INSTR();
4829*4882a593Smuzhiyun }
4830*4882a593Smuzhiyun 
4831*4882a593Smuzhiyun /****************************************************************************
4832*4882a593Smuzhiyun REMARKS:
4833*4882a593Smuzhiyun Handles opcode 0x6b
4834*4882a593Smuzhiyun ****************************************************************************/
4835*4882a593Smuzhiyun static void
x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED (op1))4836*4882a593Smuzhiyun x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4837*4882a593Smuzhiyun {
4838*4882a593Smuzhiyun     int mod, rl, rh;
4839*4882a593Smuzhiyun     uint srcoffset;
4840*4882a593Smuzhiyun     s8 imm;
4841*4882a593Smuzhiyun 
4842*4882a593Smuzhiyun     START_OF_INSTR();
4843*4882a593Smuzhiyun     DECODE_PRINTF("IMUL\t");
4844*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
4845*4882a593Smuzhiyun     switch (mod) {
4846*4882a593Smuzhiyun     case 0:
4847*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4848*4882a593Smuzhiyun             u32 *destreg;
4849*4882a593Smuzhiyun             u32 srcval;
4850*4882a593Smuzhiyun             u32 res_lo, res_hi;
4851*4882a593Smuzhiyun 
4852*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
4853*4882a593Smuzhiyun             DECODE_PRINTF(",");
4854*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
4855*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
4856*4882a593Smuzhiyun             imm = fetch_byte_imm();
4857*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4858*4882a593Smuzhiyun             TRACE_AND_STEP();
4859*4882a593Smuzhiyun             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4860*4882a593Smuzhiyun             if (res_hi != 0) {
4861*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4862*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4863*4882a593Smuzhiyun             }
4864*4882a593Smuzhiyun             else {
4865*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4866*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4867*4882a593Smuzhiyun             }
4868*4882a593Smuzhiyun             *destreg = (u32) res_lo;
4869*4882a593Smuzhiyun         }
4870*4882a593Smuzhiyun         else {
4871*4882a593Smuzhiyun             u16 *destreg;
4872*4882a593Smuzhiyun             u16 srcval;
4873*4882a593Smuzhiyun             u32 res;
4874*4882a593Smuzhiyun 
4875*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
4876*4882a593Smuzhiyun             DECODE_PRINTF(",");
4877*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
4878*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
4879*4882a593Smuzhiyun             imm = fetch_byte_imm();
4880*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4881*4882a593Smuzhiyun             TRACE_AND_STEP();
4882*4882a593Smuzhiyun             res = (s16) srcval *(s16) imm;
4883*4882a593Smuzhiyun 
4884*4882a593Smuzhiyun             if (res > 0xFFFF) {
4885*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4886*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4887*4882a593Smuzhiyun             }
4888*4882a593Smuzhiyun             else {
4889*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4890*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4891*4882a593Smuzhiyun             }
4892*4882a593Smuzhiyun             *destreg = (u16) res;
4893*4882a593Smuzhiyun         }
4894*4882a593Smuzhiyun         break;
4895*4882a593Smuzhiyun     case 1:
4896*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4897*4882a593Smuzhiyun             u32 *destreg;
4898*4882a593Smuzhiyun             u32 srcval;
4899*4882a593Smuzhiyun             u32 res_lo, res_hi;
4900*4882a593Smuzhiyun 
4901*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
4902*4882a593Smuzhiyun             DECODE_PRINTF(",");
4903*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
4904*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
4905*4882a593Smuzhiyun             imm = fetch_byte_imm();
4906*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4907*4882a593Smuzhiyun             TRACE_AND_STEP();
4908*4882a593Smuzhiyun             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4909*4882a593Smuzhiyun             if (res_hi != 0) {
4910*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4911*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4912*4882a593Smuzhiyun             }
4913*4882a593Smuzhiyun             else {
4914*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4915*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4916*4882a593Smuzhiyun             }
4917*4882a593Smuzhiyun             *destreg = (u32) res_lo;
4918*4882a593Smuzhiyun         }
4919*4882a593Smuzhiyun         else {
4920*4882a593Smuzhiyun             u16 *destreg;
4921*4882a593Smuzhiyun             u16 srcval;
4922*4882a593Smuzhiyun             u32 res;
4923*4882a593Smuzhiyun 
4924*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
4925*4882a593Smuzhiyun             DECODE_PRINTF(",");
4926*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
4927*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
4928*4882a593Smuzhiyun             imm = fetch_byte_imm();
4929*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4930*4882a593Smuzhiyun             TRACE_AND_STEP();
4931*4882a593Smuzhiyun             res = (s16) srcval *(s16) imm;
4932*4882a593Smuzhiyun 
4933*4882a593Smuzhiyun             if (res > 0xFFFF) {
4934*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4935*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4936*4882a593Smuzhiyun             }
4937*4882a593Smuzhiyun             else {
4938*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4939*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4940*4882a593Smuzhiyun             }
4941*4882a593Smuzhiyun             *destreg = (u16) res;
4942*4882a593Smuzhiyun         }
4943*4882a593Smuzhiyun         break;
4944*4882a593Smuzhiyun     case 2:
4945*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4946*4882a593Smuzhiyun             u32 *destreg;
4947*4882a593Smuzhiyun             u32 srcval;
4948*4882a593Smuzhiyun             u32 res_lo, res_hi;
4949*4882a593Smuzhiyun 
4950*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
4951*4882a593Smuzhiyun             DECODE_PRINTF(",");
4952*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
4953*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
4954*4882a593Smuzhiyun             imm = fetch_byte_imm();
4955*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4956*4882a593Smuzhiyun             TRACE_AND_STEP();
4957*4882a593Smuzhiyun             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4958*4882a593Smuzhiyun             if (res_hi != 0) {
4959*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4960*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4961*4882a593Smuzhiyun             }
4962*4882a593Smuzhiyun             else {
4963*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4964*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4965*4882a593Smuzhiyun             }
4966*4882a593Smuzhiyun             *destreg = (u32) res_lo;
4967*4882a593Smuzhiyun         }
4968*4882a593Smuzhiyun         else {
4969*4882a593Smuzhiyun             u16 *destreg;
4970*4882a593Smuzhiyun             u16 srcval;
4971*4882a593Smuzhiyun             u32 res;
4972*4882a593Smuzhiyun 
4973*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
4974*4882a593Smuzhiyun             DECODE_PRINTF(",");
4975*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
4976*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
4977*4882a593Smuzhiyun             imm = fetch_byte_imm();
4978*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
4979*4882a593Smuzhiyun             TRACE_AND_STEP();
4980*4882a593Smuzhiyun             res = (s16) srcval *(s16) imm;
4981*4882a593Smuzhiyun 
4982*4882a593Smuzhiyun             if (res > 0xFFFF) {
4983*4882a593Smuzhiyun                 SET_FLAG(F_CF);
4984*4882a593Smuzhiyun                 SET_FLAG(F_OF);
4985*4882a593Smuzhiyun             }
4986*4882a593Smuzhiyun             else {
4987*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
4988*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
4989*4882a593Smuzhiyun             }
4990*4882a593Smuzhiyun             *destreg = (u16) res;
4991*4882a593Smuzhiyun         }
4992*4882a593Smuzhiyun         break;
4993*4882a593Smuzhiyun     case 3:                    /* register to register */
4994*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4995*4882a593Smuzhiyun             u32 *destreg, *srcreg;
4996*4882a593Smuzhiyun             u32 res_lo, res_hi;
4997*4882a593Smuzhiyun 
4998*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
4999*4882a593Smuzhiyun             DECODE_PRINTF(",");
5000*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
5001*4882a593Smuzhiyun             imm = fetch_byte_imm();
5002*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
5003*4882a593Smuzhiyun             TRACE_AND_STEP();
5004*4882a593Smuzhiyun             imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
5005*4882a593Smuzhiyun             if (res_hi != 0) {
5006*4882a593Smuzhiyun                 SET_FLAG(F_CF);
5007*4882a593Smuzhiyun                 SET_FLAG(F_OF);
5008*4882a593Smuzhiyun             }
5009*4882a593Smuzhiyun             else {
5010*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
5011*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
5012*4882a593Smuzhiyun             }
5013*4882a593Smuzhiyun             *destreg = (u32) res_lo;
5014*4882a593Smuzhiyun         }
5015*4882a593Smuzhiyun         else {
5016*4882a593Smuzhiyun             u16 *destreg, *srcreg;
5017*4882a593Smuzhiyun             u32 res;
5018*4882a593Smuzhiyun 
5019*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
5020*4882a593Smuzhiyun             DECODE_PRINTF(",");
5021*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
5022*4882a593Smuzhiyun             imm = fetch_byte_imm();
5023*4882a593Smuzhiyun             DECODE_PRINTF2(",%d\n", (s32) imm);
5024*4882a593Smuzhiyun             res = (s16) * srcreg * (s16) imm;
5025*4882a593Smuzhiyun             if (res > 0xFFFF) {
5026*4882a593Smuzhiyun                 SET_FLAG(F_CF);
5027*4882a593Smuzhiyun                 SET_FLAG(F_OF);
5028*4882a593Smuzhiyun             }
5029*4882a593Smuzhiyun             else {
5030*4882a593Smuzhiyun                 CLEAR_FLAG(F_CF);
5031*4882a593Smuzhiyun                 CLEAR_FLAG(F_OF);
5032*4882a593Smuzhiyun             }
5033*4882a593Smuzhiyun             *destreg = (u16) res;
5034*4882a593Smuzhiyun         }
5035*4882a593Smuzhiyun         break;
5036*4882a593Smuzhiyun     }
5037*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5038*4882a593Smuzhiyun     END_OF_INSTR();
5039*4882a593Smuzhiyun }
5040*4882a593Smuzhiyun 
5041*4882a593Smuzhiyun /****************************************************************************
5042*4882a593Smuzhiyun REMARKS:
5043*4882a593Smuzhiyun Handles opcode 0x6c
5044*4882a593Smuzhiyun ****************************************************************************/
5045*4882a593Smuzhiyun static void
x86emuOp_ins_byte(u8 X86EMU_UNUSED (op1))5046*4882a593Smuzhiyun x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
5047*4882a593Smuzhiyun {
5048*4882a593Smuzhiyun     START_OF_INSTR();
5049*4882a593Smuzhiyun     DECODE_PRINTF("INSB\n");
5050*4882a593Smuzhiyun     ins(1);
5051*4882a593Smuzhiyun     TRACE_AND_STEP();
5052*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5053*4882a593Smuzhiyun     END_OF_INSTR();
5054*4882a593Smuzhiyun }
5055*4882a593Smuzhiyun 
5056*4882a593Smuzhiyun /****************************************************************************
5057*4882a593Smuzhiyun REMARKS:
5058*4882a593Smuzhiyun Handles opcode 0x6d
5059*4882a593Smuzhiyun ****************************************************************************/
5060*4882a593Smuzhiyun static void
x86emuOp_ins_word(u8 X86EMU_UNUSED (op1))5061*4882a593Smuzhiyun x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
5062*4882a593Smuzhiyun {
5063*4882a593Smuzhiyun     START_OF_INSTR();
5064*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5065*4882a593Smuzhiyun         DECODE_PRINTF("INSD\n");
5066*4882a593Smuzhiyun         ins(4);
5067*4882a593Smuzhiyun     }
5068*4882a593Smuzhiyun     else {
5069*4882a593Smuzhiyun         DECODE_PRINTF("INSW\n");
5070*4882a593Smuzhiyun         ins(2);
5071*4882a593Smuzhiyun     }
5072*4882a593Smuzhiyun     TRACE_AND_STEP();
5073*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5074*4882a593Smuzhiyun     END_OF_INSTR();
5075*4882a593Smuzhiyun }
5076*4882a593Smuzhiyun 
5077*4882a593Smuzhiyun /****************************************************************************
5078*4882a593Smuzhiyun REMARKS:
5079*4882a593Smuzhiyun Handles opcode 0x6e
5080*4882a593Smuzhiyun ****************************************************************************/
5081*4882a593Smuzhiyun static void
x86emuOp_outs_byte(u8 X86EMU_UNUSED (op1))5082*4882a593Smuzhiyun x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
5083*4882a593Smuzhiyun {
5084*4882a593Smuzhiyun     START_OF_INSTR();
5085*4882a593Smuzhiyun     DECODE_PRINTF("OUTSB\n");
5086*4882a593Smuzhiyun     outs(1);
5087*4882a593Smuzhiyun     TRACE_AND_STEP();
5088*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5089*4882a593Smuzhiyun     END_OF_INSTR();
5090*4882a593Smuzhiyun }
5091*4882a593Smuzhiyun 
5092*4882a593Smuzhiyun /****************************************************************************
5093*4882a593Smuzhiyun REMARKS:
5094*4882a593Smuzhiyun Handles opcode 0x6f
5095*4882a593Smuzhiyun ****************************************************************************/
5096*4882a593Smuzhiyun static void
x86emuOp_outs_word(u8 X86EMU_UNUSED (op1))5097*4882a593Smuzhiyun x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
5098*4882a593Smuzhiyun {
5099*4882a593Smuzhiyun     START_OF_INSTR();
5100*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5101*4882a593Smuzhiyun         DECODE_PRINTF("OUTSD\n");
5102*4882a593Smuzhiyun         outs(4);
5103*4882a593Smuzhiyun     }
5104*4882a593Smuzhiyun     else {
5105*4882a593Smuzhiyun         DECODE_PRINTF("OUTSW\n");
5106*4882a593Smuzhiyun         outs(2);
5107*4882a593Smuzhiyun     }
5108*4882a593Smuzhiyun     TRACE_AND_STEP();
5109*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5110*4882a593Smuzhiyun     END_OF_INSTR();
5111*4882a593Smuzhiyun }
5112*4882a593Smuzhiyun 
5113*4882a593Smuzhiyun /****************************************************************************
5114*4882a593Smuzhiyun REMARKS:
5115*4882a593Smuzhiyun Handles opcode 0x70
5116*4882a593Smuzhiyun ****************************************************************************/
5117*4882a593Smuzhiyun static void
x86emuOp_jump_near_O(u8 X86EMU_UNUSED (op1))5118*4882a593Smuzhiyun x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
5119*4882a593Smuzhiyun {
5120*4882a593Smuzhiyun     s8 offset;
5121*4882a593Smuzhiyun     u16 target;
5122*4882a593Smuzhiyun 
5123*4882a593Smuzhiyun     /* jump to byte offset if overflow flag is set */
5124*4882a593Smuzhiyun     START_OF_INSTR();
5125*4882a593Smuzhiyun     DECODE_PRINTF("JO\t");
5126*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5127*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5128*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5129*4882a593Smuzhiyun     TRACE_AND_STEP();
5130*4882a593Smuzhiyun     if (ACCESS_FLAG(F_OF))
5131*4882a593Smuzhiyun         M.x86.R_IP = target;
5132*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5133*4882a593Smuzhiyun     END_OF_INSTR();
5134*4882a593Smuzhiyun }
5135*4882a593Smuzhiyun 
5136*4882a593Smuzhiyun /****************************************************************************
5137*4882a593Smuzhiyun REMARKS:
5138*4882a593Smuzhiyun Handles opcode 0x71
5139*4882a593Smuzhiyun ****************************************************************************/
5140*4882a593Smuzhiyun static void
x86emuOp_jump_near_NO(u8 X86EMU_UNUSED (op1))5141*4882a593Smuzhiyun x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
5142*4882a593Smuzhiyun {
5143*4882a593Smuzhiyun     s8 offset;
5144*4882a593Smuzhiyun     u16 target;
5145*4882a593Smuzhiyun 
5146*4882a593Smuzhiyun     /* jump to byte offset if overflow is not set */
5147*4882a593Smuzhiyun     START_OF_INSTR();
5148*4882a593Smuzhiyun     DECODE_PRINTF("JNO\t");
5149*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5150*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5151*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5152*4882a593Smuzhiyun     TRACE_AND_STEP();
5153*4882a593Smuzhiyun     if (!ACCESS_FLAG(F_OF))
5154*4882a593Smuzhiyun         M.x86.R_IP = target;
5155*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5156*4882a593Smuzhiyun     END_OF_INSTR();
5157*4882a593Smuzhiyun }
5158*4882a593Smuzhiyun 
5159*4882a593Smuzhiyun /****************************************************************************
5160*4882a593Smuzhiyun REMARKS:
5161*4882a593Smuzhiyun Handles opcode 0x72
5162*4882a593Smuzhiyun ****************************************************************************/
5163*4882a593Smuzhiyun static void
x86emuOp_jump_near_B(u8 X86EMU_UNUSED (op1))5164*4882a593Smuzhiyun x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
5165*4882a593Smuzhiyun {
5166*4882a593Smuzhiyun     s8 offset;
5167*4882a593Smuzhiyun     u16 target;
5168*4882a593Smuzhiyun 
5169*4882a593Smuzhiyun     /* jump to byte offset if carry flag is set. */
5170*4882a593Smuzhiyun     START_OF_INSTR();
5171*4882a593Smuzhiyun     DECODE_PRINTF("JB\t");
5172*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5173*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5174*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5175*4882a593Smuzhiyun     TRACE_AND_STEP();
5176*4882a593Smuzhiyun     if (ACCESS_FLAG(F_CF))
5177*4882a593Smuzhiyun         M.x86.R_IP = target;
5178*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5179*4882a593Smuzhiyun     END_OF_INSTR();
5180*4882a593Smuzhiyun }
5181*4882a593Smuzhiyun 
5182*4882a593Smuzhiyun /****************************************************************************
5183*4882a593Smuzhiyun REMARKS:
5184*4882a593Smuzhiyun Handles opcode 0x73
5185*4882a593Smuzhiyun ****************************************************************************/
5186*4882a593Smuzhiyun static void
x86emuOp_jump_near_NB(u8 X86EMU_UNUSED (op1))5187*4882a593Smuzhiyun x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
5188*4882a593Smuzhiyun {
5189*4882a593Smuzhiyun     s8 offset;
5190*4882a593Smuzhiyun     u16 target;
5191*4882a593Smuzhiyun 
5192*4882a593Smuzhiyun     /* jump to byte offset if carry flag is clear. */
5193*4882a593Smuzhiyun     START_OF_INSTR();
5194*4882a593Smuzhiyun     DECODE_PRINTF("JNB\t");
5195*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5196*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5197*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5198*4882a593Smuzhiyun     TRACE_AND_STEP();
5199*4882a593Smuzhiyun     if (!ACCESS_FLAG(F_CF))
5200*4882a593Smuzhiyun         M.x86.R_IP = target;
5201*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5202*4882a593Smuzhiyun     END_OF_INSTR();
5203*4882a593Smuzhiyun }
5204*4882a593Smuzhiyun 
5205*4882a593Smuzhiyun /****************************************************************************
5206*4882a593Smuzhiyun REMARKS:
5207*4882a593Smuzhiyun Handles opcode 0x74
5208*4882a593Smuzhiyun ****************************************************************************/
5209*4882a593Smuzhiyun static void
x86emuOp_jump_near_Z(u8 X86EMU_UNUSED (op1))5210*4882a593Smuzhiyun x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
5211*4882a593Smuzhiyun {
5212*4882a593Smuzhiyun     s8 offset;
5213*4882a593Smuzhiyun     u16 target;
5214*4882a593Smuzhiyun 
5215*4882a593Smuzhiyun     /* jump to byte offset if zero flag is set. */
5216*4882a593Smuzhiyun     START_OF_INSTR();
5217*4882a593Smuzhiyun     DECODE_PRINTF("JZ\t");
5218*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5219*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5220*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5221*4882a593Smuzhiyun     TRACE_AND_STEP();
5222*4882a593Smuzhiyun     if (ACCESS_FLAG(F_ZF))
5223*4882a593Smuzhiyun         M.x86.R_IP = target;
5224*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5225*4882a593Smuzhiyun     END_OF_INSTR();
5226*4882a593Smuzhiyun }
5227*4882a593Smuzhiyun 
5228*4882a593Smuzhiyun /****************************************************************************
5229*4882a593Smuzhiyun REMARKS:
5230*4882a593Smuzhiyun Handles opcode 0x75
5231*4882a593Smuzhiyun ****************************************************************************/
5232*4882a593Smuzhiyun static void
x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED (op1))5233*4882a593Smuzhiyun x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
5234*4882a593Smuzhiyun {
5235*4882a593Smuzhiyun     s8 offset;
5236*4882a593Smuzhiyun     u16 target;
5237*4882a593Smuzhiyun 
5238*4882a593Smuzhiyun     /* jump to byte offset if zero flag is clear. */
5239*4882a593Smuzhiyun     START_OF_INSTR();
5240*4882a593Smuzhiyun     DECODE_PRINTF("JNZ\t");
5241*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5242*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5243*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5244*4882a593Smuzhiyun     TRACE_AND_STEP();
5245*4882a593Smuzhiyun     if (!ACCESS_FLAG(F_ZF))
5246*4882a593Smuzhiyun         M.x86.R_IP = target;
5247*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5248*4882a593Smuzhiyun     END_OF_INSTR();
5249*4882a593Smuzhiyun }
5250*4882a593Smuzhiyun 
5251*4882a593Smuzhiyun /****************************************************************************
5252*4882a593Smuzhiyun REMARKS:
5253*4882a593Smuzhiyun Handles opcode 0x76
5254*4882a593Smuzhiyun ****************************************************************************/
5255*4882a593Smuzhiyun static void
x86emuOp_jump_near_BE(u8 X86EMU_UNUSED (op1))5256*4882a593Smuzhiyun x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
5257*4882a593Smuzhiyun {
5258*4882a593Smuzhiyun     s8 offset;
5259*4882a593Smuzhiyun     u16 target;
5260*4882a593Smuzhiyun 
5261*4882a593Smuzhiyun     /* jump to byte offset if carry flag is set or if the zero
5262*4882a593Smuzhiyun        flag is set. */
5263*4882a593Smuzhiyun     START_OF_INSTR();
5264*4882a593Smuzhiyun     DECODE_PRINTF("JBE\t");
5265*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5266*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5267*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5268*4882a593Smuzhiyun     TRACE_AND_STEP();
5269*4882a593Smuzhiyun     if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
5270*4882a593Smuzhiyun         M.x86.R_IP = target;
5271*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5272*4882a593Smuzhiyun     END_OF_INSTR();
5273*4882a593Smuzhiyun }
5274*4882a593Smuzhiyun 
5275*4882a593Smuzhiyun /****************************************************************************
5276*4882a593Smuzhiyun REMARKS:
5277*4882a593Smuzhiyun Handles opcode 0x77
5278*4882a593Smuzhiyun ****************************************************************************/
5279*4882a593Smuzhiyun static void
x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED (op1))5280*4882a593Smuzhiyun x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
5281*4882a593Smuzhiyun {
5282*4882a593Smuzhiyun     s8 offset;
5283*4882a593Smuzhiyun     u16 target;
5284*4882a593Smuzhiyun 
5285*4882a593Smuzhiyun     /* jump to byte offset if carry flag is clear and if the zero
5286*4882a593Smuzhiyun        flag is clear */
5287*4882a593Smuzhiyun     START_OF_INSTR();
5288*4882a593Smuzhiyun     DECODE_PRINTF("JNBE\t");
5289*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5290*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5291*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5292*4882a593Smuzhiyun     TRACE_AND_STEP();
5293*4882a593Smuzhiyun     if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
5294*4882a593Smuzhiyun         M.x86.R_IP = target;
5295*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5296*4882a593Smuzhiyun     END_OF_INSTR();
5297*4882a593Smuzhiyun }
5298*4882a593Smuzhiyun 
5299*4882a593Smuzhiyun /****************************************************************************
5300*4882a593Smuzhiyun REMARKS:
5301*4882a593Smuzhiyun Handles opcode 0x78
5302*4882a593Smuzhiyun ****************************************************************************/
5303*4882a593Smuzhiyun static void
x86emuOp_jump_near_S(u8 X86EMU_UNUSED (op1))5304*4882a593Smuzhiyun x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5305*4882a593Smuzhiyun {
5306*4882a593Smuzhiyun     s8 offset;
5307*4882a593Smuzhiyun     u16 target;
5308*4882a593Smuzhiyun 
5309*4882a593Smuzhiyun     /* jump to byte offset if sign flag is set */
5310*4882a593Smuzhiyun     START_OF_INSTR();
5311*4882a593Smuzhiyun     DECODE_PRINTF("JS\t");
5312*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5313*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5314*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5315*4882a593Smuzhiyun     TRACE_AND_STEP();
5316*4882a593Smuzhiyun     if (ACCESS_FLAG(F_SF))
5317*4882a593Smuzhiyun         M.x86.R_IP = target;
5318*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5319*4882a593Smuzhiyun     END_OF_INSTR();
5320*4882a593Smuzhiyun }
5321*4882a593Smuzhiyun 
5322*4882a593Smuzhiyun /****************************************************************************
5323*4882a593Smuzhiyun REMARKS:
5324*4882a593Smuzhiyun Handles opcode 0x79
5325*4882a593Smuzhiyun ****************************************************************************/
5326*4882a593Smuzhiyun static void
x86emuOp_jump_near_NS(u8 X86EMU_UNUSED (op1))5327*4882a593Smuzhiyun x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5328*4882a593Smuzhiyun {
5329*4882a593Smuzhiyun     s8 offset;
5330*4882a593Smuzhiyun     u16 target;
5331*4882a593Smuzhiyun 
5332*4882a593Smuzhiyun     /* jump to byte offset if sign flag is clear */
5333*4882a593Smuzhiyun     START_OF_INSTR();
5334*4882a593Smuzhiyun     DECODE_PRINTF("JNS\t");
5335*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5336*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5337*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5338*4882a593Smuzhiyun     TRACE_AND_STEP();
5339*4882a593Smuzhiyun     if (!ACCESS_FLAG(F_SF))
5340*4882a593Smuzhiyun         M.x86.R_IP = target;
5341*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5342*4882a593Smuzhiyun     END_OF_INSTR();
5343*4882a593Smuzhiyun }
5344*4882a593Smuzhiyun 
5345*4882a593Smuzhiyun /****************************************************************************
5346*4882a593Smuzhiyun REMARKS:
5347*4882a593Smuzhiyun Handles opcode 0x7a
5348*4882a593Smuzhiyun ****************************************************************************/
5349*4882a593Smuzhiyun static void
x86emuOp_jump_near_P(u8 X86EMU_UNUSED (op1))5350*4882a593Smuzhiyun x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5351*4882a593Smuzhiyun {
5352*4882a593Smuzhiyun     s8 offset;
5353*4882a593Smuzhiyun     u16 target;
5354*4882a593Smuzhiyun 
5355*4882a593Smuzhiyun     /* jump to byte offset if parity flag is set (even parity) */
5356*4882a593Smuzhiyun     START_OF_INSTR();
5357*4882a593Smuzhiyun     DECODE_PRINTF("JP\t");
5358*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5359*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5360*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5361*4882a593Smuzhiyun     TRACE_AND_STEP();
5362*4882a593Smuzhiyun     if (ACCESS_FLAG(F_PF))
5363*4882a593Smuzhiyun         M.x86.R_IP = target;
5364*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5365*4882a593Smuzhiyun     END_OF_INSTR();
5366*4882a593Smuzhiyun }
5367*4882a593Smuzhiyun 
5368*4882a593Smuzhiyun /****************************************************************************
5369*4882a593Smuzhiyun REMARKS:
5370*4882a593Smuzhiyun Handles opcode 0x7b
5371*4882a593Smuzhiyun ****************************************************************************/
5372*4882a593Smuzhiyun static void
x86emuOp_jump_near_NP(u8 X86EMU_UNUSED (op1))5373*4882a593Smuzhiyun x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5374*4882a593Smuzhiyun {
5375*4882a593Smuzhiyun     s8 offset;
5376*4882a593Smuzhiyun     u16 target;
5377*4882a593Smuzhiyun 
5378*4882a593Smuzhiyun     /* jump to byte offset if parity flag is clear (odd parity) */
5379*4882a593Smuzhiyun     START_OF_INSTR();
5380*4882a593Smuzhiyun     DECODE_PRINTF("JNP\t");
5381*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5382*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5383*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5384*4882a593Smuzhiyun     TRACE_AND_STEP();
5385*4882a593Smuzhiyun     if (!ACCESS_FLAG(F_PF))
5386*4882a593Smuzhiyun         M.x86.R_IP = target;
5387*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5388*4882a593Smuzhiyun     END_OF_INSTR();
5389*4882a593Smuzhiyun }
5390*4882a593Smuzhiyun 
5391*4882a593Smuzhiyun /****************************************************************************
5392*4882a593Smuzhiyun REMARKS:
5393*4882a593Smuzhiyun Handles opcode 0x7c
5394*4882a593Smuzhiyun ****************************************************************************/
5395*4882a593Smuzhiyun static void
x86emuOp_jump_near_L(u8 X86EMU_UNUSED (op1))5396*4882a593Smuzhiyun x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5397*4882a593Smuzhiyun {
5398*4882a593Smuzhiyun     s8 offset;
5399*4882a593Smuzhiyun     u16 target;
5400*4882a593Smuzhiyun     int sf, of;
5401*4882a593Smuzhiyun 
5402*4882a593Smuzhiyun     /* jump to byte offset if sign flag not equal to overflow flag. */
5403*4882a593Smuzhiyun     START_OF_INSTR();
5404*4882a593Smuzhiyun     DECODE_PRINTF("JL\t");
5405*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5406*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5407*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5408*4882a593Smuzhiyun     TRACE_AND_STEP();
5409*4882a593Smuzhiyun     sf = ACCESS_FLAG(F_SF) != 0;
5410*4882a593Smuzhiyun     of = ACCESS_FLAG(F_OF) != 0;
5411*4882a593Smuzhiyun     if (sf ^ of)
5412*4882a593Smuzhiyun         M.x86.R_IP = target;
5413*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5414*4882a593Smuzhiyun     END_OF_INSTR();
5415*4882a593Smuzhiyun }
5416*4882a593Smuzhiyun 
5417*4882a593Smuzhiyun /****************************************************************************
5418*4882a593Smuzhiyun REMARKS:
5419*4882a593Smuzhiyun Handles opcode 0x7d
5420*4882a593Smuzhiyun ****************************************************************************/
5421*4882a593Smuzhiyun static void
x86emuOp_jump_near_NL(u8 X86EMU_UNUSED (op1))5422*4882a593Smuzhiyun x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5423*4882a593Smuzhiyun {
5424*4882a593Smuzhiyun     s8 offset;
5425*4882a593Smuzhiyun     u16 target;
5426*4882a593Smuzhiyun     int sf, of;
5427*4882a593Smuzhiyun 
5428*4882a593Smuzhiyun     /* jump to byte offset if sign flag not equal to overflow flag. */
5429*4882a593Smuzhiyun     START_OF_INSTR();
5430*4882a593Smuzhiyun     DECODE_PRINTF("JNL\t");
5431*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5432*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5433*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5434*4882a593Smuzhiyun     TRACE_AND_STEP();
5435*4882a593Smuzhiyun     sf = ACCESS_FLAG(F_SF) != 0;
5436*4882a593Smuzhiyun     of = ACCESS_FLAG(F_OF) != 0;
5437*4882a593Smuzhiyun     /* note: inverse of above, but using == instead of xor. */
5438*4882a593Smuzhiyun     if (sf == of)
5439*4882a593Smuzhiyun         M.x86.R_IP = target;
5440*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5441*4882a593Smuzhiyun     END_OF_INSTR();
5442*4882a593Smuzhiyun }
5443*4882a593Smuzhiyun 
5444*4882a593Smuzhiyun /****************************************************************************
5445*4882a593Smuzhiyun REMARKS:
5446*4882a593Smuzhiyun Handles opcode 0x7e
5447*4882a593Smuzhiyun ****************************************************************************/
5448*4882a593Smuzhiyun static void
x86emuOp_jump_near_LE(u8 X86EMU_UNUSED (op1))5449*4882a593Smuzhiyun x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5450*4882a593Smuzhiyun {
5451*4882a593Smuzhiyun     s8 offset;
5452*4882a593Smuzhiyun     u16 target;
5453*4882a593Smuzhiyun     int sf, of;
5454*4882a593Smuzhiyun 
5455*4882a593Smuzhiyun     /* jump to byte offset if sign flag not equal to overflow flag
5456*4882a593Smuzhiyun        or the zero flag is set */
5457*4882a593Smuzhiyun     START_OF_INSTR();
5458*4882a593Smuzhiyun     DECODE_PRINTF("JLE\t");
5459*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5460*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5461*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5462*4882a593Smuzhiyun     TRACE_AND_STEP();
5463*4882a593Smuzhiyun     sf = ACCESS_FLAG(F_SF) != 0;
5464*4882a593Smuzhiyun     of = ACCESS_FLAG(F_OF) != 0;
5465*4882a593Smuzhiyun     if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5466*4882a593Smuzhiyun         M.x86.R_IP = target;
5467*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5468*4882a593Smuzhiyun     END_OF_INSTR();
5469*4882a593Smuzhiyun }
5470*4882a593Smuzhiyun 
5471*4882a593Smuzhiyun /****************************************************************************
5472*4882a593Smuzhiyun REMARKS:
5473*4882a593Smuzhiyun Handles opcode 0x7f
5474*4882a593Smuzhiyun ****************************************************************************/
5475*4882a593Smuzhiyun static void
x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED (op1))5476*4882a593Smuzhiyun x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5477*4882a593Smuzhiyun {
5478*4882a593Smuzhiyun     s8 offset;
5479*4882a593Smuzhiyun     u16 target;
5480*4882a593Smuzhiyun     int sf, of;
5481*4882a593Smuzhiyun 
5482*4882a593Smuzhiyun     /* jump to byte offset if sign flag equal to overflow flag.
5483*4882a593Smuzhiyun        and the zero flag is clear */
5484*4882a593Smuzhiyun     START_OF_INSTR();
5485*4882a593Smuzhiyun     DECODE_PRINTF("JNLE\t");
5486*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
5487*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + (s16) offset);
5488*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
5489*4882a593Smuzhiyun     TRACE_AND_STEP();
5490*4882a593Smuzhiyun     sf = ACCESS_FLAG(F_SF) != 0;
5491*4882a593Smuzhiyun     of = ACCESS_FLAG(F_OF) != 0;
5492*4882a593Smuzhiyun     if ((sf == of) && !ACCESS_FLAG(F_ZF))
5493*4882a593Smuzhiyun         M.x86.R_IP = target;
5494*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5495*4882a593Smuzhiyun     END_OF_INSTR();
5496*4882a593Smuzhiyun }
5497*4882a593Smuzhiyun 
5498*4882a593Smuzhiyun static u8(*opc80_byte_operation[]) (u8 d, u8 s) = {
5499*4882a593Smuzhiyun     add_byte,                   /* 00 */
5500*4882a593Smuzhiyun         or_byte,                /* 01 */
5501*4882a593Smuzhiyun         adc_byte,               /* 02 */
5502*4882a593Smuzhiyun         sbb_byte,               /* 03 */
5503*4882a593Smuzhiyun         and_byte,               /* 04 */
5504*4882a593Smuzhiyun         sub_byte,               /* 05 */
5505*4882a593Smuzhiyun         xor_byte,               /* 06 */
5506*4882a593Smuzhiyun         cmp_byte,               /* 07 */
5507*4882a593Smuzhiyun };
5508*4882a593Smuzhiyun 
5509*4882a593Smuzhiyun /****************************************************************************
5510*4882a593Smuzhiyun REMARKS:
5511*4882a593Smuzhiyun Handles opcode 0x80
5512*4882a593Smuzhiyun ****************************************************************************/
5513*4882a593Smuzhiyun static void
x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED (op1))5514*4882a593Smuzhiyun x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5515*4882a593Smuzhiyun {
5516*4882a593Smuzhiyun     int mod, rl, rh;
5517*4882a593Smuzhiyun     u8 *destreg;
5518*4882a593Smuzhiyun     uint destoffset;
5519*4882a593Smuzhiyun     u8 imm;
5520*4882a593Smuzhiyun     u8 destval;
5521*4882a593Smuzhiyun 
5522*4882a593Smuzhiyun     /*
5523*4882a593Smuzhiyun      * Weirdo special case instruction format.  Part of the opcode
5524*4882a593Smuzhiyun      * held below in "RH".  Doubly nested case would result, except
5525*4882a593Smuzhiyun      * that the decoded instruction
5526*4882a593Smuzhiyun      */
5527*4882a593Smuzhiyun     START_OF_INSTR();
5528*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
5529*4882a593Smuzhiyun #ifdef DEBUG
5530*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
5531*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
5532*4882a593Smuzhiyun            general, so that it is important to leave the strings
5533*4882a593Smuzhiyun            in the same format, even though the result is that the
5534*4882a593Smuzhiyun            above test is done twice. */
5535*4882a593Smuzhiyun 
5536*4882a593Smuzhiyun         switch (rh) {
5537*4882a593Smuzhiyun         case 0:
5538*4882a593Smuzhiyun             DECODE_PRINTF("ADD\t");
5539*4882a593Smuzhiyun             break;
5540*4882a593Smuzhiyun         case 1:
5541*4882a593Smuzhiyun             DECODE_PRINTF("OR\t");
5542*4882a593Smuzhiyun             break;
5543*4882a593Smuzhiyun         case 2:
5544*4882a593Smuzhiyun             DECODE_PRINTF("ADC\t");
5545*4882a593Smuzhiyun             break;
5546*4882a593Smuzhiyun         case 3:
5547*4882a593Smuzhiyun             DECODE_PRINTF("SBB\t");
5548*4882a593Smuzhiyun             break;
5549*4882a593Smuzhiyun         case 4:
5550*4882a593Smuzhiyun             DECODE_PRINTF("AND\t");
5551*4882a593Smuzhiyun             break;
5552*4882a593Smuzhiyun         case 5:
5553*4882a593Smuzhiyun             DECODE_PRINTF("SUB\t");
5554*4882a593Smuzhiyun             break;
5555*4882a593Smuzhiyun         case 6:
5556*4882a593Smuzhiyun             DECODE_PRINTF("XOR\t");
5557*4882a593Smuzhiyun             break;
5558*4882a593Smuzhiyun         case 7:
5559*4882a593Smuzhiyun             DECODE_PRINTF("CMP\t");
5560*4882a593Smuzhiyun             break;
5561*4882a593Smuzhiyun         }
5562*4882a593Smuzhiyun     }
5563*4882a593Smuzhiyun #endif
5564*4882a593Smuzhiyun     /* know operation, decode the mod byte to find the addressing
5565*4882a593Smuzhiyun        mode. */
5566*4882a593Smuzhiyun     switch (mod) {
5567*4882a593Smuzhiyun     case 0:
5568*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
5569*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
5570*4882a593Smuzhiyun         DECODE_PRINTF(",");
5571*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
5572*4882a593Smuzhiyun         imm = fetch_byte_imm();
5573*4882a593Smuzhiyun         DECODE_PRINTF2("%x\n", imm);
5574*4882a593Smuzhiyun         TRACE_AND_STEP();
5575*4882a593Smuzhiyun         destval = (*opc80_byte_operation[rh]) (destval, imm);
5576*4882a593Smuzhiyun         if (rh != 7)
5577*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
5578*4882a593Smuzhiyun         break;
5579*4882a593Smuzhiyun     case 1:
5580*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
5581*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
5582*4882a593Smuzhiyun         DECODE_PRINTF(",");
5583*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
5584*4882a593Smuzhiyun         imm = fetch_byte_imm();
5585*4882a593Smuzhiyun         DECODE_PRINTF2("%x\n", imm);
5586*4882a593Smuzhiyun         TRACE_AND_STEP();
5587*4882a593Smuzhiyun         destval = (*opc80_byte_operation[rh]) (destval, imm);
5588*4882a593Smuzhiyun         if (rh != 7)
5589*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
5590*4882a593Smuzhiyun         break;
5591*4882a593Smuzhiyun     case 2:
5592*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
5593*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
5594*4882a593Smuzhiyun         DECODE_PRINTF(",");
5595*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
5596*4882a593Smuzhiyun         imm = fetch_byte_imm();
5597*4882a593Smuzhiyun         DECODE_PRINTF2("%x\n", imm);
5598*4882a593Smuzhiyun         TRACE_AND_STEP();
5599*4882a593Smuzhiyun         destval = (*opc80_byte_operation[rh]) (destval, imm);
5600*4882a593Smuzhiyun         if (rh != 7)
5601*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
5602*4882a593Smuzhiyun         break;
5603*4882a593Smuzhiyun     case 3:                    /* register to register */
5604*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
5605*4882a593Smuzhiyun         DECODE_PRINTF(",");
5606*4882a593Smuzhiyun         imm = fetch_byte_imm();
5607*4882a593Smuzhiyun         DECODE_PRINTF2("%x\n", imm);
5608*4882a593Smuzhiyun         TRACE_AND_STEP();
5609*4882a593Smuzhiyun         destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5610*4882a593Smuzhiyun         if (rh != 7)
5611*4882a593Smuzhiyun             *destreg = destval;
5612*4882a593Smuzhiyun         break;
5613*4882a593Smuzhiyun     }
5614*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5615*4882a593Smuzhiyun     END_OF_INSTR();
5616*4882a593Smuzhiyun }
5617*4882a593Smuzhiyun 
5618*4882a593Smuzhiyun static u16(*opc81_word_operation[]) (u16 d, u16 s) = {
5619*4882a593Smuzhiyun     add_word,                   /*00 */
5620*4882a593Smuzhiyun         or_word,                /*01 */
5621*4882a593Smuzhiyun         adc_word,               /*02 */
5622*4882a593Smuzhiyun         sbb_word,               /*03 */
5623*4882a593Smuzhiyun         and_word,               /*04 */
5624*4882a593Smuzhiyun         sub_word,               /*05 */
5625*4882a593Smuzhiyun         xor_word,               /*06 */
5626*4882a593Smuzhiyun         cmp_word,               /*07 */
5627*4882a593Smuzhiyun };
5628*4882a593Smuzhiyun 
5629*4882a593Smuzhiyun static u32(*opc81_long_operation[]) (u32 d, u32 s) = {
5630*4882a593Smuzhiyun     add_long,                   /*00 */
5631*4882a593Smuzhiyun         or_long,                /*01 */
5632*4882a593Smuzhiyun         adc_long,               /*02 */
5633*4882a593Smuzhiyun         sbb_long,               /*03 */
5634*4882a593Smuzhiyun         and_long,               /*04 */
5635*4882a593Smuzhiyun         sub_long,               /*05 */
5636*4882a593Smuzhiyun         xor_long,               /*06 */
5637*4882a593Smuzhiyun         cmp_long,               /*07 */
5638*4882a593Smuzhiyun };
5639*4882a593Smuzhiyun 
5640*4882a593Smuzhiyun /****************************************************************************
5641*4882a593Smuzhiyun REMARKS:
5642*4882a593Smuzhiyun Handles opcode 0x81
5643*4882a593Smuzhiyun ****************************************************************************/
5644*4882a593Smuzhiyun static void
x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED (op1))5645*4882a593Smuzhiyun x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5646*4882a593Smuzhiyun {
5647*4882a593Smuzhiyun     int mod, rl, rh;
5648*4882a593Smuzhiyun     uint destoffset;
5649*4882a593Smuzhiyun 
5650*4882a593Smuzhiyun     /*
5651*4882a593Smuzhiyun      * Weirdo special case instruction format.  Part of the opcode
5652*4882a593Smuzhiyun      * held below in "RH".  Doubly nested case would result, except
5653*4882a593Smuzhiyun      * that the decoded instruction
5654*4882a593Smuzhiyun      */
5655*4882a593Smuzhiyun     START_OF_INSTR();
5656*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
5657*4882a593Smuzhiyun #ifdef DEBUG
5658*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
5659*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
5660*4882a593Smuzhiyun            general, so that it is important to leave the strings
5661*4882a593Smuzhiyun            in the same format, even though the result is that the
5662*4882a593Smuzhiyun            above test is done twice. */
5663*4882a593Smuzhiyun 
5664*4882a593Smuzhiyun         switch (rh) {
5665*4882a593Smuzhiyun         case 0:
5666*4882a593Smuzhiyun             DECODE_PRINTF("ADD\t");
5667*4882a593Smuzhiyun             break;
5668*4882a593Smuzhiyun         case 1:
5669*4882a593Smuzhiyun             DECODE_PRINTF("OR\t");
5670*4882a593Smuzhiyun             break;
5671*4882a593Smuzhiyun         case 2:
5672*4882a593Smuzhiyun             DECODE_PRINTF("ADC\t");
5673*4882a593Smuzhiyun             break;
5674*4882a593Smuzhiyun         case 3:
5675*4882a593Smuzhiyun             DECODE_PRINTF("SBB\t");
5676*4882a593Smuzhiyun             break;
5677*4882a593Smuzhiyun         case 4:
5678*4882a593Smuzhiyun             DECODE_PRINTF("AND\t");
5679*4882a593Smuzhiyun             break;
5680*4882a593Smuzhiyun         case 5:
5681*4882a593Smuzhiyun             DECODE_PRINTF("SUB\t");
5682*4882a593Smuzhiyun             break;
5683*4882a593Smuzhiyun         case 6:
5684*4882a593Smuzhiyun             DECODE_PRINTF("XOR\t");
5685*4882a593Smuzhiyun             break;
5686*4882a593Smuzhiyun         case 7:
5687*4882a593Smuzhiyun             DECODE_PRINTF("CMP\t");
5688*4882a593Smuzhiyun             break;
5689*4882a593Smuzhiyun         }
5690*4882a593Smuzhiyun     }
5691*4882a593Smuzhiyun #endif
5692*4882a593Smuzhiyun     /*
5693*4882a593Smuzhiyun      * Know operation, decode the mod byte to find the addressing
5694*4882a593Smuzhiyun      * mode.
5695*4882a593Smuzhiyun      */
5696*4882a593Smuzhiyun     switch (mod) {
5697*4882a593Smuzhiyun     case 0:
5698*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5699*4882a593Smuzhiyun             u32 destval, imm;
5700*4882a593Smuzhiyun 
5701*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
5702*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
5703*4882a593Smuzhiyun             DECODE_PRINTF(",");
5704*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
5705*4882a593Smuzhiyun             imm = fetch_long_imm();
5706*4882a593Smuzhiyun             DECODE_PRINTF2("%x\n", imm);
5707*4882a593Smuzhiyun             TRACE_AND_STEP();
5708*4882a593Smuzhiyun             destval = (*opc81_long_operation[rh]) (destval, imm);
5709*4882a593Smuzhiyun             if (rh != 7)
5710*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
5711*4882a593Smuzhiyun         }
5712*4882a593Smuzhiyun         else {
5713*4882a593Smuzhiyun             u16 destval, imm;
5714*4882a593Smuzhiyun 
5715*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
5716*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
5717*4882a593Smuzhiyun             DECODE_PRINTF(",");
5718*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
5719*4882a593Smuzhiyun             imm = fetch_word_imm();
5720*4882a593Smuzhiyun             DECODE_PRINTF2("%x\n", imm);
5721*4882a593Smuzhiyun             TRACE_AND_STEP();
5722*4882a593Smuzhiyun             destval = (*opc81_word_operation[rh]) (destval, imm);
5723*4882a593Smuzhiyun             if (rh != 7)
5724*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
5725*4882a593Smuzhiyun         }
5726*4882a593Smuzhiyun         break;
5727*4882a593Smuzhiyun     case 1:
5728*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5729*4882a593Smuzhiyun             u32 destval, imm;
5730*4882a593Smuzhiyun 
5731*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
5732*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
5733*4882a593Smuzhiyun             DECODE_PRINTF(",");
5734*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
5735*4882a593Smuzhiyun             imm = fetch_long_imm();
5736*4882a593Smuzhiyun             DECODE_PRINTF2("%x\n", imm);
5737*4882a593Smuzhiyun             TRACE_AND_STEP();
5738*4882a593Smuzhiyun             destval = (*opc81_long_operation[rh]) (destval, imm);
5739*4882a593Smuzhiyun             if (rh != 7)
5740*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
5741*4882a593Smuzhiyun         }
5742*4882a593Smuzhiyun         else {
5743*4882a593Smuzhiyun             u16 destval, imm;
5744*4882a593Smuzhiyun 
5745*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
5746*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
5747*4882a593Smuzhiyun             DECODE_PRINTF(",");
5748*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
5749*4882a593Smuzhiyun             imm = fetch_word_imm();
5750*4882a593Smuzhiyun             DECODE_PRINTF2("%x\n", imm);
5751*4882a593Smuzhiyun             TRACE_AND_STEP();
5752*4882a593Smuzhiyun             destval = (*opc81_word_operation[rh]) (destval, imm);
5753*4882a593Smuzhiyun             if (rh != 7)
5754*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
5755*4882a593Smuzhiyun         }
5756*4882a593Smuzhiyun         break;
5757*4882a593Smuzhiyun     case 2:
5758*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5759*4882a593Smuzhiyun             u32 destval, imm;
5760*4882a593Smuzhiyun 
5761*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
5762*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
5763*4882a593Smuzhiyun             DECODE_PRINTF(",");
5764*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
5765*4882a593Smuzhiyun             imm = fetch_long_imm();
5766*4882a593Smuzhiyun             DECODE_PRINTF2("%x\n", imm);
5767*4882a593Smuzhiyun             TRACE_AND_STEP();
5768*4882a593Smuzhiyun             destval = (*opc81_long_operation[rh]) (destval, imm);
5769*4882a593Smuzhiyun             if (rh != 7)
5770*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
5771*4882a593Smuzhiyun         }
5772*4882a593Smuzhiyun         else {
5773*4882a593Smuzhiyun             u16 destval, imm;
5774*4882a593Smuzhiyun 
5775*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
5776*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
5777*4882a593Smuzhiyun             DECODE_PRINTF(",");
5778*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
5779*4882a593Smuzhiyun             imm = fetch_word_imm();
5780*4882a593Smuzhiyun             DECODE_PRINTF2("%x\n", imm);
5781*4882a593Smuzhiyun             TRACE_AND_STEP();
5782*4882a593Smuzhiyun             destval = (*opc81_word_operation[rh]) (destval, imm);
5783*4882a593Smuzhiyun             if (rh != 7)
5784*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
5785*4882a593Smuzhiyun         }
5786*4882a593Smuzhiyun         break;
5787*4882a593Smuzhiyun     case 3:                    /* register to register */
5788*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5789*4882a593Smuzhiyun             u32 *destreg;
5790*4882a593Smuzhiyun             u32 destval, imm;
5791*4882a593Smuzhiyun 
5792*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
5793*4882a593Smuzhiyun             DECODE_PRINTF(",");
5794*4882a593Smuzhiyun             imm = fetch_long_imm();
5795*4882a593Smuzhiyun             DECODE_PRINTF2("%x\n", imm);
5796*4882a593Smuzhiyun             TRACE_AND_STEP();
5797*4882a593Smuzhiyun             destval = (*opc81_long_operation[rh]) (*destreg, imm);
5798*4882a593Smuzhiyun             if (rh != 7)
5799*4882a593Smuzhiyun                 *destreg = destval;
5800*4882a593Smuzhiyun         }
5801*4882a593Smuzhiyun         else {
5802*4882a593Smuzhiyun             u16 *destreg;
5803*4882a593Smuzhiyun             u16 destval, imm;
5804*4882a593Smuzhiyun 
5805*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
5806*4882a593Smuzhiyun             DECODE_PRINTF(",");
5807*4882a593Smuzhiyun             imm = fetch_word_imm();
5808*4882a593Smuzhiyun             DECODE_PRINTF2("%x\n", imm);
5809*4882a593Smuzhiyun             TRACE_AND_STEP();
5810*4882a593Smuzhiyun             destval = (*opc81_word_operation[rh]) (*destreg, imm);
5811*4882a593Smuzhiyun             if (rh != 7)
5812*4882a593Smuzhiyun                 *destreg = destval;
5813*4882a593Smuzhiyun         }
5814*4882a593Smuzhiyun         break;
5815*4882a593Smuzhiyun     }
5816*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5817*4882a593Smuzhiyun     END_OF_INSTR();
5818*4882a593Smuzhiyun }
5819*4882a593Smuzhiyun 
5820*4882a593Smuzhiyun static u8(*opc82_byte_operation[]) (u8 s, u8 d) = {
5821*4882a593Smuzhiyun     add_byte,                   /*00 */
5822*4882a593Smuzhiyun         or_byte,                /*01 *//*YYY UNUSED ???? */
5823*4882a593Smuzhiyun         adc_byte,               /*02 */
5824*4882a593Smuzhiyun         sbb_byte,               /*03 */
5825*4882a593Smuzhiyun         and_byte,               /*04 *//*YYY UNUSED ???? */
5826*4882a593Smuzhiyun         sub_byte,               /*05 */
5827*4882a593Smuzhiyun         xor_byte,               /*06 *//*YYY UNUSED ???? */
5828*4882a593Smuzhiyun         cmp_byte,               /*07 */
5829*4882a593Smuzhiyun };
5830*4882a593Smuzhiyun 
5831*4882a593Smuzhiyun /****************************************************************************
5832*4882a593Smuzhiyun REMARKS:
5833*4882a593Smuzhiyun Handles opcode 0x82
5834*4882a593Smuzhiyun ****************************************************************************/
5835*4882a593Smuzhiyun static void
x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED (op1))5836*4882a593Smuzhiyun x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5837*4882a593Smuzhiyun {
5838*4882a593Smuzhiyun     int mod, rl, rh;
5839*4882a593Smuzhiyun     u8 *destreg;
5840*4882a593Smuzhiyun     uint destoffset;
5841*4882a593Smuzhiyun     u8 imm;
5842*4882a593Smuzhiyun     u8 destval;
5843*4882a593Smuzhiyun 
5844*4882a593Smuzhiyun     /*
5845*4882a593Smuzhiyun      * Weirdo special case instruction format.  Part of the opcode
5846*4882a593Smuzhiyun      * held below in "RH".  Doubly nested case would result, except
5847*4882a593Smuzhiyun      * that the decoded instruction Similar to opcode 81, except that
5848*4882a593Smuzhiyun      * the immediate byte is sign extended to a word length.
5849*4882a593Smuzhiyun      */
5850*4882a593Smuzhiyun     START_OF_INSTR();
5851*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
5852*4882a593Smuzhiyun #ifdef DEBUG
5853*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
5854*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
5855*4882a593Smuzhiyun            general, so that it is important to leave the strings
5856*4882a593Smuzhiyun            in the same format, even though the result is that the
5857*4882a593Smuzhiyun            above test is done twice. */
5858*4882a593Smuzhiyun         switch (rh) {
5859*4882a593Smuzhiyun         case 0:
5860*4882a593Smuzhiyun             DECODE_PRINTF("ADD\t");
5861*4882a593Smuzhiyun             break;
5862*4882a593Smuzhiyun         case 1:
5863*4882a593Smuzhiyun             DECODE_PRINTF("OR\t");
5864*4882a593Smuzhiyun             break;
5865*4882a593Smuzhiyun         case 2:
5866*4882a593Smuzhiyun             DECODE_PRINTF("ADC\t");
5867*4882a593Smuzhiyun             break;
5868*4882a593Smuzhiyun         case 3:
5869*4882a593Smuzhiyun             DECODE_PRINTF("SBB\t");
5870*4882a593Smuzhiyun             break;
5871*4882a593Smuzhiyun         case 4:
5872*4882a593Smuzhiyun             DECODE_PRINTF("AND\t");
5873*4882a593Smuzhiyun             break;
5874*4882a593Smuzhiyun         case 5:
5875*4882a593Smuzhiyun             DECODE_PRINTF("SUB\t");
5876*4882a593Smuzhiyun             break;
5877*4882a593Smuzhiyun         case 6:
5878*4882a593Smuzhiyun             DECODE_PRINTF("XOR\t");
5879*4882a593Smuzhiyun             break;
5880*4882a593Smuzhiyun         case 7:
5881*4882a593Smuzhiyun             DECODE_PRINTF("CMP\t");
5882*4882a593Smuzhiyun             break;
5883*4882a593Smuzhiyun         }
5884*4882a593Smuzhiyun     }
5885*4882a593Smuzhiyun #endif
5886*4882a593Smuzhiyun     /* know operation, decode the mod byte to find the addressing
5887*4882a593Smuzhiyun        mode. */
5888*4882a593Smuzhiyun     switch (mod) {
5889*4882a593Smuzhiyun     case 0:
5890*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
5891*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
5892*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
5893*4882a593Smuzhiyun         imm = fetch_byte_imm();
5894*4882a593Smuzhiyun         DECODE_PRINTF2(",%x\n", imm);
5895*4882a593Smuzhiyun         TRACE_AND_STEP();
5896*4882a593Smuzhiyun         destval = (*opc82_byte_operation[rh]) (destval, imm);
5897*4882a593Smuzhiyun         if (rh != 7)
5898*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
5899*4882a593Smuzhiyun         break;
5900*4882a593Smuzhiyun     case 1:
5901*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
5902*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
5903*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
5904*4882a593Smuzhiyun         imm = fetch_byte_imm();
5905*4882a593Smuzhiyun         DECODE_PRINTF2(",%x\n", imm);
5906*4882a593Smuzhiyun         TRACE_AND_STEP();
5907*4882a593Smuzhiyun         destval = (*opc82_byte_operation[rh]) (destval, imm);
5908*4882a593Smuzhiyun         if (rh != 7)
5909*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
5910*4882a593Smuzhiyun         break;
5911*4882a593Smuzhiyun     case 2:
5912*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
5913*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
5914*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
5915*4882a593Smuzhiyun         imm = fetch_byte_imm();
5916*4882a593Smuzhiyun         DECODE_PRINTF2(",%x\n", imm);
5917*4882a593Smuzhiyun         TRACE_AND_STEP();
5918*4882a593Smuzhiyun         destval = (*opc82_byte_operation[rh]) (destval, imm);
5919*4882a593Smuzhiyun         if (rh != 7)
5920*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
5921*4882a593Smuzhiyun         break;
5922*4882a593Smuzhiyun     case 3:                    /* register to register */
5923*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
5924*4882a593Smuzhiyun         imm = fetch_byte_imm();
5925*4882a593Smuzhiyun         DECODE_PRINTF2(",%x\n", imm);
5926*4882a593Smuzhiyun         TRACE_AND_STEP();
5927*4882a593Smuzhiyun         destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5928*4882a593Smuzhiyun         if (rh != 7)
5929*4882a593Smuzhiyun             *destreg = destval;
5930*4882a593Smuzhiyun         break;
5931*4882a593Smuzhiyun     }
5932*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
5933*4882a593Smuzhiyun     END_OF_INSTR();
5934*4882a593Smuzhiyun }
5935*4882a593Smuzhiyun 
5936*4882a593Smuzhiyun static u16(*opc83_word_operation[]) (u16 s, u16 d) = {
5937*4882a593Smuzhiyun     add_word,                   /*00 */
5938*4882a593Smuzhiyun         or_word,                /*01 *//*YYY UNUSED ???? */
5939*4882a593Smuzhiyun         adc_word,               /*02 */
5940*4882a593Smuzhiyun         sbb_word,               /*03 */
5941*4882a593Smuzhiyun         and_word,               /*04 *//*YYY UNUSED ???? */
5942*4882a593Smuzhiyun         sub_word,               /*05 */
5943*4882a593Smuzhiyun         xor_word,               /*06 *//*YYY UNUSED ???? */
5944*4882a593Smuzhiyun         cmp_word,               /*07 */
5945*4882a593Smuzhiyun };
5946*4882a593Smuzhiyun 
5947*4882a593Smuzhiyun static u32(*opc83_long_operation[]) (u32 s, u32 d) = {
5948*4882a593Smuzhiyun     add_long,                   /*00 */
5949*4882a593Smuzhiyun         or_long,                /*01 *//*YYY UNUSED ???? */
5950*4882a593Smuzhiyun         adc_long,               /*02 */
5951*4882a593Smuzhiyun         sbb_long,               /*03 */
5952*4882a593Smuzhiyun         and_long,               /*04 *//*YYY UNUSED ???? */
5953*4882a593Smuzhiyun         sub_long,               /*05 */
5954*4882a593Smuzhiyun         xor_long,               /*06 *//*YYY UNUSED ???? */
5955*4882a593Smuzhiyun         cmp_long,               /*07 */
5956*4882a593Smuzhiyun };
5957*4882a593Smuzhiyun 
5958*4882a593Smuzhiyun /****************************************************************************
5959*4882a593Smuzhiyun REMARKS:
5960*4882a593Smuzhiyun Handles opcode 0x83
5961*4882a593Smuzhiyun ****************************************************************************/
5962*4882a593Smuzhiyun static void
x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED (op1))5963*4882a593Smuzhiyun x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5964*4882a593Smuzhiyun {
5965*4882a593Smuzhiyun     int mod, rl, rh;
5966*4882a593Smuzhiyun     uint destoffset;
5967*4882a593Smuzhiyun 
5968*4882a593Smuzhiyun     /*
5969*4882a593Smuzhiyun      * Weirdo special case instruction format.  Part of the opcode
5970*4882a593Smuzhiyun      * held below in "RH".  Doubly nested case would result, except
5971*4882a593Smuzhiyun      * that the decoded instruction Similar to opcode 81, except that
5972*4882a593Smuzhiyun      * the immediate byte is sign extended to a word length.
5973*4882a593Smuzhiyun      */
5974*4882a593Smuzhiyun     START_OF_INSTR();
5975*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
5976*4882a593Smuzhiyun #ifdef DEBUG
5977*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
5978*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
5979*4882a593Smuzhiyun            general, so that it is important to leave the strings
5980*4882a593Smuzhiyun            in the same format, even though the result is that the
5981*4882a593Smuzhiyun            above test is done twice. */
5982*4882a593Smuzhiyun         switch (rh) {
5983*4882a593Smuzhiyun         case 0:
5984*4882a593Smuzhiyun             DECODE_PRINTF("ADD\t");
5985*4882a593Smuzhiyun             break;
5986*4882a593Smuzhiyun         case 1:
5987*4882a593Smuzhiyun             DECODE_PRINTF("OR\t");
5988*4882a593Smuzhiyun             break;
5989*4882a593Smuzhiyun         case 2:
5990*4882a593Smuzhiyun             DECODE_PRINTF("ADC\t");
5991*4882a593Smuzhiyun             break;
5992*4882a593Smuzhiyun         case 3:
5993*4882a593Smuzhiyun             DECODE_PRINTF("SBB\t");
5994*4882a593Smuzhiyun             break;
5995*4882a593Smuzhiyun         case 4:
5996*4882a593Smuzhiyun             DECODE_PRINTF("AND\t");
5997*4882a593Smuzhiyun             break;
5998*4882a593Smuzhiyun         case 5:
5999*4882a593Smuzhiyun             DECODE_PRINTF("SUB\t");
6000*4882a593Smuzhiyun             break;
6001*4882a593Smuzhiyun         case 6:
6002*4882a593Smuzhiyun             DECODE_PRINTF("XOR\t");
6003*4882a593Smuzhiyun             break;
6004*4882a593Smuzhiyun         case 7:
6005*4882a593Smuzhiyun             DECODE_PRINTF("CMP\t");
6006*4882a593Smuzhiyun             break;
6007*4882a593Smuzhiyun         }
6008*4882a593Smuzhiyun     }
6009*4882a593Smuzhiyun #endif
6010*4882a593Smuzhiyun     /* know operation, decode the mod byte to find the addressing
6011*4882a593Smuzhiyun        mode. */
6012*4882a593Smuzhiyun     switch (mod) {
6013*4882a593Smuzhiyun     case 0:
6014*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6015*4882a593Smuzhiyun             u32 destval, imm;
6016*4882a593Smuzhiyun 
6017*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
6018*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
6019*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
6020*4882a593Smuzhiyun             imm = (s8) fetch_byte_imm();
6021*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
6022*4882a593Smuzhiyun             TRACE_AND_STEP();
6023*4882a593Smuzhiyun             destval = (*opc83_long_operation[rh]) (destval, imm);
6024*4882a593Smuzhiyun             if (rh != 7)
6025*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
6026*4882a593Smuzhiyun         }
6027*4882a593Smuzhiyun         else {
6028*4882a593Smuzhiyun             u16 destval, imm;
6029*4882a593Smuzhiyun 
6030*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
6031*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
6032*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
6033*4882a593Smuzhiyun             imm = (s8) fetch_byte_imm();
6034*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
6035*4882a593Smuzhiyun             TRACE_AND_STEP();
6036*4882a593Smuzhiyun             destval = (*opc83_word_operation[rh]) (destval, imm);
6037*4882a593Smuzhiyun             if (rh != 7)
6038*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
6039*4882a593Smuzhiyun         }
6040*4882a593Smuzhiyun         break;
6041*4882a593Smuzhiyun     case 1:
6042*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6043*4882a593Smuzhiyun             u32 destval, imm;
6044*4882a593Smuzhiyun 
6045*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
6046*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
6047*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
6048*4882a593Smuzhiyun             imm = (s8) fetch_byte_imm();
6049*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
6050*4882a593Smuzhiyun             TRACE_AND_STEP();
6051*4882a593Smuzhiyun             destval = (*opc83_long_operation[rh]) (destval, imm);
6052*4882a593Smuzhiyun             if (rh != 7)
6053*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
6054*4882a593Smuzhiyun         }
6055*4882a593Smuzhiyun         else {
6056*4882a593Smuzhiyun             u16 destval, imm;
6057*4882a593Smuzhiyun 
6058*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
6059*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
6060*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
6061*4882a593Smuzhiyun             imm = (s8) fetch_byte_imm();
6062*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
6063*4882a593Smuzhiyun             TRACE_AND_STEP();
6064*4882a593Smuzhiyun             destval = (*opc83_word_operation[rh]) (destval, imm);
6065*4882a593Smuzhiyun             if (rh != 7)
6066*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
6067*4882a593Smuzhiyun         }
6068*4882a593Smuzhiyun         break;
6069*4882a593Smuzhiyun     case 2:
6070*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6071*4882a593Smuzhiyun             u32 destval, imm;
6072*4882a593Smuzhiyun 
6073*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
6074*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
6075*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
6076*4882a593Smuzhiyun             imm = (s8) fetch_byte_imm();
6077*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
6078*4882a593Smuzhiyun             TRACE_AND_STEP();
6079*4882a593Smuzhiyun             destval = (*opc83_long_operation[rh]) (destval, imm);
6080*4882a593Smuzhiyun             if (rh != 7)
6081*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
6082*4882a593Smuzhiyun         }
6083*4882a593Smuzhiyun         else {
6084*4882a593Smuzhiyun             u16 destval, imm;
6085*4882a593Smuzhiyun 
6086*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
6087*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
6088*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
6089*4882a593Smuzhiyun             imm = (s8) fetch_byte_imm();
6090*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
6091*4882a593Smuzhiyun             TRACE_AND_STEP();
6092*4882a593Smuzhiyun             destval = (*opc83_word_operation[rh]) (destval, imm);
6093*4882a593Smuzhiyun             if (rh != 7)
6094*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
6095*4882a593Smuzhiyun         }
6096*4882a593Smuzhiyun         break;
6097*4882a593Smuzhiyun     case 3:                    /* register to register */
6098*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6099*4882a593Smuzhiyun             u32 *destreg;
6100*4882a593Smuzhiyun             u32 destval, imm;
6101*4882a593Smuzhiyun 
6102*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
6103*4882a593Smuzhiyun             imm = (s8) fetch_byte_imm();
6104*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
6105*4882a593Smuzhiyun             TRACE_AND_STEP();
6106*4882a593Smuzhiyun             destval = (*opc83_long_operation[rh]) (*destreg, imm);
6107*4882a593Smuzhiyun             if (rh != 7)
6108*4882a593Smuzhiyun                 *destreg = destval;
6109*4882a593Smuzhiyun         }
6110*4882a593Smuzhiyun         else {
6111*4882a593Smuzhiyun             u16 *destreg;
6112*4882a593Smuzhiyun             u16 destval, imm;
6113*4882a593Smuzhiyun 
6114*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
6115*4882a593Smuzhiyun             imm = (s8) fetch_byte_imm();
6116*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
6117*4882a593Smuzhiyun             TRACE_AND_STEP();
6118*4882a593Smuzhiyun             destval = (*opc83_word_operation[rh]) (*destreg, imm);
6119*4882a593Smuzhiyun             if (rh != 7)
6120*4882a593Smuzhiyun                 *destreg = destval;
6121*4882a593Smuzhiyun         }
6122*4882a593Smuzhiyun         break;
6123*4882a593Smuzhiyun     }
6124*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6125*4882a593Smuzhiyun     END_OF_INSTR();
6126*4882a593Smuzhiyun }
6127*4882a593Smuzhiyun 
6128*4882a593Smuzhiyun /****************************************************************************
6129*4882a593Smuzhiyun REMARKS:
6130*4882a593Smuzhiyun Handles opcode 0x84
6131*4882a593Smuzhiyun ****************************************************************************/
6132*4882a593Smuzhiyun static void
x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED (op1))6133*4882a593Smuzhiyun x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
6134*4882a593Smuzhiyun {
6135*4882a593Smuzhiyun     int mod, rl, rh;
6136*4882a593Smuzhiyun     u8 *destreg, *srcreg;
6137*4882a593Smuzhiyun     uint destoffset;
6138*4882a593Smuzhiyun     u8 destval;
6139*4882a593Smuzhiyun 
6140*4882a593Smuzhiyun     START_OF_INSTR();
6141*4882a593Smuzhiyun     DECODE_PRINTF("TEST\t");
6142*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
6143*4882a593Smuzhiyun     switch (mod) {
6144*4882a593Smuzhiyun     case 0:
6145*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
6146*4882a593Smuzhiyun         DECODE_PRINTF(",");
6147*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
6148*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6149*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6150*4882a593Smuzhiyun         TRACE_AND_STEP();
6151*4882a593Smuzhiyun         test_byte(destval, *srcreg);
6152*4882a593Smuzhiyun         break;
6153*4882a593Smuzhiyun     case 1:
6154*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
6155*4882a593Smuzhiyun         DECODE_PRINTF(",");
6156*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
6157*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6158*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6159*4882a593Smuzhiyun         TRACE_AND_STEP();
6160*4882a593Smuzhiyun         test_byte(destval, *srcreg);
6161*4882a593Smuzhiyun         break;
6162*4882a593Smuzhiyun     case 2:
6163*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
6164*4882a593Smuzhiyun         DECODE_PRINTF(",");
6165*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
6166*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6167*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6168*4882a593Smuzhiyun         TRACE_AND_STEP();
6169*4882a593Smuzhiyun         test_byte(destval, *srcreg);
6170*4882a593Smuzhiyun         break;
6171*4882a593Smuzhiyun     case 3:                    /* register to register */
6172*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
6173*4882a593Smuzhiyun         DECODE_PRINTF(",");
6174*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6175*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6176*4882a593Smuzhiyun         TRACE_AND_STEP();
6177*4882a593Smuzhiyun         test_byte(*destreg, *srcreg);
6178*4882a593Smuzhiyun         break;
6179*4882a593Smuzhiyun     }
6180*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6181*4882a593Smuzhiyun     END_OF_INSTR();
6182*4882a593Smuzhiyun }
6183*4882a593Smuzhiyun 
6184*4882a593Smuzhiyun /****************************************************************************
6185*4882a593Smuzhiyun REMARKS:
6186*4882a593Smuzhiyun Handles opcode 0x85
6187*4882a593Smuzhiyun ****************************************************************************/
6188*4882a593Smuzhiyun static void
x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED (op1))6189*4882a593Smuzhiyun x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
6190*4882a593Smuzhiyun {
6191*4882a593Smuzhiyun     int mod, rl, rh;
6192*4882a593Smuzhiyun     uint destoffset;
6193*4882a593Smuzhiyun 
6194*4882a593Smuzhiyun     START_OF_INSTR();
6195*4882a593Smuzhiyun     DECODE_PRINTF("TEST\t");
6196*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
6197*4882a593Smuzhiyun     switch (mod) {
6198*4882a593Smuzhiyun     case 0:
6199*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6200*4882a593Smuzhiyun             u32 destval;
6201*4882a593Smuzhiyun             u32 *srcreg;
6202*4882a593Smuzhiyun 
6203*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
6204*4882a593Smuzhiyun             DECODE_PRINTF(",");
6205*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
6206*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6207*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6208*4882a593Smuzhiyun             TRACE_AND_STEP();
6209*4882a593Smuzhiyun             test_long(destval, *srcreg);
6210*4882a593Smuzhiyun         }
6211*4882a593Smuzhiyun         else {
6212*4882a593Smuzhiyun             u16 destval;
6213*4882a593Smuzhiyun             u16 *srcreg;
6214*4882a593Smuzhiyun 
6215*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
6216*4882a593Smuzhiyun             DECODE_PRINTF(",");
6217*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
6218*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6219*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6220*4882a593Smuzhiyun             TRACE_AND_STEP();
6221*4882a593Smuzhiyun             test_word(destval, *srcreg);
6222*4882a593Smuzhiyun         }
6223*4882a593Smuzhiyun         break;
6224*4882a593Smuzhiyun     case 1:
6225*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6226*4882a593Smuzhiyun             u32 destval;
6227*4882a593Smuzhiyun             u32 *srcreg;
6228*4882a593Smuzhiyun 
6229*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
6230*4882a593Smuzhiyun             DECODE_PRINTF(",");
6231*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
6232*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6233*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6234*4882a593Smuzhiyun             TRACE_AND_STEP();
6235*4882a593Smuzhiyun             test_long(destval, *srcreg);
6236*4882a593Smuzhiyun         }
6237*4882a593Smuzhiyun         else {
6238*4882a593Smuzhiyun             u16 destval;
6239*4882a593Smuzhiyun             u16 *srcreg;
6240*4882a593Smuzhiyun 
6241*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
6242*4882a593Smuzhiyun             DECODE_PRINTF(",");
6243*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
6244*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6245*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6246*4882a593Smuzhiyun             TRACE_AND_STEP();
6247*4882a593Smuzhiyun             test_word(destval, *srcreg);
6248*4882a593Smuzhiyun         }
6249*4882a593Smuzhiyun         break;
6250*4882a593Smuzhiyun     case 2:
6251*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6252*4882a593Smuzhiyun             u32 destval;
6253*4882a593Smuzhiyun             u32 *srcreg;
6254*4882a593Smuzhiyun 
6255*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
6256*4882a593Smuzhiyun             DECODE_PRINTF(",");
6257*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
6258*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6259*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6260*4882a593Smuzhiyun             TRACE_AND_STEP();
6261*4882a593Smuzhiyun             test_long(destval, *srcreg);
6262*4882a593Smuzhiyun         }
6263*4882a593Smuzhiyun         else {
6264*4882a593Smuzhiyun             u16 destval;
6265*4882a593Smuzhiyun             u16 *srcreg;
6266*4882a593Smuzhiyun 
6267*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
6268*4882a593Smuzhiyun             DECODE_PRINTF(",");
6269*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
6270*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6271*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6272*4882a593Smuzhiyun             TRACE_AND_STEP();
6273*4882a593Smuzhiyun             test_word(destval, *srcreg);
6274*4882a593Smuzhiyun         }
6275*4882a593Smuzhiyun         break;
6276*4882a593Smuzhiyun     case 3:                    /* register to register */
6277*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6278*4882a593Smuzhiyun             u32 *destreg, *srcreg;
6279*4882a593Smuzhiyun 
6280*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
6281*4882a593Smuzhiyun             DECODE_PRINTF(",");
6282*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6283*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6284*4882a593Smuzhiyun             TRACE_AND_STEP();
6285*4882a593Smuzhiyun             test_long(*destreg, *srcreg);
6286*4882a593Smuzhiyun         }
6287*4882a593Smuzhiyun         else {
6288*4882a593Smuzhiyun             u16 *destreg, *srcreg;
6289*4882a593Smuzhiyun 
6290*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
6291*4882a593Smuzhiyun             DECODE_PRINTF(",");
6292*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6293*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6294*4882a593Smuzhiyun             TRACE_AND_STEP();
6295*4882a593Smuzhiyun             test_word(*destreg, *srcreg);
6296*4882a593Smuzhiyun         }
6297*4882a593Smuzhiyun         break;
6298*4882a593Smuzhiyun     }
6299*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6300*4882a593Smuzhiyun     END_OF_INSTR();
6301*4882a593Smuzhiyun }
6302*4882a593Smuzhiyun 
6303*4882a593Smuzhiyun /****************************************************************************
6304*4882a593Smuzhiyun REMARKS:
6305*4882a593Smuzhiyun Handles opcode 0x86
6306*4882a593Smuzhiyun ****************************************************************************/
6307*4882a593Smuzhiyun static void
x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED (op1))6308*4882a593Smuzhiyun x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
6309*4882a593Smuzhiyun {
6310*4882a593Smuzhiyun     int mod, rl, rh;
6311*4882a593Smuzhiyun     u8 *destreg, *srcreg;
6312*4882a593Smuzhiyun     uint destoffset;
6313*4882a593Smuzhiyun     u8 destval;
6314*4882a593Smuzhiyun     u8 tmp;
6315*4882a593Smuzhiyun 
6316*4882a593Smuzhiyun     START_OF_INSTR();
6317*4882a593Smuzhiyun     DECODE_PRINTF("XCHG\t");
6318*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
6319*4882a593Smuzhiyun     switch (mod) {
6320*4882a593Smuzhiyun     case 0:
6321*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
6322*4882a593Smuzhiyun         DECODE_PRINTF(",");
6323*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
6324*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6325*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6326*4882a593Smuzhiyun         TRACE_AND_STEP();
6327*4882a593Smuzhiyun         tmp = *srcreg;
6328*4882a593Smuzhiyun         *srcreg = destval;
6329*4882a593Smuzhiyun         destval = tmp;
6330*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
6331*4882a593Smuzhiyun         break;
6332*4882a593Smuzhiyun     case 1:
6333*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
6334*4882a593Smuzhiyun         DECODE_PRINTF(",");
6335*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
6336*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6337*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6338*4882a593Smuzhiyun         TRACE_AND_STEP();
6339*4882a593Smuzhiyun         tmp = *srcreg;
6340*4882a593Smuzhiyun         *srcreg = destval;
6341*4882a593Smuzhiyun         destval = tmp;
6342*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
6343*4882a593Smuzhiyun         break;
6344*4882a593Smuzhiyun     case 2:
6345*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
6346*4882a593Smuzhiyun         DECODE_PRINTF(",");
6347*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
6348*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6349*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6350*4882a593Smuzhiyun         TRACE_AND_STEP();
6351*4882a593Smuzhiyun         tmp = *srcreg;
6352*4882a593Smuzhiyun         *srcreg = destval;
6353*4882a593Smuzhiyun         destval = tmp;
6354*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
6355*4882a593Smuzhiyun         break;
6356*4882a593Smuzhiyun     case 3:                    /* register to register */
6357*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
6358*4882a593Smuzhiyun         DECODE_PRINTF(",");
6359*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6360*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6361*4882a593Smuzhiyun         TRACE_AND_STEP();
6362*4882a593Smuzhiyun         tmp = *srcreg;
6363*4882a593Smuzhiyun         *srcreg = *destreg;
6364*4882a593Smuzhiyun         *destreg = tmp;
6365*4882a593Smuzhiyun         break;
6366*4882a593Smuzhiyun     }
6367*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6368*4882a593Smuzhiyun     END_OF_INSTR();
6369*4882a593Smuzhiyun }
6370*4882a593Smuzhiyun 
6371*4882a593Smuzhiyun /****************************************************************************
6372*4882a593Smuzhiyun REMARKS:
6373*4882a593Smuzhiyun Handles opcode 0x87
6374*4882a593Smuzhiyun ****************************************************************************/
6375*4882a593Smuzhiyun static void
x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED (op1))6376*4882a593Smuzhiyun x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6377*4882a593Smuzhiyun {
6378*4882a593Smuzhiyun     int mod, rl, rh;
6379*4882a593Smuzhiyun     uint destoffset;
6380*4882a593Smuzhiyun 
6381*4882a593Smuzhiyun     START_OF_INSTR();
6382*4882a593Smuzhiyun     DECODE_PRINTF("XCHG\t");
6383*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
6384*4882a593Smuzhiyun     switch (mod) {
6385*4882a593Smuzhiyun     case 0:
6386*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6387*4882a593Smuzhiyun             u32 *srcreg;
6388*4882a593Smuzhiyun             u32 destval, tmp;
6389*4882a593Smuzhiyun 
6390*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
6391*4882a593Smuzhiyun             DECODE_PRINTF(",");
6392*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
6393*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6394*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6395*4882a593Smuzhiyun             TRACE_AND_STEP();
6396*4882a593Smuzhiyun             tmp = *srcreg;
6397*4882a593Smuzhiyun             *srcreg = destval;
6398*4882a593Smuzhiyun             destval = tmp;
6399*4882a593Smuzhiyun             store_data_long(destoffset, destval);
6400*4882a593Smuzhiyun         }
6401*4882a593Smuzhiyun         else {
6402*4882a593Smuzhiyun             u16 *srcreg;
6403*4882a593Smuzhiyun             u16 destval, tmp;
6404*4882a593Smuzhiyun 
6405*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
6406*4882a593Smuzhiyun             DECODE_PRINTF(",");
6407*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
6408*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6409*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6410*4882a593Smuzhiyun             TRACE_AND_STEP();
6411*4882a593Smuzhiyun             tmp = *srcreg;
6412*4882a593Smuzhiyun             *srcreg = destval;
6413*4882a593Smuzhiyun             destval = tmp;
6414*4882a593Smuzhiyun             store_data_word(destoffset, destval);
6415*4882a593Smuzhiyun         }
6416*4882a593Smuzhiyun         break;
6417*4882a593Smuzhiyun     case 1:
6418*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6419*4882a593Smuzhiyun             u32 *srcreg;
6420*4882a593Smuzhiyun             u32 destval, tmp;
6421*4882a593Smuzhiyun 
6422*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
6423*4882a593Smuzhiyun             DECODE_PRINTF(",");
6424*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
6425*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6426*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6427*4882a593Smuzhiyun             TRACE_AND_STEP();
6428*4882a593Smuzhiyun             tmp = *srcreg;
6429*4882a593Smuzhiyun             *srcreg = destval;
6430*4882a593Smuzhiyun             destval = tmp;
6431*4882a593Smuzhiyun             store_data_long(destoffset, destval);
6432*4882a593Smuzhiyun         }
6433*4882a593Smuzhiyun         else {
6434*4882a593Smuzhiyun             u16 *srcreg;
6435*4882a593Smuzhiyun             u16 destval, tmp;
6436*4882a593Smuzhiyun 
6437*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
6438*4882a593Smuzhiyun             DECODE_PRINTF(",");
6439*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
6440*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6441*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6442*4882a593Smuzhiyun             TRACE_AND_STEP();
6443*4882a593Smuzhiyun             tmp = *srcreg;
6444*4882a593Smuzhiyun             *srcreg = destval;
6445*4882a593Smuzhiyun             destval = tmp;
6446*4882a593Smuzhiyun             store_data_word(destoffset, destval);
6447*4882a593Smuzhiyun         }
6448*4882a593Smuzhiyun         break;
6449*4882a593Smuzhiyun     case 2:
6450*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6451*4882a593Smuzhiyun             u32 *srcreg;
6452*4882a593Smuzhiyun             u32 destval, tmp;
6453*4882a593Smuzhiyun 
6454*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
6455*4882a593Smuzhiyun             DECODE_PRINTF(",");
6456*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
6457*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6458*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6459*4882a593Smuzhiyun             TRACE_AND_STEP();
6460*4882a593Smuzhiyun             tmp = *srcreg;
6461*4882a593Smuzhiyun             *srcreg = destval;
6462*4882a593Smuzhiyun             destval = tmp;
6463*4882a593Smuzhiyun             store_data_long(destoffset, destval);
6464*4882a593Smuzhiyun         }
6465*4882a593Smuzhiyun         else {
6466*4882a593Smuzhiyun             u16 *srcreg;
6467*4882a593Smuzhiyun             u16 destval, tmp;
6468*4882a593Smuzhiyun 
6469*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
6470*4882a593Smuzhiyun             DECODE_PRINTF(",");
6471*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
6472*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6473*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6474*4882a593Smuzhiyun             TRACE_AND_STEP();
6475*4882a593Smuzhiyun             tmp = *srcreg;
6476*4882a593Smuzhiyun             *srcreg = destval;
6477*4882a593Smuzhiyun             destval = tmp;
6478*4882a593Smuzhiyun             store_data_word(destoffset, destval);
6479*4882a593Smuzhiyun         }
6480*4882a593Smuzhiyun         break;
6481*4882a593Smuzhiyun     case 3:                    /* register to register */
6482*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6483*4882a593Smuzhiyun             u32 *destreg, *srcreg;
6484*4882a593Smuzhiyun             u32 tmp;
6485*4882a593Smuzhiyun 
6486*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
6487*4882a593Smuzhiyun             DECODE_PRINTF(",");
6488*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6489*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6490*4882a593Smuzhiyun             TRACE_AND_STEP();
6491*4882a593Smuzhiyun             tmp = *srcreg;
6492*4882a593Smuzhiyun             *srcreg = *destreg;
6493*4882a593Smuzhiyun             *destreg = tmp;
6494*4882a593Smuzhiyun         }
6495*4882a593Smuzhiyun         else {
6496*4882a593Smuzhiyun             u16 *destreg, *srcreg;
6497*4882a593Smuzhiyun             u16 tmp;
6498*4882a593Smuzhiyun 
6499*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
6500*4882a593Smuzhiyun             DECODE_PRINTF(",");
6501*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6502*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6503*4882a593Smuzhiyun             TRACE_AND_STEP();
6504*4882a593Smuzhiyun             tmp = *srcreg;
6505*4882a593Smuzhiyun             *srcreg = *destreg;
6506*4882a593Smuzhiyun             *destreg = tmp;
6507*4882a593Smuzhiyun         }
6508*4882a593Smuzhiyun         break;
6509*4882a593Smuzhiyun     }
6510*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6511*4882a593Smuzhiyun     END_OF_INSTR();
6512*4882a593Smuzhiyun }
6513*4882a593Smuzhiyun 
6514*4882a593Smuzhiyun /****************************************************************************
6515*4882a593Smuzhiyun REMARKS:
6516*4882a593Smuzhiyun Handles opcode 0x88
6517*4882a593Smuzhiyun ****************************************************************************/
6518*4882a593Smuzhiyun static void
x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED (op1))6519*4882a593Smuzhiyun x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6520*4882a593Smuzhiyun {
6521*4882a593Smuzhiyun     int mod, rl, rh;
6522*4882a593Smuzhiyun     u8 *destreg, *srcreg;
6523*4882a593Smuzhiyun     uint destoffset;
6524*4882a593Smuzhiyun 
6525*4882a593Smuzhiyun     START_OF_INSTR();
6526*4882a593Smuzhiyun     DECODE_PRINTF("MOV\t");
6527*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
6528*4882a593Smuzhiyun     switch (mod) {
6529*4882a593Smuzhiyun     case 0:
6530*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
6531*4882a593Smuzhiyun         DECODE_PRINTF(",");
6532*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6533*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6534*4882a593Smuzhiyun         TRACE_AND_STEP();
6535*4882a593Smuzhiyun         store_data_byte(destoffset, *srcreg);
6536*4882a593Smuzhiyun         break;
6537*4882a593Smuzhiyun     case 1:
6538*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
6539*4882a593Smuzhiyun         DECODE_PRINTF(",");
6540*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6541*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6542*4882a593Smuzhiyun         TRACE_AND_STEP();
6543*4882a593Smuzhiyun         store_data_byte(destoffset, *srcreg);
6544*4882a593Smuzhiyun         break;
6545*4882a593Smuzhiyun     case 2:
6546*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
6547*4882a593Smuzhiyun         DECODE_PRINTF(",");
6548*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6549*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6550*4882a593Smuzhiyun         TRACE_AND_STEP();
6551*4882a593Smuzhiyun         store_data_byte(destoffset, *srcreg);
6552*4882a593Smuzhiyun         break;
6553*4882a593Smuzhiyun     case 3:                    /* register to register */
6554*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
6555*4882a593Smuzhiyun         DECODE_PRINTF(",");
6556*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6557*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6558*4882a593Smuzhiyun         TRACE_AND_STEP();
6559*4882a593Smuzhiyun         *destreg = *srcreg;
6560*4882a593Smuzhiyun         break;
6561*4882a593Smuzhiyun     }
6562*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6563*4882a593Smuzhiyun     END_OF_INSTR();
6564*4882a593Smuzhiyun }
6565*4882a593Smuzhiyun 
6566*4882a593Smuzhiyun /****************************************************************************
6567*4882a593Smuzhiyun REMARKS:
6568*4882a593Smuzhiyun Handles opcode 0x89
6569*4882a593Smuzhiyun ****************************************************************************/
6570*4882a593Smuzhiyun static void
x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED (op1))6571*4882a593Smuzhiyun x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6572*4882a593Smuzhiyun {
6573*4882a593Smuzhiyun     int mod, rl, rh;
6574*4882a593Smuzhiyun     u32 destoffset;
6575*4882a593Smuzhiyun 
6576*4882a593Smuzhiyun     START_OF_INSTR();
6577*4882a593Smuzhiyun     DECODE_PRINTF("MOV\t");
6578*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
6579*4882a593Smuzhiyun     switch (mod) {
6580*4882a593Smuzhiyun     case 0:
6581*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6582*4882a593Smuzhiyun             u32 *srcreg;
6583*4882a593Smuzhiyun 
6584*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
6585*4882a593Smuzhiyun             DECODE_PRINTF(",");
6586*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6587*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6588*4882a593Smuzhiyun             TRACE_AND_STEP();
6589*4882a593Smuzhiyun             store_data_long(destoffset, *srcreg);
6590*4882a593Smuzhiyun         }
6591*4882a593Smuzhiyun         else {
6592*4882a593Smuzhiyun             u16 *srcreg;
6593*4882a593Smuzhiyun 
6594*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
6595*4882a593Smuzhiyun             DECODE_PRINTF(",");
6596*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6597*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6598*4882a593Smuzhiyun             TRACE_AND_STEP();
6599*4882a593Smuzhiyun             store_data_word(destoffset, *srcreg);
6600*4882a593Smuzhiyun         }
6601*4882a593Smuzhiyun         break;
6602*4882a593Smuzhiyun     case 1:
6603*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6604*4882a593Smuzhiyun             u32 *srcreg;
6605*4882a593Smuzhiyun 
6606*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
6607*4882a593Smuzhiyun             DECODE_PRINTF(",");
6608*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6609*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6610*4882a593Smuzhiyun             TRACE_AND_STEP();
6611*4882a593Smuzhiyun             store_data_long(destoffset, *srcreg);
6612*4882a593Smuzhiyun         }
6613*4882a593Smuzhiyun         else {
6614*4882a593Smuzhiyun             u16 *srcreg;
6615*4882a593Smuzhiyun 
6616*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
6617*4882a593Smuzhiyun             DECODE_PRINTF(",");
6618*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6619*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6620*4882a593Smuzhiyun             TRACE_AND_STEP();
6621*4882a593Smuzhiyun             store_data_word(destoffset, *srcreg);
6622*4882a593Smuzhiyun         }
6623*4882a593Smuzhiyun         break;
6624*4882a593Smuzhiyun     case 2:
6625*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6626*4882a593Smuzhiyun             u32 *srcreg;
6627*4882a593Smuzhiyun 
6628*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
6629*4882a593Smuzhiyun             DECODE_PRINTF(",");
6630*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6631*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6632*4882a593Smuzhiyun             TRACE_AND_STEP();
6633*4882a593Smuzhiyun             store_data_long(destoffset, *srcreg);
6634*4882a593Smuzhiyun         }
6635*4882a593Smuzhiyun         else {
6636*4882a593Smuzhiyun             u16 *srcreg;
6637*4882a593Smuzhiyun 
6638*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
6639*4882a593Smuzhiyun             DECODE_PRINTF(",");
6640*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6641*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6642*4882a593Smuzhiyun             TRACE_AND_STEP();
6643*4882a593Smuzhiyun             store_data_word(destoffset, *srcreg);
6644*4882a593Smuzhiyun         }
6645*4882a593Smuzhiyun         break;
6646*4882a593Smuzhiyun     case 3:                    /* register to register */
6647*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6648*4882a593Smuzhiyun             u32 *destreg, *srcreg;
6649*4882a593Smuzhiyun 
6650*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
6651*4882a593Smuzhiyun             DECODE_PRINTF(",");
6652*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rh);
6653*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6654*4882a593Smuzhiyun             TRACE_AND_STEP();
6655*4882a593Smuzhiyun             *destreg = *srcreg;
6656*4882a593Smuzhiyun         }
6657*4882a593Smuzhiyun         else {
6658*4882a593Smuzhiyun             u16 *destreg, *srcreg;
6659*4882a593Smuzhiyun 
6660*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
6661*4882a593Smuzhiyun             DECODE_PRINTF(",");
6662*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rh);
6663*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6664*4882a593Smuzhiyun             TRACE_AND_STEP();
6665*4882a593Smuzhiyun             *destreg = *srcreg;
6666*4882a593Smuzhiyun         }
6667*4882a593Smuzhiyun         break;
6668*4882a593Smuzhiyun     }
6669*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6670*4882a593Smuzhiyun     END_OF_INSTR();
6671*4882a593Smuzhiyun }
6672*4882a593Smuzhiyun 
6673*4882a593Smuzhiyun /****************************************************************************
6674*4882a593Smuzhiyun REMARKS:
6675*4882a593Smuzhiyun Handles opcode 0x8a
6676*4882a593Smuzhiyun ****************************************************************************/
6677*4882a593Smuzhiyun static void
x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED (op1))6678*4882a593Smuzhiyun x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6679*4882a593Smuzhiyun {
6680*4882a593Smuzhiyun     int mod, rl, rh;
6681*4882a593Smuzhiyun     u8 *destreg, *srcreg;
6682*4882a593Smuzhiyun     uint srcoffset;
6683*4882a593Smuzhiyun     u8 srcval;
6684*4882a593Smuzhiyun 
6685*4882a593Smuzhiyun     START_OF_INSTR();
6686*4882a593Smuzhiyun     DECODE_PRINTF("MOV\t");
6687*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
6688*4882a593Smuzhiyun     switch (mod) {
6689*4882a593Smuzhiyun     case 0:
6690*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
6691*4882a593Smuzhiyun         DECODE_PRINTF(",");
6692*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
6693*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
6694*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6695*4882a593Smuzhiyun         TRACE_AND_STEP();
6696*4882a593Smuzhiyun         *destreg = srcval;
6697*4882a593Smuzhiyun         break;
6698*4882a593Smuzhiyun     case 1:
6699*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
6700*4882a593Smuzhiyun         DECODE_PRINTF(",");
6701*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
6702*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
6703*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6704*4882a593Smuzhiyun         TRACE_AND_STEP();
6705*4882a593Smuzhiyun         *destreg = srcval;
6706*4882a593Smuzhiyun         break;
6707*4882a593Smuzhiyun     case 2:
6708*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
6709*4882a593Smuzhiyun         DECODE_PRINTF(",");
6710*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
6711*4882a593Smuzhiyun         srcval = fetch_data_byte(srcoffset);
6712*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6713*4882a593Smuzhiyun         TRACE_AND_STEP();
6714*4882a593Smuzhiyun         *destreg = srcval;
6715*4882a593Smuzhiyun         break;
6716*4882a593Smuzhiyun     case 3:                    /* register to register */
6717*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rh);
6718*4882a593Smuzhiyun         DECODE_PRINTF(",");
6719*4882a593Smuzhiyun         srcreg = DECODE_RM_BYTE_REGISTER(rl);
6720*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6721*4882a593Smuzhiyun         TRACE_AND_STEP();
6722*4882a593Smuzhiyun         *destreg = *srcreg;
6723*4882a593Smuzhiyun         break;
6724*4882a593Smuzhiyun     }
6725*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6726*4882a593Smuzhiyun     END_OF_INSTR();
6727*4882a593Smuzhiyun }
6728*4882a593Smuzhiyun 
6729*4882a593Smuzhiyun /****************************************************************************
6730*4882a593Smuzhiyun REMARKS:
6731*4882a593Smuzhiyun Handles opcode 0x8b
6732*4882a593Smuzhiyun ****************************************************************************/
6733*4882a593Smuzhiyun static void
x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED (op1))6734*4882a593Smuzhiyun x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6735*4882a593Smuzhiyun {
6736*4882a593Smuzhiyun     int mod, rl, rh;
6737*4882a593Smuzhiyun     uint srcoffset;
6738*4882a593Smuzhiyun 
6739*4882a593Smuzhiyun     START_OF_INSTR();
6740*4882a593Smuzhiyun     DECODE_PRINTF("MOV\t");
6741*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
6742*4882a593Smuzhiyun     switch (mod) {
6743*4882a593Smuzhiyun     case 0:
6744*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6745*4882a593Smuzhiyun             u32 *destreg;
6746*4882a593Smuzhiyun             u32 srcval;
6747*4882a593Smuzhiyun 
6748*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
6749*4882a593Smuzhiyun             DECODE_PRINTF(",");
6750*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
6751*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
6752*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6753*4882a593Smuzhiyun             TRACE_AND_STEP();
6754*4882a593Smuzhiyun             *destreg = srcval;
6755*4882a593Smuzhiyun         }
6756*4882a593Smuzhiyun         else {
6757*4882a593Smuzhiyun             u16 *destreg;
6758*4882a593Smuzhiyun             u16 srcval;
6759*4882a593Smuzhiyun 
6760*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
6761*4882a593Smuzhiyun             DECODE_PRINTF(",");
6762*4882a593Smuzhiyun             srcoffset = decode_rm00_address(rl);
6763*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
6764*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6765*4882a593Smuzhiyun             TRACE_AND_STEP();
6766*4882a593Smuzhiyun             *destreg = srcval;
6767*4882a593Smuzhiyun         }
6768*4882a593Smuzhiyun         break;
6769*4882a593Smuzhiyun     case 1:
6770*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6771*4882a593Smuzhiyun             u32 *destreg;
6772*4882a593Smuzhiyun             u32 srcval;
6773*4882a593Smuzhiyun 
6774*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
6775*4882a593Smuzhiyun             DECODE_PRINTF(",");
6776*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
6777*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
6778*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6779*4882a593Smuzhiyun             TRACE_AND_STEP();
6780*4882a593Smuzhiyun             *destreg = srcval;
6781*4882a593Smuzhiyun         }
6782*4882a593Smuzhiyun         else {
6783*4882a593Smuzhiyun             u16 *destreg;
6784*4882a593Smuzhiyun             u16 srcval;
6785*4882a593Smuzhiyun 
6786*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
6787*4882a593Smuzhiyun             DECODE_PRINTF(",");
6788*4882a593Smuzhiyun             srcoffset = decode_rm01_address(rl);
6789*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
6790*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6791*4882a593Smuzhiyun             TRACE_AND_STEP();
6792*4882a593Smuzhiyun             *destreg = srcval;
6793*4882a593Smuzhiyun         }
6794*4882a593Smuzhiyun         break;
6795*4882a593Smuzhiyun     case 2:
6796*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6797*4882a593Smuzhiyun             u32 *destreg;
6798*4882a593Smuzhiyun             u32 srcval;
6799*4882a593Smuzhiyun 
6800*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
6801*4882a593Smuzhiyun             DECODE_PRINTF(",");
6802*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
6803*4882a593Smuzhiyun             srcval = fetch_data_long(srcoffset);
6804*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6805*4882a593Smuzhiyun             TRACE_AND_STEP();
6806*4882a593Smuzhiyun             *destreg = srcval;
6807*4882a593Smuzhiyun         }
6808*4882a593Smuzhiyun         else {
6809*4882a593Smuzhiyun             u16 *destreg;
6810*4882a593Smuzhiyun             u16 srcval;
6811*4882a593Smuzhiyun 
6812*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
6813*4882a593Smuzhiyun             DECODE_PRINTF(",");
6814*4882a593Smuzhiyun             srcoffset = decode_rm10_address(rl);
6815*4882a593Smuzhiyun             srcval = fetch_data_word(srcoffset);
6816*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6817*4882a593Smuzhiyun             TRACE_AND_STEP();
6818*4882a593Smuzhiyun             *destreg = srcval;
6819*4882a593Smuzhiyun         }
6820*4882a593Smuzhiyun         break;
6821*4882a593Smuzhiyun     case 3:                    /* register to register */
6822*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6823*4882a593Smuzhiyun             u32 *destreg, *srcreg;
6824*4882a593Smuzhiyun 
6825*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rh);
6826*4882a593Smuzhiyun             DECODE_PRINTF(",");
6827*4882a593Smuzhiyun             srcreg = DECODE_RM_LONG_REGISTER(rl);
6828*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6829*4882a593Smuzhiyun             TRACE_AND_STEP();
6830*4882a593Smuzhiyun             *destreg = *srcreg;
6831*4882a593Smuzhiyun         }
6832*4882a593Smuzhiyun         else {
6833*4882a593Smuzhiyun             u16 *destreg, *srcreg;
6834*4882a593Smuzhiyun 
6835*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rh);
6836*4882a593Smuzhiyun             DECODE_PRINTF(",");
6837*4882a593Smuzhiyun             srcreg = DECODE_RM_WORD_REGISTER(rl);
6838*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6839*4882a593Smuzhiyun             TRACE_AND_STEP();
6840*4882a593Smuzhiyun             *destreg = *srcreg;
6841*4882a593Smuzhiyun         }
6842*4882a593Smuzhiyun         break;
6843*4882a593Smuzhiyun     }
6844*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6845*4882a593Smuzhiyun     END_OF_INSTR();
6846*4882a593Smuzhiyun }
6847*4882a593Smuzhiyun 
6848*4882a593Smuzhiyun /****************************************************************************
6849*4882a593Smuzhiyun REMARKS:
6850*4882a593Smuzhiyun Handles opcode 0x8c
6851*4882a593Smuzhiyun ****************************************************************************/
6852*4882a593Smuzhiyun static void
x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED (op1))6853*4882a593Smuzhiyun x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6854*4882a593Smuzhiyun {
6855*4882a593Smuzhiyun     int mod, rl, rh;
6856*4882a593Smuzhiyun     u16 *destreg, *srcreg;
6857*4882a593Smuzhiyun     uint destoffset;
6858*4882a593Smuzhiyun     u16 destval;
6859*4882a593Smuzhiyun 
6860*4882a593Smuzhiyun     START_OF_INSTR();
6861*4882a593Smuzhiyun     DECODE_PRINTF("MOV\t");
6862*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
6863*4882a593Smuzhiyun     switch (mod) {
6864*4882a593Smuzhiyun     case 0:
6865*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
6866*4882a593Smuzhiyun         DECODE_PRINTF(",");
6867*4882a593Smuzhiyun         srcreg = decode_rm_seg_register(rh);
6868*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6869*4882a593Smuzhiyun         TRACE_AND_STEP();
6870*4882a593Smuzhiyun         destval = *srcreg;
6871*4882a593Smuzhiyun         store_data_word(destoffset, destval);
6872*4882a593Smuzhiyun         break;
6873*4882a593Smuzhiyun     case 1:
6874*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
6875*4882a593Smuzhiyun         DECODE_PRINTF(",");
6876*4882a593Smuzhiyun         srcreg = decode_rm_seg_register(rh);
6877*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6878*4882a593Smuzhiyun         TRACE_AND_STEP();
6879*4882a593Smuzhiyun         destval = *srcreg;
6880*4882a593Smuzhiyun         store_data_word(destoffset, destval);
6881*4882a593Smuzhiyun         break;
6882*4882a593Smuzhiyun     case 2:
6883*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
6884*4882a593Smuzhiyun         DECODE_PRINTF(",");
6885*4882a593Smuzhiyun         srcreg = decode_rm_seg_register(rh);
6886*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6887*4882a593Smuzhiyun         TRACE_AND_STEP();
6888*4882a593Smuzhiyun         destval = *srcreg;
6889*4882a593Smuzhiyun         store_data_word(destoffset, destval);
6890*4882a593Smuzhiyun         break;
6891*4882a593Smuzhiyun     case 3:                    /* register to register */
6892*4882a593Smuzhiyun         destreg = DECODE_RM_WORD_REGISTER(rl);
6893*4882a593Smuzhiyun         DECODE_PRINTF(",");
6894*4882a593Smuzhiyun         srcreg = decode_rm_seg_register(rh);
6895*4882a593Smuzhiyun         DECODE_PRINTF("\n");
6896*4882a593Smuzhiyun         TRACE_AND_STEP();
6897*4882a593Smuzhiyun         *destreg = *srcreg;
6898*4882a593Smuzhiyun         break;
6899*4882a593Smuzhiyun     }
6900*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6901*4882a593Smuzhiyun     END_OF_INSTR();
6902*4882a593Smuzhiyun }
6903*4882a593Smuzhiyun 
6904*4882a593Smuzhiyun /****************************************************************************
6905*4882a593Smuzhiyun REMARKS:
6906*4882a593Smuzhiyun Handles opcode 0x8d
6907*4882a593Smuzhiyun ****************************************************************************/
6908*4882a593Smuzhiyun static void
x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED (op1))6909*4882a593Smuzhiyun x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6910*4882a593Smuzhiyun {
6911*4882a593Smuzhiyun     int mod, rl, rh;
6912*4882a593Smuzhiyun     uint destoffset;
6913*4882a593Smuzhiyun 
6914*4882a593Smuzhiyun     START_OF_INSTR();
6915*4882a593Smuzhiyun     DECODE_PRINTF("LEA\t");
6916*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
6917*4882a593Smuzhiyun     switch (mod) {
6918*4882a593Smuzhiyun     case 0:
6919*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6920*4882a593Smuzhiyun             u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6921*4882a593Smuzhiyun 
6922*4882a593Smuzhiyun             DECODE_PRINTF(",");
6923*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
6924*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6925*4882a593Smuzhiyun             TRACE_AND_STEP();
6926*4882a593Smuzhiyun             *srcreg = (u32) destoffset;
6927*4882a593Smuzhiyun         }
6928*4882a593Smuzhiyun         else {
6929*4882a593Smuzhiyun             u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6930*4882a593Smuzhiyun 
6931*4882a593Smuzhiyun             DECODE_PRINTF(",");
6932*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
6933*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6934*4882a593Smuzhiyun             TRACE_AND_STEP();
6935*4882a593Smuzhiyun             *srcreg = (u16) destoffset;
6936*4882a593Smuzhiyun         }
6937*4882a593Smuzhiyun         break;
6938*4882a593Smuzhiyun     case 1:
6939*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6940*4882a593Smuzhiyun             u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6941*4882a593Smuzhiyun 
6942*4882a593Smuzhiyun             DECODE_PRINTF(",");
6943*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
6944*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6945*4882a593Smuzhiyun             TRACE_AND_STEP();
6946*4882a593Smuzhiyun             *srcreg = (u32) destoffset;
6947*4882a593Smuzhiyun         }
6948*4882a593Smuzhiyun         else {
6949*4882a593Smuzhiyun             u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6950*4882a593Smuzhiyun 
6951*4882a593Smuzhiyun             DECODE_PRINTF(",");
6952*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
6953*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6954*4882a593Smuzhiyun             TRACE_AND_STEP();
6955*4882a593Smuzhiyun             *srcreg = (u16) destoffset;
6956*4882a593Smuzhiyun         }
6957*4882a593Smuzhiyun         break;
6958*4882a593Smuzhiyun     case 2:
6959*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6960*4882a593Smuzhiyun             u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6961*4882a593Smuzhiyun 
6962*4882a593Smuzhiyun             DECODE_PRINTF(",");
6963*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
6964*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6965*4882a593Smuzhiyun             TRACE_AND_STEP();
6966*4882a593Smuzhiyun             *srcreg = (u32) destoffset;
6967*4882a593Smuzhiyun         }
6968*4882a593Smuzhiyun         else {
6969*4882a593Smuzhiyun             u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6970*4882a593Smuzhiyun 
6971*4882a593Smuzhiyun             DECODE_PRINTF(",");
6972*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
6973*4882a593Smuzhiyun             DECODE_PRINTF("\n");
6974*4882a593Smuzhiyun             TRACE_AND_STEP();
6975*4882a593Smuzhiyun             *srcreg = (u16) destoffset;
6976*4882a593Smuzhiyun         }
6977*4882a593Smuzhiyun         break;
6978*4882a593Smuzhiyun     case 3:                    /* register to register */
6979*4882a593Smuzhiyun         /* undefined.  Do nothing. */
6980*4882a593Smuzhiyun         break;
6981*4882a593Smuzhiyun     }
6982*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
6983*4882a593Smuzhiyun     END_OF_INSTR();
6984*4882a593Smuzhiyun }
6985*4882a593Smuzhiyun 
6986*4882a593Smuzhiyun /****************************************************************************
6987*4882a593Smuzhiyun REMARKS:
6988*4882a593Smuzhiyun Handles opcode 0x8e
6989*4882a593Smuzhiyun ****************************************************************************/
6990*4882a593Smuzhiyun static void
x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED (op1))6991*4882a593Smuzhiyun x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6992*4882a593Smuzhiyun {
6993*4882a593Smuzhiyun     int mod, rl, rh;
6994*4882a593Smuzhiyun     u16 *destreg, *srcreg;
6995*4882a593Smuzhiyun     uint srcoffset;
6996*4882a593Smuzhiyun     u16 srcval;
6997*4882a593Smuzhiyun 
6998*4882a593Smuzhiyun     START_OF_INSTR();
6999*4882a593Smuzhiyun     DECODE_PRINTF("MOV\t");
7000*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
7001*4882a593Smuzhiyun     switch (mod) {
7002*4882a593Smuzhiyun     case 0:
7003*4882a593Smuzhiyun         destreg = decode_rm_seg_register(rh);
7004*4882a593Smuzhiyun         DECODE_PRINTF(",");
7005*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
7006*4882a593Smuzhiyun         srcval = fetch_data_word(srcoffset);
7007*4882a593Smuzhiyun         DECODE_PRINTF("\n");
7008*4882a593Smuzhiyun         TRACE_AND_STEP();
7009*4882a593Smuzhiyun         *destreg = srcval;
7010*4882a593Smuzhiyun         break;
7011*4882a593Smuzhiyun     case 1:
7012*4882a593Smuzhiyun         destreg = decode_rm_seg_register(rh);
7013*4882a593Smuzhiyun         DECODE_PRINTF(",");
7014*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
7015*4882a593Smuzhiyun         srcval = fetch_data_word(srcoffset);
7016*4882a593Smuzhiyun         DECODE_PRINTF("\n");
7017*4882a593Smuzhiyun         TRACE_AND_STEP();
7018*4882a593Smuzhiyun         *destreg = srcval;
7019*4882a593Smuzhiyun         break;
7020*4882a593Smuzhiyun     case 2:
7021*4882a593Smuzhiyun         destreg = decode_rm_seg_register(rh);
7022*4882a593Smuzhiyun         DECODE_PRINTF(",");
7023*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
7024*4882a593Smuzhiyun         srcval = fetch_data_word(srcoffset);
7025*4882a593Smuzhiyun         DECODE_PRINTF("\n");
7026*4882a593Smuzhiyun         TRACE_AND_STEP();
7027*4882a593Smuzhiyun         *destreg = srcval;
7028*4882a593Smuzhiyun         break;
7029*4882a593Smuzhiyun     case 3:                    /* register to register */
7030*4882a593Smuzhiyun         destreg = decode_rm_seg_register(rh);
7031*4882a593Smuzhiyun         DECODE_PRINTF(",");
7032*4882a593Smuzhiyun         srcreg = DECODE_RM_WORD_REGISTER(rl);
7033*4882a593Smuzhiyun         DECODE_PRINTF("\n");
7034*4882a593Smuzhiyun         TRACE_AND_STEP();
7035*4882a593Smuzhiyun         *destreg = *srcreg;
7036*4882a593Smuzhiyun         break;
7037*4882a593Smuzhiyun     }
7038*4882a593Smuzhiyun     /*
7039*4882a593Smuzhiyun      * Clean up, and reset all the R_xSP pointers to the correct
7040*4882a593Smuzhiyun      * locations.  This is about 3x too much overhead (doing all the
7041*4882a593Smuzhiyun      * segreg ptrs when only one is needed, but this instruction
7042*4882a593Smuzhiyun      * *cannot* be that common, and this isn't too much work anyway.
7043*4882a593Smuzhiyun      */
7044*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7045*4882a593Smuzhiyun     END_OF_INSTR();
7046*4882a593Smuzhiyun }
7047*4882a593Smuzhiyun 
7048*4882a593Smuzhiyun /****************************************************************************
7049*4882a593Smuzhiyun REMARKS:
7050*4882a593Smuzhiyun Handles opcode 0x8f
7051*4882a593Smuzhiyun ****************************************************************************/
7052*4882a593Smuzhiyun static void
x86emuOp_pop_RM(u8 X86EMU_UNUSED (op1))7053*4882a593Smuzhiyun x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
7054*4882a593Smuzhiyun {
7055*4882a593Smuzhiyun     int mod, rl, rh;
7056*4882a593Smuzhiyun     uint destoffset;
7057*4882a593Smuzhiyun 
7058*4882a593Smuzhiyun     START_OF_INSTR();
7059*4882a593Smuzhiyun     DECODE_PRINTF("POP\t");
7060*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
7061*4882a593Smuzhiyun     if (rh != 0) {
7062*4882a593Smuzhiyun         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
7063*4882a593Smuzhiyun         HALT_SYS();
7064*4882a593Smuzhiyun     }
7065*4882a593Smuzhiyun     switch (mod) {
7066*4882a593Smuzhiyun     case 0:
7067*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7068*4882a593Smuzhiyun             u32 destval;
7069*4882a593Smuzhiyun 
7070*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
7071*4882a593Smuzhiyun             DECODE_PRINTF("\n");
7072*4882a593Smuzhiyun             TRACE_AND_STEP();
7073*4882a593Smuzhiyun             destval = pop_long();
7074*4882a593Smuzhiyun             store_data_long(destoffset, destval);
7075*4882a593Smuzhiyun         }
7076*4882a593Smuzhiyun         else {
7077*4882a593Smuzhiyun             u16 destval;
7078*4882a593Smuzhiyun 
7079*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
7080*4882a593Smuzhiyun             DECODE_PRINTF("\n");
7081*4882a593Smuzhiyun             TRACE_AND_STEP();
7082*4882a593Smuzhiyun             destval = pop_word();
7083*4882a593Smuzhiyun             store_data_word(destoffset, destval);
7084*4882a593Smuzhiyun         }
7085*4882a593Smuzhiyun         break;
7086*4882a593Smuzhiyun     case 1:
7087*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7088*4882a593Smuzhiyun             u32 destval;
7089*4882a593Smuzhiyun 
7090*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
7091*4882a593Smuzhiyun             DECODE_PRINTF("\n");
7092*4882a593Smuzhiyun             TRACE_AND_STEP();
7093*4882a593Smuzhiyun             destval = pop_long();
7094*4882a593Smuzhiyun             store_data_long(destoffset, destval);
7095*4882a593Smuzhiyun         }
7096*4882a593Smuzhiyun         else {
7097*4882a593Smuzhiyun             u16 destval;
7098*4882a593Smuzhiyun 
7099*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
7100*4882a593Smuzhiyun             DECODE_PRINTF("\n");
7101*4882a593Smuzhiyun             TRACE_AND_STEP();
7102*4882a593Smuzhiyun             destval = pop_word();
7103*4882a593Smuzhiyun             store_data_word(destoffset, destval);
7104*4882a593Smuzhiyun         }
7105*4882a593Smuzhiyun         break;
7106*4882a593Smuzhiyun     case 2:
7107*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7108*4882a593Smuzhiyun             u32 destval;
7109*4882a593Smuzhiyun 
7110*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
7111*4882a593Smuzhiyun             DECODE_PRINTF("\n");
7112*4882a593Smuzhiyun             TRACE_AND_STEP();
7113*4882a593Smuzhiyun             destval = pop_long();
7114*4882a593Smuzhiyun             store_data_long(destoffset, destval);
7115*4882a593Smuzhiyun         }
7116*4882a593Smuzhiyun         else {
7117*4882a593Smuzhiyun             u16 destval;
7118*4882a593Smuzhiyun 
7119*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
7120*4882a593Smuzhiyun             DECODE_PRINTF("\n");
7121*4882a593Smuzhiyun             TRACE_AND_STEP();
7122*4882a593Smuzhiyun             destval = pop_word();
7123*4882a593Smuzhiyun             store_data_word(destoffset, destval);
7124*4882a593Smuzhiyun         }
7125*4882a593Smuzhiyun         break;
7126*4882a593Smuzhiyun     case 3:                    /* register to register */
7127*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7128*4882a593Smuzhiyun             u32 *destreg;
7129*4882a593Smuzhiyun 
7130*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
7131*4882a593Smuzhiyun             DECODE_PRINTF("\n");
7132*4882a593Smuzhiyun             TRACE_AND_STEP();
7133*4882a593Smuzhiyun             *destreg = pop_long();
7134*4882a593Smuzhiyun         }
7135*4882a593Smuzhiyun         else {
7136*4882a593Smuzhiyun             u16 *destreg;
7137*4882a593Smuzhiyun 
7138*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
7139*4882a593Smuzhiyun             DECODE_PRINTF("\n");
7140*4882a593Smuzhiyun             TRACE_AND_STEP();
7141*4882a593Smuzhiyun             *destreg = pop_word();
7142*4882a593Smuzhiyun         }
7143*4882a593Smuzhiyun         break;
7144*4882a593Smuzhiyun     }
7145*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7146*4882a593Smuzhiyun     END_OF_INSTR();
7147*4882a593Smuzhiyun }
7148*4882a593Smuzhiyun 
7149*4882a593Smuzhiyun /****************************************************************************
7150*4882a593Smuzhiyun REMARKS:
7151*4882a593Smuzhiyun Handles opcode 0x90
7152*4882a593Smuzhiyun ****************************************************************************/
7153*4882a593Smuzhiyun static void
x86emuOp_nop(u8 X86EMU_UNUSED (op1))7154*4882a593Smuzhiyun x86emuOp_nop(u8 X86EMU_UNUSED(op1))
7155*4882a593Smuzhiyun {
7156*4882a593Smuzhiyun     START_OF_INSTR();
7157*4882a593Smuzhiyun     DECODE_PRINTF("NOP\n");
7158*4882a593Smuzhiyun     TRACE_AND_STEP();
7159*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7160*4882a593Smuzhiyun     END_OF_INSTR();
7161*4882a593Smuzhiyun }
7162*4882a593Smuzhiyun 
7163*4882a593Smuzhiyun /****************************************************************************
7164*4882a593Smuzhiyun REMARKS:
7165*4882a593Smuzhiyun Handles opcode 0x91
7166*4882a593Smuzhiyun ****************************************************************************/
7167*4882a593Smuzhiyun static void
x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED (op1))7168*4882a593Smuzhiyun x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
7169*4882a593Smuzhiyun {
7170*4882a593Smuzhiyun     u32 tmp;
7171*4882a593Smuzhiyun 
7172*4882a593Smuzhiyun     START_OF_INSTR();
7173*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7174*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tEAX,ECX\n");
7175*4882a593Smuzhiyun     }
7176*4882a593Smuzhiyun     else {
7177*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tAX,CX\n");
7178*4882a593Smuzhiyun     }
7179*4882a593Smuzhiyun     TRACE_AND_STEP();
7180*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7181*4882a593Smuzhiyun         tmp = M.x86.R_EAX;
7182*4882a593Smuzhiyun         M.x86.R_EAX = M.x86.R_ECX;
7183*4882a593Smuzhiyun         M.x86.R_ECX = tmp;
7184*4882a593Smuzhiyun     }
7185*4882a593Smuzhiyun     else {
7186*4882a593Smuzhiyun         tmp = M.x86.R_AX;
7187*4882a593Smuzhiyun         M.x86.R_AX = M.x86.R_CX;
7188*4882a593Smuzhiyun         M.x86.R_CX = (u16) tmp;
7189*4882a593Smuzhiyun     }
7190*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7191*4882a593Smuzhiyun     END_OF_INSTR();
7192*4882a593Smuzhiyun }
7193*4882a593Smuzhiyun 
7194*4882a593Smuzhiyun /****************************************************************************
7195*4882a593Smuzhiyun REMARKS:
7196*4882a593Smuzhiyun Handles opcode 0x92
7197*4882a593Smuzhiyun ****************************************************************************/
7198*4882a593Smuzhiyun static void
x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED (op1))7199*4882a593Smuzhiyun x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
7200*4882a593Smuzhiyun {
7201*4882a593Smuzhiyun     u32 tmp;
7202*4882a593Smuzhiyun 
7203*4882a593Smuzhiyun     START_OF_INSTR();
7204*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7205*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tEAX,EDX\n");
7206*4882a593Smuzhiyun     }
7207*4882a593Smuzhiyun     else {
7208*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tAX,DX\n");
7209*4882a593Smuzhiyun     }
7210*4882a593Smuzhiyun     TRACE_AND_STEP();
7211*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7212*4882a593Smuzhiyun         tmp = M.x86.R_EAX;
7213*4882a593Smuzhiyun         M.x86.R_EAX = M.x86.R_EDX;
7214*4882a593Smuzhiyun         M.x86.R_EDX = tmp;
7215*4882a593Smuzhiyun     }
7216*4882a593Smuzhiyun     else {
7217*4882a593Smuzhiyun         tmp = M.x86.R_AX;
7218*4882a593Smuzhiyun         M.x86.R_AX = M.x86.R_DX;
7219*4882a593Smuzhiyun         M.x86.R_DX = (u16) tmp;
7220*4882a593Smuzhiyun     }
7221*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7222*4882a593Smuzhiyun     END_OF_INSTR();
7223*4882a593Smuzhiyun }
7224*4882a593Smuzhiyun 
7225*4882a593Smuzhiyun /****************************************************************************
7226*4882a593Smuzhiyun REMARKS:
7227*4882a593Smuzhiyun Handles opcode 0x93
7228*4882a593Smuzhiyun ****************************************************************************/
7229*4882a593Smuzhiyun static void
x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED (op1))7230*4882a593Smuzhiyun x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
7231*4882a593Smuzhiyun {
7232*4882a593Smuzhiyun     u32 tmp;
7233*4882a593Smuzhiyun 
7234*4882a593Smuzhiyun     START_OF_INSTR();
7235*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7236*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tEAX,EBX\n");
7237*4882a593Smuzhiyun     }
7238*4882a593Smuzhiyun     else {
7239*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tAX,BX\n");
7240*4882a593Smuzhiyun     }
7241*4882a593Smuzhiyun     TRACE_AND_STEP();
7242*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7243*4882a593Smuzhiyun         tmp = M.x86.R_EAX;
7244*4882a593Smuzhiyun         M.x86.R_EAX = M.x86.R_EBX;
7245*4882a593Smuzhiyun         M.x86.R_EBX = tmp;
7246*4882a593Smuzhiyun     }
7247*4882a593Smuzhiyun     else {
7248*4882a593Smuzhiyun         tmp = M.x86.R_AX;
7249*4882a593Smuzhiyun         M.x86.R_AX = M.x86.R_BX;
7250*4882a593Smuzhiyun         M.x86.R_BX = (u16) tmp;
7251*4882a593Smuzhiyun     }
7252*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7253*4882a593Smuzhiyun     END_OF_INSTR();
7254*4882a593Smuzhiyun }
7255*4882a593Smuzhiyun 
7256*4882a593Smuzhiyun /****************************************************************************
7257*4882a593Smuzhiyun REMARKS:
7258*4882a593Smuzhiyun Handles opcode 0x94
7259*4882a593Smuzhiyun ****************************************************************************/
7260*4882a593Smuzhiyun static void
x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED (op1))7261*4882a593Smuzhiyun x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
7262*4882a593Smuzhiyun {
7263*4882a593Smuzhiyun     u32 tmp;
7264*4882a593Smuzhiyun 
7265*4882a593Smuzhiyun     START_OF_INSTR();
7266*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7267*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tEAX,ESP\n");
7268*4882a593Smuzhiyun     }
7269*4882a593Smuzhiyun     else {
7270*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tAX,SP\n");
7271*4882a593Smuzhiyun     }
7272*4882a593Smuzhiyun     TRACE_AND_STEP();
7273*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7274*4882a593Smuzhiyun         tmp = M.x86.R_EAX;
7275*4882a593Smuzhiyun         M.x86.R_EAX = M.x86.R_ESP;
7276*4882a593Smuzhiyun         M.x86.R_ESP = tmp;
7277*4882a593Smuzhiyun     }
7278*4882a593Smuzhiyun     else {
7279*4882a593Smuzhiyun         tmp = M.x86.R_AX;
7280*4882a593Smuzhiyun         M.x86.R_AX = M.x86.R_SP;
7281*4882a593Smuzhiyun         M.x86.R_SP = (u16) tmp;
7282*4882a593Smuzhiyun     }
7283*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7284*4882a593Smuzhiyun     END_OF_INSTR();
7285*4882a593Smuzhiyun }
7286*4882a593Smuzhiyun 
7287*4882a593Smuzhiyun /****************************************************************************
7288*4882a593Smuzhiyun REMARKS:
7289*4882a593Smuzhiyun Handles opcode 0x95
7290*4882a593Smuzhiyun ****************************************************************************/
7291*4882a593Smuzhiyun static void
x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED (op1))7292*4882a593Smuzhiyun x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
7293*4882a593Smuzhiyun {
7294*4882a593Smuzhiyun     u32 tmp;
7295*4882a593Smuzhiyun 
7296*4882a593Smuzhiyun     START_OF_INSTR();
7297*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7298*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tEAX,EBP\n");
7299*4882a593Smuzhiyun     }
7300*4882a593Smuzhiyun     else {
7301*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tAX,BP\n");
7302*4882a593Smuzhiyun     }
7303*4882a593Smuzhiyun     TRACE_AND_STEP();
7304*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7305*4882a593Smuzhiyun         tmp = M.x86.R_EAX;
7306*4882a593Smuzhiyun         M.x86.R_EAX = M.x86.R_EBP;
7307*4882a593Smuzhiyun         M.x86.R_EBP = tmp;
7308*4882a593Smuzhiyun     }
7309*4882a593Smuzhiyun     else {
7310*4882a593Smuzhiyun         tmp = M.x86.R_AX;
7311*4882a593Smuzhiyun         M.x86.R_AX = M.x86.R_BP;
7312*4882a593Smuzhiyun         M.x86.R_BP = (u16) tmp;
7313*4882a593Smuzhiyun     }
7314*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7315*4882a593Smuzhiyun     END_OF_INSTR();
7316*4882a593Smuzhiyun }
7317*4882a593Smuzhiyun 
7318*4882a593Smuzhiyun /****************************************************************************
7319*4882a593Smuzhiyun REMARKS:
7320*4882a593Smuzhiyun Handles opcode 0x96
7321*4882a593Smuzhiyun ****************************************************************************/
7322*4882a593Smuzhiyun static void
x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED (op1))7323*4882a593Smuzhiyun x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
7324*4882a593Smuzhiyun {
7325*4882a593Smuzhiyun     u32 tmp;
7326*4882a593Smuzhiyun 
7327*4882a593Smuzhiyun     START_OF_INSTR();
7328*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7329*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tEAX,ESI\n");
7330*4882a593Smuzhiyun     }
7331*4882a593Smuzhiyun     else {
7332*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tAX,SI\n");
7333*4882a593Smuzhiyun     }
7334*4882a593Smuzhiyun     TRACE_AND_STEP();
7335*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7336*4882a593Smuzhiyun         tmp = M.x86.R_EAX;
7337*4882a593Smuzhiyun         M.x86.R_EAX = M.x86.R_ESI;
7338*4882a593Smuzhiyun         M.x86.R_ESI = tmp;
7339*4882a593Smuzhiyun     }
7340*4882a593Smuzhiyun     else {
7341*4882a593Smuzhiyun         tmp = M.x86.R_AX;
7342*4882a593Smuzhiyun         M.x86.R_AX = M.x86.R_SI;
7343*4882a593Smuzhiyun         M.x86.R_SI = (u16) tmp;
7344*4882a593Smuzhiyun     }
7345*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7346*4882a593Smuzhiyun     END_OF_INSTR();
7347*4882a593Smuzhiyun }
7348*4882a593Smuzhiyun 
7349*4882a593Smuzhiyun /****************************************************************************
7350*4882a593Smuzhiyun REMARKS:
7351*4882a593Smuzhiyun Handles opcode 0x97
7352*4882a593Smuzhiyun ****************************************************************************/
7353*4882a593Smuzhiyun static void
x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED (op1))7354*4882a593Smuzhiyun x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
7355*4882a593Smuzhiyun {
7356*4882a593Smuzhiyun     u32 tmp;
7357*4882a593Smuzhiyun 
7358*4882a593Smuzhiyun     START_OF_INSTR();
7359*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7360*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tEAX,EDI\n");
7361*4882a593Smuzhiyun     }
7362*4882a593Smuzhiyun     else {
7363*4882a593Smuzhiyun         DECODE_PRINTF("XCHG\tAX,DI\n");
7364*4882a593Smuzhiyun     }
7365*4882a593Smuzhiyun     TRACE_AND_STEP();
7366*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7367*4882a593Smuzhiyun         tmp = M.x86.R_EAX;
7368*4882a593Smuzhiyun         M.x86.R_EAX = M.x86.R_EDI;
7369*4882a593Smuzhiyun         M.x86.R_EDI = tmp;
7370*4882a593Smuzhiyun     }
7371*4882a593Smuzhiyun     else {
7372*4882a593Smuzhiyun         tmp = M.x86.R_AX;
7373*4882a593Smuzhiyun         M.x86.R_AX = M.x86.R_DI;
7374*4882a593Smuzhiyun         M.x86.R_DI = (u16) tmp;
7375*4882a593Smuzhiyun     }
7376*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7377*4882a593Smuzhiyun     END_OF_INSTR();
7378*4882a593Smuzhiyun }
7379*4882a593Smuzhiyun 
7380*4882a593Smuzhiyun /****************************************************************************
7381*4882a593Smuzhiyun REMARKS:
7382*4882a593Smuzhiyun Handles opcode 0x98
7383*4882a593Smuzhiyun ****************************************************************************/
7384*4882a593Smuzhiyun static void
x86emuOp_cbw(u8 X86EMU_UNUSED (op1))7385*4882a593Smuzhiyun x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
7386*4882a593Smuzhiyun {
7387*4882a593Smuzhiyun     START_OF_INSTR();
7388*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7389*4882a593Smuzhiyun         DECODE_PRINTF("CWDE\n");
7390*4882a593Smuzhiyun     }
7391*4882a593Smuzhiyun     else {
7392*4882a593Smuzhiyun         DECODE_PRINTF("CBW\n");
7393*4882a593Smuzhiyun     }
7394*4882a593Smuzhiyun     TRACE_AND_STEP();
7395*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7396*4882a593Smuzhiyun         if (M.x86.R_AX & 0x8000) {
7397*4882a593Smuzhiyun             M.x86.R_EAX |= 0xffff0000;
7398*4882a593Smuzhiyun         }
7399*4882a593Smuzhiyun         else {
7400*4882a593Smuzhiyun             M.x86.R_EAX &= 0x0000ffff;
7401*4882a593Smuzhiyun         }
7402*4882a593Smuzhiyun     }
7403*4882a593Smuzhiyun     else {
7404*4882a593Smuzhiyun         if (M.x86.R_AL & 0x80) {
7405*4882a593Smuzhiyun             M.x86.R_AH = 0xff;
7406*4882a593Smuzhiyun         }
7407*4882a593Smuzhiyun         else {
7408*4882a593Smuzhiyun             M.x86.R_AH = 0x0;
7409*4882a593Smuzhiyun         }
7410*4882a593Smuzhiyun     }
7411*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7412*4882a593Smuzhiyun     END_OF_INSTR();
7413*4882a593Smuzhiyun }
7414*4882a593Smuzhiyun 
7415*4882a593Smuzhiyun /****************************************************************************
7416*4882a593Smuzhiyun REMARKS:
7417*4882a593Smuzhiyun Handles opcode 0x99
7418*4882a593Smuzhiyun ****************************************************************************/
7419*4882a593Smuzhiyun static void
x86emuOp_cwd(u8 X86EMU_UNUSED (op1))7420*4882a593Smuzhiyun x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7421*4882a593Smuzhiyun {
7422*4882a593Smuzhiyun     START_OF_INSTR();
7423*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7424*4882a593Smuzhiyun         DECODE_PRINTF("CDQ\n");
7425*4882a593Smuzhiyun     }
7426*4882a593Smuzhiyun     else {
7427*4882a593Smuzhiyun         DECODE_PRINTF("CWD\n");
7428*4882a593Smuzhiyun     }
7429*4882a593Smuzhiyun     DECODE_PRINTF("CWD\n");
7430*4882a593Smuzhiyun     TRACE_AND_STEP();
7431*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7432*4882a593Smuzhiyun         if (M.x86.R_EAX & 0x80000000) {
7433*4882a593Smuzhiyun             M.x86.R_EDX = 0xffffffff;
7434*4882a593Smuzhiyun         }
7435*4882a593Smuzhiyun         else {
7436*4882a593Smuzhiyun             M.x86.R_EDX = 0x0;
7437*4882a593Smuzhiyun         }
7438*4882a593Smuzhiyun     }
7439*4882a593Smuzhiyun     else {
7440*4882a593Smuzhiyun         if (M.x86.R_AX & 0x8000) {
7441*4882a593Smuzhiyun             M.x86.R_DX = 0xffff;
7442*4882a593Smuzhiyun         }
7443*4882a593Smuzhiyun         else {
7444*4882a593Smuzhiyun             M.x86.R_DX = 0x0;
7445*4882a593Smuzhiyun         }
7446*4882a593Smuzhiyun     }
7447*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7448*4882a593Smuzhiyun     END_OF_INSTR();
7449*4882a593Smuzhiyun }
7450*4882a593Smuzhiyun 
7451*4882a593Smuzhiyun /****************************************************************************
7452*4882a593Smuzhiyun REMARKS:
7453*4882a593Smuzhiyun Handles opcode 0x9a
7454*4882a593Smuzhiyun ****************************************************************************/
7455*4882a593Smuzhiyun static void
x86emuOp_call_far_IMM(u8 X86EMU_UNUSED (op1))7456*4882a593Smuzhiyun x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7457*4882a593Smuzhiyun {
7458*4882a593Smuzhiyun     u32 farseg, faroff;
7459*4882a593Smuzhiyun 
7460*4882a593Smuzhiyun     START_OF_INSTR();
7461*4882a593Smuzhiyun     DECODE_PRINTF("CALL\t");
7462*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7463*4882a593Smuzhiyun         faroff = fetch_long_imm();
7464*4882a593Smuzhiyun         farseg = fetch_word_imm();
7465*4882a593Smuzhiyun     }
7466*4882a593Smuzhiyun     else {
7467*4882a593Smuzhiyun         faroff = fetch_word_imm();
7468*4882a593Smuzhiyun         farseg = fetch_word_imm();
7469*4882a593Smuzhiyun     }
7470*4882a593Smuzhiyun     DECODE_PRINTF2("%04x:", farseg);
7471*4882a593Smuzhiyun     DECODE_PRINTF2("%04x\n", faroff);
7472*4882a593Smuzhiyun     CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7473*4882a593Smuzhiyun 
7474*4882a593Smuzhiyun     /* XXX
7475*4882a593Smuzhiyun      *
7476*4882a593Smuzhiyun      * Hooked interrupt vectors calling into our "BIOS" will cause
7477*4882a593Smuzhiyun      * problems unless all intersegment stuff is checked for BIOS
7478*4882a593Smuzhiyun      * access.  Check needed here.  For moment, let it alone.
7479*4882a593Smuzhiyun      */
7480*4882a593Smuzhiyun     TRACE_AND_STEP();
7481*4882a593Smuzhiyun     push_word(M.x86.R_CS);
7482*4882a593Smuzhiyun     M.x86.R_CS = farseg;
7483*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7484*4882a593Smuzhiyun         push_long(M.x86.R_EIP);
7485*4882a593Smuzhiyun     }
7486*4882a593Smuzhiyun     else {
7487*4882a593Smuzhiyun         push_word(M.x86.R_IP);
7488*4882a593Smuzhiyun     }
7489*4882a593Smuzhiyun     M.x86.R_EIP = faroff & 0xffff;
7490*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7491*4882a593Smuzhiyun     END_OF_INSTR();
7492*4882a593Smuzhiyun }
7493*4882a593Smuzhiyun 
7494*4882a593Smuzhiyun /****************************************************************************
7495*4882a593Smuzhiyun REMARKS:
7496*4882a593Smuzhiyun Handles opcode 0x9b
7497*4882a593Smuzhiyun ****************************************************************************/
7498*4882a593Smuzhiyun static void
x86emuOp_wait(u8 X86EMU_UNUSED (op1))7499*4882a593Smuzhiyun x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7500*4882a593Smuzhiyun {
7501*4882a593Smuzhiyun     START_OF_INSTR();
7502*4882a593Smuzhiyun     DECODE_PRINTF("WAIT");
7503*4882a593Smuzhiyun     TRACE_AND_STEP();
7504*4882a593Smuzhiyun     /* NADA.  */
7505*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7506*4882a593Smuzhiyun     END_OF_INSTR();
7507*4882a593Smuzhiyun }
7508*4882a593Smuzhiyun 
7509*4882a593Smuzhiyun /****************************************************************************
7510*4882a593Smuzhiyun REMARKS:
7511*4882a593Smuzhiyun Handles opcode 0x9c
7512*4882a593Smuzhiyun ****************************************************************************/
7513*4882a593Smuzhiyun static void
x86emuOp_pushf_word(u8 X86EMU_UNUSED (op1))7514*4882a593Smuzhiyun x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7515*4882a593Smuzhiyun {
7516*4882a593Smuzhiyun     u32 flags;
7517*4882a593Smuzhiyun 
7518*4882a593Smuzhiyun     START_OF_INSTR();
7519*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7520*4882a593Smuzhiyun         DECODE_PRINTF("PUSHFD\n");
7521*4882a593Smuzhiyun     }
7522*4882a593Smuzhiyun     else {
7523*4882a593Smuzhiyun         DECODE_PRINTF("PUSHF\n");
7524*4882a593Smuzhiyun     }
7525*4882a593Smuzhiyun     TRACE_AND_STEP();
7526*4882a593Smuzhiyun 
7527*4882a593Smuzhiyun     /* clear out *all* bits not representing flags, and turn on real bits */
7528*4882a593Smuzhiyun     flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7529*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7530*4882a593Smuzhiyun         push_long(flags);
7531*4882a593Smuzhiyun     }
7532*4882a593Smuzhiyun     else {
7533*4882a593Smuzhiyun         push_word((u16) flags);
7534*4882a593Smuzhiyun     }
7535*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7536*4882a593Smuzhiyun     END_OF_INSTR();
7537*4882a593Smuzhiyun }
7538*4882a593Smuzhiyun 
7539*4882a593Smuzhiyun /****************************************************************************
7540*4882a593Smuzhiyun REMARKS:
7541*4882a593Smuzhiyun Handles opcode 0x9d
7542*4882a593Smuzhiyun ****************************************************************************/
7543*4882a593Smuzhiyun static void
x86emuOp_popf_word(u8 X86EMU_UNUSED (op1))7544*4882a593Smuzhiyun x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7545*4882a593Smuzhiyun {
7546*4882a593Smuzhiyun     START_OF_INSTR();
7547*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7548*4882a593Smuzhiyun         DECODE_PRINTF("POPFD\n");
7549*4882a593Smuzhiyun     }
7550*4882a593Smuzhiyun     else {
7551*4882a593Smuzhiyun         DECODE_PRINTF("POPF\n");
7552*4882a593Smuzhiyun     }
7553*4882a593Smuzhiyun     TRACE_AND_STEP();
7554*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7555*4882a593Smuzhiyun         M.x86.R_EFLG = pop_long();
7556*4882a593Smuzhiyun     }
7557*4882a593Smuzhiyun     else {
7558*4882a593Smuzhiyun         M.x86.R_FLG = pop_word();
7559*4882a593Smuzhiyun     }
7560*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7561*4882a593Smuzhiyun     END_OF_INSTR();
7562*4882a593Smuzhiyun }
7563*4882a593Smuzhiyun 
7564*4882a593Smuzhiyun /****************************************************************************
7565*4882a593Smuzhiyun REMARKS:
7566*4882a593Smuzhiyun Handles opcode 0x9e
7567*4882a593Smuzhiyun ****************************************************************************/
7568*4882a593Smuzhiyun static void
x86emuOp_sahf(u8 X86EMU_UNUSED (op1))7569*4882a593Smuzhiyun x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7570*4882a593Smuzhiyun {
7571*4882a593Smuzhiyun     START_OF_INSTR();
7572*4882a593Smuzhiyun     DECODE_PRINTF("SAHF\n");
7573*4882a593Smuzhiyun     TRACE_AND_STEP();
7574*4882a593Smuzhiyun     /* clear the lower bits of the flag register */
7575*4882a593Smuzhiyun     M.x86.R_FLG &= 0xffffff00;
7576*4882a593Smuzhiyun     /* or in the AH register into the flags register */
7577*4882a593Smuzhiyun     M.x86.R_FLG |= M.x86.R_AH;
7578*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7579*4882a593Smuzhiyun     END_OF_INSTR();
7580*4882a593Smuzhiyun }
7581*4882a593Smuzhiyun 
7582*4882a593Smuzhiyun /****************************************************************************
7583*4882a593Smuzhiyun REMARKS:
7584*4882a593Smuzhiyun Handles opcode 0x9f
7585*4882a593Smuzhiyun ****************************************************************************/
7586*4882a593Smuzhiyun static void
x86emuOp_lahf(u8 X86EMU_UNUSED (op1))7587*4882a593Smuzhiyun x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7588*4882a593Smuzhiyun {
7589*4882a593Smuzhiyun     START_OF_INSTR();
7590*4882a593Smuzhiyun     DECODE_PRINTF("LAHF\n");
7591*4882a593Smuzhiyun     TRACE_AND_STEP();
7592*4882a593Smuzhiyun     M.x86.R_AH = (u8) (M.x86.R_FLG & 0xff);
7593*4882a593Smuzhiyun     /*undocumented TC++ behavior??? Nope.  It's documented, but
7594*4882a593Smuzhiyun        you have too look real hard to notice it. */
7595*4882a593Smuzhiyun     M.x86.R_AH |= 0x2;
7596*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7597*4882a593Smuzhiyun     END_OF_INSTR();
7598*4882a593Smuzhiyun }
7599*4882a593Smuzhiyun 
7600*4882a593Smuzhiyun /****************************************************************************
7601*4882a593Smuzhiyun REMARKS:
7602*4882a593Smuzhiyun Handles opcode 0xa0
7603*4882a593Smuzhiyun ****************************************************************************/
7604*4882a593Smuzhiyun static void
x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED (op1))7605*4882a593Smuzhiyun x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7606*4882a593Smuzhiyun {
7607*4882a593Smuzhiyun     u16 offset;
7608*4882a593Smuzhiyun 
7609*4882a593Smuzhiyun     START_OF_INSTR();
7610*4882a593Smuzhiyun     DECODE_PRINTF("MOV\tAL,");
7611*4882a593Smuzhiyun     offset = fetch_word_imm();
7612*4882a593Smuzhiyun     DECODE_PRINTF2("[%04x]\n", offset);
7613*4882a593Smuzhiyun     TRACE_AND_STEP();
7614*4882a593Smuzhiyun     M.x86.R_AL = fetch_data_byte(offset);
7615*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7616*4882a593Smuzhiyun     END_OF_INSTR();
7617*4882a593Smuzhiyun }
7618*4882a593Smuzhiyun 
7619*4882a593Smuzhiyun /****************************************************************************
7620*4882a593Smuzhiyun REMARKS:
7621*4882a593Smuzhiyun Handles opcode 0xa1
7622*4882a593Smuzhiyun ****************************************************************************/
7623*4882a593Smuzhiyun static void
x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED (op1))7624*4882a593Smuzhiyun x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7625*4882a593Smuzhiyun {
7626*4882a593Smuzhiyun     u16 offset;
7627*4882a593Smuzhiyun 
7628*4882a593Smuzhiyun     START_OF_INSTR();
7629*4882a593Smuzhiyun     offset = fetch_word_imm();
7630*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7631*4882a593Smuzhiyun         DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7632*4882a593Smuzhiyun     }
7633*4882a593Smuzhiyun     else {
7634*4882a593Smuzhiyun         DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7635*4882a593Smuzhiyun     }
7636*4882a593Smuzhiyun     TRACE_AND_STEP();
7637*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7638*4882a593Smuzhiyun         M.x86.R_EAX = fetch_data_long(offset);
7639*4882a593Smuzhiyun     }
7640*4882a593Smuzhiyun     else {
7641*4882a593Smuzhiyun         M.x86.R_AX = fetch_data_word(offset);
7642*4882a593Smuzhiyun     }
7643*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7644*4882a593Smuzhiyun     END_OF_INSTR();
7645*4882a593Smuzhiyun }
7646*4882a593Smuzhiyun 
7647*4882a593Smuzhiyun /****************************************************************************
7648*4882a593Smuzhiyun REMARKS:
7649*4882a593Smuzhiyun Handles opcode 0xa2
7650*4882a593Smuzhiyun ****************************************************************************/
7651*4882a593Smuzhiyun static void
x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED (op1))7652*4882a593Smuzhiyun x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7653*4882a593Smuzhiyun {
7654*4882a593Smuzhiyun     u16 offset;
7655*4882a593Smuzhiyun 
7656*4882a593Smuzhiyun     START_OF_INSTR();
7657*4882a593Smuzhiyun     DECODE_PRINTF("MOV\t");
7658*4882a593Smuzhiyun     offset = fetch_word_imm();
7659*4882a593Smuzhiyun     DECODE_PRINTF2("[%04x],AL\n", offset);
7660*4882a593Smuzhiyun     TRACE_AND_STEP();
7661*4882a593Smuzhiyun     store_data_byte(offset, M.x86.R_AL);
7662*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7663*4882a593Smuzhiyun     END_OF_INSTR();
7664*4882a593Smuzhiyun }
7665*4882a593Smuzhiyun 
7666*4882a593Smuzhiyun /****************************************************************************
7667*4882a593Smuzhiyun REMARKS:
7668*4882a593Smuzhiyun Handles opcode 0xa3
7669*4882a593Smuzhiyun ****************************************************************************/
7670*4882a593Smuzhiyun static void
x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED (op1))7671*4882a593Smuzhiyun x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7672*4882a593Smuzhiyun {
7673*4882a593Smuzhiyun     u16 offset;
7674*4882a593Smuzhiyun 
7675*4882a593Smuzhiyun     START_OF_INSTR();
7676*4882a593Smuzhiyun     offset = fetch_word_imm();
7677*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7678*4882a593Smuzhiyun         DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7679*4882a593Smuzhiyun     }
7680*4882a593Smuzhiyun     else {
7681*4882a593Smuzhiyun         DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7682*4882a593Smuzhiyun     }
7683*4882a593Smuzhiyun     TRACE_AND_STEP();
7684*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7685*4882a593Smuzhiyun         store_data_long(offset, M.x86.R_EAX);
7686*4882a593Smuzhiyun     }
7687*4882a593Smuzhiyun     else {
7688*4882a593Smuzhiyun         store_data_word(offset, M.x86.R_AX);
7689*4882a593Smuzhiyun     }
7690*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7691*4882a593Smuzhiyun     END_OF_INSTR();
7692*4882a593Smuzhiyun }
7693*4882a593Smuzhiyun 
7694*4882a593Smuzhiyun /****************************************************************************
7695*4882a593Smuzhiyun REMARKS:
7696*4882a593Smuzhiyun Handles opcode 0xa4
7697*4882a593Smuzhiyun ****************************************************************************/
7698*4882a593Smuzhiyun static void
x86emuOp_movs_byte(u8 X86EMU_UNUSED (op1))7699*4882a593Smuzhiyun x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7700*4882a593Smuzhiyun {
7701*4882a593Smuzhiyun     u8 val;
7702*4882a593Smuzhiyun     u32 count;
7703*4882a593Smuzhiyun     int inc;
7704*4882a593Smuzhiyun 
7705*4882a593Smuzhiyun     START_OF_INSTR();
7706*4882a593Smuzhiyun     DECODE_PRINTF("MOVS\tBYTE\n");
7707*4882a593Smuzhiyun     if (ACCESS_FLAG(F_DF))      /* down */
7708*4882a593Smuzhiyun         inc = -1;
7709*4882a593Smuzhiyun     else
7710*4882a593Smuzhiyun         inc = 1;
7711*4882a593Smuzhiyun     TRACE_AND_STEP();
7712*4882a593Smuzhiyun     count = 1;
7713*4882a593Smuzhiyun     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7714*4882a593Smuzhiyun         /* dont care whether REPE or REPNE */
7715*4882a593Smuzhiyun         /* move them until CX is ZERO. */
7716*4882a593Smuzhiyun         count = M.x86.R_CX;
7717*4882a593Smuzhiyun         M.x86.R_CX = 0;
7718*4882a593Smuzhiyun         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7719*4882a593Smuzhiyun     }
7720*4882a593Smuzhiyun     while (count--) {
7721*4882a593Smuzhiyun         val = fetch_data_byte(M.x86.R_SI);
7722*4882a593Smuzhiyun         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7723*4882a593Smuzhiyun         M.x86.R_SI += inc;
7724*4882a593Smuzhiyun         M.x86.R_DI += inc;
7725*4882a593Smuzhiyun     }
7726*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7727*4882a593Smuzhiyun     END_OF_INSTR();
7728*4882a593Smuzhiyun }
7729*4882a593Smuzhiyun 
7730*4882a593Smuzhiyun /****************************************************************************
7731*4882a593Smuzhiyun REMARKS:
7732*4882a593Smuzhiyun Handles opcode 0xa5
7733*4882a593Smuzhiyun ****************************************************************************/
7734*4882a593Smuzhiyun static void
x86emuOp_movs_word(u8 X86EMU_UNUSED (op1))7735*4882a593Smuzhiyun x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7736*4882a593Smuzhiyun {
7737*4882a593Smuzhiyun     u32 val;
7738*4882a593Smuzhiyun     int inc;
7739*4882a593Smuzhiyun     u32 count;
7740*4882a593Smuzhiyun 
7741*4882a593Smuzhiyun     START_OF_INSTR();
7742*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7743*4882a593Smuzhiyun         DECODE_PRINTF("MOVS\tDWORD\n");
7744*4882a593Smuzhiyun         if (ACCESS_FLAG(F_DF))  /* down */
7745*4882a593Smuzhiyun             inc = -4;
7746*4882a593Smuzhiyun         else
7747*4882a593Smuzhiyun             inc = 4;
7748*4882a593Smuzhiyun     }
7749*4882a593Smuzhiyun     else {
7750*4882a593Smuzhiyun         DECODE_PRINTF("MOVS\tWORD\n");
7751*4882a593Smuzhiyun         if (ACCESS_FLAG(F_DF))  /* down */
7752*4882a593Smuzhiyun             inc = -2;
7753*4882a593Smuzhiyun         else
7754*4882a593Smuzhiyun             inc = 2;
7755*4882a593Smuzhiyun     }
7756*4882a593Smuzhiyun     TRACE_AND_STEP();
7757*4882a593Smuzhiyun     count = 1;
7758*4882a593Smuzhiyun     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7759*4882a593Smuzhiyun         /* dont care whether REPE or REPNE */
7760*4882a593Smuzhiyun         /* move them until CX is ZERO. */
7761*4882a593Smuzhiyun         count = M.x86.R_CX;
7762*4882a593Smuzhiyun         M.x86.R_CX = 0;
7763*4882a593Smuzhiyun         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7764*4882a593Smuzhiyun     }
7765*4882a593Smuzhiyun     while (count--) {
7766*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7767*4882a593Smuzhiyun             val = fetch_data_long(M.x86.R_SI);
7768*4882a593Smuzhiyun             store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7769*4882a593Smuzhiyun         }
7770*4882a593Smuzhiyun         else {
7771*4882a593Smuzhiyun             val = fetch_data_word(M.x86.R_SI);
7772*4882a593Smuzhiyun             store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16) val);
7773*4882a593Smuzhiyun         }
7774*4882a593Smuzhiyun         M.x86.R_SI += inc;
7775*4882a593Smuzhiyun         M.x86.R_DI += inc;
7776*4882a593Smuzhiyun     }
7777*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7778*4882a593Smuzhiyun     END_OF_INSTR();
7779*4882a593Smuzhiyun }
7780*4882a593Smuzhiyun 
7781*4882a593Smuzhiyun /****************************************************************************
7782*4882a593Smuzhiyun REMARKS:
7783*4882a593Smuzhiyun Handles opcode 0xa6
7784*4882a593Smuzhiyun ****************************************************************************/
7785*4882a593Smuzhiyun static void
x86emuOp_cmps_byte(u8 X86EMU_UNUSED (op1))7786*4882a593Smuzhiyun x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7787*4882a593Smuzhiyun {
7788*4882a593Smuzhiyun     s8 val1, val2;
7789*4882a593Smuzhiyun     int inc;
7790*4882a593Smuzhiyun 
7791*4882a593Smuzhiyun     START_OF_INSTR();
7792*4882a593Smuzhiyun     DECODE_PRINTF("CMPS\tBYTE\n");
7793*4882a593Smuzhiyun     TRACE_AND_STEP();
7794*4882a593Smuzhiyun     if (ACCESS_FLAG(F_DF))      /* down */
7795*4882a593Smuzhiyun         inc = -1;
7796*4882a593Smuzhiyun     else
7797*4882a593Smuzhiyun         inc = 1;
7798*4882a593Smuzhiyun 
7799*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7800*4882a593Smuzhiyun         /* REPE  */
7801*4882a593Smuzhiyun         /* move them until CX is ZERO. */
7802*4882a593Smuzhiyun         while (M.x86.R_CX != 0) {
7803*4882a593Smuzhiyun             val1 = fetch_data_byte(M.x86.R_SI);
7804*4882a593Smuzhiyun             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7805*4882a593Smuzhiyun             cmp_byte(val1, val2);
7806*4882a593Smuzhiyun             M.x86.R_CX -= 1;
7807*4882a593Smuzhiyun             M.x86.R_SI += inc;
7808*4882a593Smuzhiyun             M.x86.R_DI += inc;
7809*4882a593Smuzhiyun             if (ACCESS_FLAG(F_ZF) == 0)
7810*4882a593Smuzhiyun                 break;
7811*4882a593Smuzhiyun         }
7812*4882a593Smuzhiyun         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7813*4882a593Smuzhiyun     }
7814*4882a593Smuzhiyun     else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7815*4882a593Smuzhiyun         /* REPNE  */
7816*4882a593Smuzhiyun         /* move them until CX is ZERO. */
7817*4882a593Smuzhiyun         while (M.x86.R_CX != 0) {
7818*4882a593Smuzhiyun             val1 = fetch_data_byte(M.x86.R_SI);
7819*4882a593Smuzhiyun             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7820*4882a593Smuzhiyun             cmp_byte(val1, val2);
7821*4882a593Smuzhiyun             M.x86.R_CX -= 1;
7822*4882a593Smuzhiyun             M.x86.R_SI += inc;
7823*4882a593Smuzhiyun             M.x86.R_DI += inc;
7824*4882a593Smuzhiyun             if (ACCESS_FLAG(F_ZF))
7825*4882a593Smuzhiyun                 break;          /* zero flag set means equal */
7826*4882a593Smuzhiyun         }
7827*4882a593Smuzhiyun         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7828*4882a593Smuzhiyun     }
7829*4882a593Smuzhiyun     else {
7830*4882a593Smuzhiyun         val1 = fetch_data_byte(M.x86.R_SI);
7831*4882a593Smuzhiyun         val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7832*4882a593Smuzhiyun         cmp_byte(val1, val2);
7833*4882a593Smuzhiyun         M.x86.R_SI += inc;
7834*4882a593Smuzhiyun         M.x86.R_DI += inc;
7835*4882a593Smuzhiyun     }
7836*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7837*4882a593Smuzhiyun     END_OF_INSTR();
7838*4882a593Smuzhiyun }
7839*4882a593Smuzhiyun 
7840*4882a593Smuzhiyun /****************************************************************************
7841*4882a593Smuzhiyun REMARKS:
7842*4882a593Smuzhiyun Handles opcode 0xa7
7843*4882a593Smuzhiyun ****************************************************************************/
7844*4882a593Smuzhiyun static void
x86emuOp_cmps_word(u8 X86EMU_UNUSED (op1))7845*4882a593Smuzhiyun x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7846*4882a593Smuzhiyun {
7847*4882a593Smuzhiyun     u32 val1, val2;
7848*4882a593Smuzhiyun     int inc;
7849*4882a593Smuzhiyun 
7850*4882a593Smuzhiyun     START_OF_INSTR();
7851*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7852*4882a593Smuzhiyun         DECODE_PRINTF("CMPS\tDWORD\n");
7853*4882a593Smuzhiyun         if (ACCESS_FLAG(F_DF))  /* down */
7854*4882a593Smuzhiyun             inc = -4;
7855*4882a593Smuzhiyun         else
7856*4882a593Smuzhiyun             inc = 4;
7857*4882a593Smuzhiyun     }
7858*4882a593Smuzhiyun     else {
7859*4882a593Smuzhiyun         DECODE_PRINTF("CMPS\tWORD\n");
7860*4882a593Smuzhiyun         if (ACCESS_FLAG(F_DF))  /* down */
7861*4882a593Smuzhiyun             inc = -2;
7862*4882a593Smuzhiyun         else
7863*4882a593Smuzhiyun             inc = 2;
7864*4882a593Smuzhiyun     }
7865*4882a593Smuzhiyun     TRACE_AND_STEP();
7866*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7867*4882a593Smuzhiyun         /* REPE  */
7868*4882a593Smuzhiyun         /* move them until CX is ZERO. */
7869*4882a593Smuzhiyun         while (M.x86.R_CX != 0) {
7870*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7871*4882a593Smuzhiyun                 val1 = fetch_data_long(M.x86.R_SI);
7872*4882a593Smuzhiyun                 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7873*4882a593Smuzhiyun                 cmp_long(val1, val2);
7874*4882a593Smuzhiyun             }
7875*4882a593Smuzhiyun             else {
7876*4882a593Smuzhiyun                 val1 = fetch_data_word(M.x86.R_SI);
7877*4882a593Smuzhiyun                 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7878*4882a593Smuzhiyun                 cmp_word((u16) val1, (u16) val2);
7879*4882a593Smuzhiyun             }
7880*4882a593Smuzhiyun             M.x86.R_CX -= 1;
7881*4882a593Smuzhiyun             M.x86.R_SI += inc;
7882*4882a593Smuzhiyun             M.x86.R_DI += inc;
7883*4882a593Smuzhiyun             if (ACCESS_FLAG(F_ZF) == 0)
7884*4882a593Smuzhiyun                 break;
7885*4882a593Smuzhiyun         }
7886*4882a593Smuzhiyun         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7887*4882a593Smuzhiyun     }
7888*4882a593Smuzhiyun     else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7889*4882a593Smuzhiyun         /* REPNE  */
7890*4882a593Smuzhiyun         /* move them until CX is ZERO. */
7891*4882a593Smuzhiyun         while (M.x86.R_CX != 0) {
7892*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7893*4882a593Smuzhiyun                 val1 = fetch_data_long(M.x86.R_SI);
7894*4882a593Smuzhiyun                 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7895*4882a593Smuzhiyun                 cmp_long(val1, val2);
7896*4882a593Smuzhiyun             }
7897*4882a593Smuzhiyun             else {
7898*4882a593Smuzhiyun                 val1 = fetch_data_word(M.x86.R_SI);
7899*4882a593Smuzhiyun                 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7900*4882a593Smuzhiyun                 cmp_word((u16) val1, (u16) val2);
7901*4882a593Smuzhiyun             }
7902*4882a593Smuzhiyun             M.x86.R_CX -= 1;
7903*4882a593Smuzhiyun             M.x86.R_SI += inc;
7904*4882a593Smuzhiyun             M.x86.R_DI += inc;
7905*4882a593Smuzhiyun             if (ACCESS_FLAG(F_ZF))
7906*4882a593Smuzhiyun                 break;          /* zero flag set means equal */
7907*4882a593Smuzhiyun         }
7908*4882a593Smuzhiyun         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7909*4882a593Smuzhiyun     }
7910*4882a593Smuzhiyun     else {
7911*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7912*4882a593Smuzhiyun             val1 = fetch_data_long(M.x86.R_SI);
7913*4882a593Smuzhiyun             val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7914*4882a593Smuzhiyun             cmp_long(val1, val2);
7915*4882a593Smuzhiyun         }
7916*4882a593Smuzhiyun         else {
7917*4882a593Smuzhiyun             val1 = fetch_data_word(M.x86.R_SI);
7918*4882a593Smuzhiyun             val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7919*4882a593Smuzhiyun             cmp_word((u16) val1, (u16) val2);
7920*4882a593Smuzhiyun         }
7921*4882a593Smuzhiyun         M.x86.R_SI += inc;
7922*4882a593Smuzhiyun         M.x86.R_DI += inc;
7923*4882a593Smuzhiyun     }
7924*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7925*4882a593Smuzhiyun     END_OF_INSTR();
7926*4882a593Smuzhiyun }
7927*4882a593Smuzhiyun 
7928*4882a593Smuzhiyun /****************************************************************************
7929*4882a593Smuzhiyun REMARKS:
7930*4882a593Smuzhiyun Handles opcode 0xa8
7931*4882a593Smuzhiyun ****************************************************************************/
7932*4882a593Smuzhiyun static void
x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED (op1))7933*4882a593Smuzhiyun x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7934*4882a593Smuzhiyun {
7935*4882a593Smuzhiyun     int imm;
7936*4882a593Smuzhiyun 
7937*4882a593Smuzhiyun     START_OF_INSTR();
7938*4882a593Smuzhiyun     DECODE_PRINTF("TEST\tAL,");
7939*4882a593Smuzhiyun     imm = fetch_byte_imm();
7940*4882a593Smuzhiyun     DECODE_PRINTF2("%04x\n", imm);
7941*4882a593Smuzhiyun     TRACE_AND_STEP();
7942*4882a593Smuzhiyun     test_byte(M.x86.R_AL, (u8) imm);
7943*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7944*4882a593Smuzhiyun     END_OF_INSTR();
7945*4882a593Smuzhiyun }
7946*4882a593Smuzhiyun 
7947*4882a593Smuzhiyun /****************************************************************************
7948*4882a593Smuzhiyun REMARKS:
7949*4882a593Smuzhiyun Handles opcode 0xa9
7950*4882a593Smuzhiyun ****************************************************************************/
7951*4882a593Smuzhiyun static void
x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED (op1))7952*4882a593Smuzhiyun x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7953*4882a593Smuzhiyun {
7954*4882a593Smuzhiyun     u32 srcval;
7955*4882a593Smuzhiyun 
7956*4882a593Smuzhiyun     START_OF_INSTR();
7957*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7958*4882a593Smuzhiyun         DECODE_PRINTF("TEST\tEAX,");
7959*4882a593Smuzhiyun         srcval = fetch_long_imm();
7960*4882a593Smuzhiyun     }
7961*4882a593Smuzhiyun     else {
7962*4882a593Smuzhiyun         DECODE_PRINTF("TEST\tAX,");
7963*4882a593Smuzhiyun         srcval = fetch_word_imm();
7964*4882a593Smuzhiyun     }
7965*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
7966*4882a593Smuzhiyun     TRACE_AND_STEP();
7967*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7968*4882a593Smuzhiyun         test_long(M.x86.R_EAX, srcval);
7969*4882a593Smuzhiyun     }
7970*4882a593Smuzhiyun     else {
7971*4882a593Smuzhiyun         test_word(M.x86.R_AX, (u16) srcval);
7972*4882a593Smuzhiyun     }
7973*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
7974*4882a593Smuzhiyun     END_OF_INSTR();
7975*4882a593Smuzhiyun }
7976*4882a593Smuzhiyun 
7977*4882a593Smuzhiyun /****************************************************************************
7978*4882a593Smuzhiyun REMARKS:
7979*4882a593Smuzhiyun Handles opcode 0xaa
7980*4882a593Smuzhiyun ****************************************************************************/
7981*4882a593Smuzhiyun static void
x86emuOp_stos_byte(u8 X86EMU_UNUSED (op1))7982*4882a593Smuzhiyun x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7983*4882a593Smuzhiyun {
7984*4882a593Smuzhiyun     int inc;
7985*4882a593Smuzhiyun 
7986*4882a593Smuzhiyun     START_OF_INSTR();
7987*4882a593Smuzhiyun     DECODE_PRINTF("STOS\tBYTE\n");
7988*4882a593Smuzhiyun     if (ACCESS_FLAG(F_DF))      /* down */
7989*4882a593Smuzhiyun         inc = -1;
7990*4882a593Smuzhiyun     else
7991*4882a593Smuzhiyun         inc = 1;
7992*4882a593Smuzhiyun     TRACE_AND_STEP();
7993*4882a593Smuzhiyun     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7994*4882a593Smuzhiyun         /* dont care whether REPE or REPNE */
7995*4882a593Smuzhiyun         /* move them until CX is ZERO. */
7996*4882a593Smuzhiyun         while (M.x86.R_CX != 0) {
7997*4882a593Smuzhiyun             store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7998*4882a593Smuzhiyun             M.x86.R_CX -= 1;
7999*4882a593Smuzhiyun             M.x86.R_DI += inc;
8000*4882a593Smuzhiyun         }
8001*4882a593Smuzhiyun         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8002*4882a593Smuzhiyun     }
8003*4882a593Smuzhiyun     else {
8004*4882a593Smuzhiyun         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
8005*4882a593Smuzhiyun         M.x86.R_DI += inc;
8006*4882a593Smuzhiyun     }
8007*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8008*4882a593Smuzhiyun     END_OF_INSTR();
8009*4882a593Smuzhiyun }
8010*4882a593Smuzhiyun 
8011*4882a593Smuzhiyun /****************************************************************************
8012*4882a593Smuzhiyun REMARKS:
8013*4882a593Smuzhiyun Handles opcode 0xab
8014*4882a593Smuzhiyun ****************************************************************************/
8015*4882a593Smuzhiyun static void
x86emuOp_stos_word(u8 X86EMU_UNUSED (op1))8016*4882a593Smuzhiyun x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
8017*4882a593Smuzhiyun {
8018*4882a593Smuzhiyun     int inc;
8019*4882a593Smuzhiyun     u32 count;
8020*4882a593Smuzhiyun 
8021*4882a593Smuzhiyun     START_OF_INSTR();
8022*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8023*4882a593Smuzhiyun         DECODE_PRINTF("STOS\tDWORD\n");
8024*4882a593Smuzhiyun         if (ACCESS_FLAG(F_DF))  /* down */
8025*4882a593Smuzhiyun             inc = -4;
8026*4882a593Smuzhiyun         else
8027*4882a593Smuzhiyun             inc = 4;
8028*4882a593Smuzhiyun     }
8029*4882a593Smuzhiyun     else {
8030*4882a593Smuzhiyun         DECODE_PRINTF("STOS\tWORD\n");
8031*4882a593Smuzhiyun         if (ACCESS_FLAG(F_DF))  /* down */
8032*4882a593Smuzhiyun             inc = -2;
8033*4882a593Smuzhiyun         else
8034*4882a593Smuzhiyun             inc = 2;
8035*4882a593Smuzhiyun     }
8036*4882a593Smuzhiyun     TRACE_AND_STEP();
8037*4882a593Smuzhiyun     count = 1;
8038*4882a593Smuzhiyun     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8039*4882a593Smuzhiyun         /* dont care whether REPE or REPNE */
8040*4882a593Smuzhiyun         /* move them until CX is ZERO. */
8041*4882a593Smuzhiyun         count = M.x86.R_CX;
8042*4882a593Smuzhiyun         M.x86.R_CX = 0;
8043*4882a593Smuzhiyun         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8044*4882a593Smuzhiyun     }
8045*4882a593Smuzhiyun     while (count--) {
8046*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8047*4882a593Smuzhiyun             store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
8048*4882a593Smuzhiyun         }
8049*4882a593Smuzhiyun         else {
8050*4882a593Smuzhiyun             store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
8051*4882a593Smuzhiyun         }
8052*4882a593Smuzhiyun         M.x86.R_DI += inc;
8053*4882a593Smuzhiyun     }
8054*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8055*4882a593Smuzhiyun     END_OF_INSTR();
8056*4882a593Smuzhiyun }
8057*4882a593Smuzhiyun 
8058*4882a593Smuzhiyun /****************************************************************************
8059*4882a593Smuzhiyun REMARKS:
8060*4882a593Smuzhiyun Handles opcode 0xac
8061*4882a593Smuzhiyun ****************************************************************************/
8062*4882a593Smuzhiyun static void
x86emuOp_lods_byte(u8 X86EMU_UNUSED (op1))8063*4882a593Smuzhiyun x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
8064*4882a593Smuzhiyun {
8065*4882a593Smuzhiyun     int inc;
8066*4882a593Smuzhiyun 
8067*4882a593Smuzhiyun     START_OF_INSTR();
8068*4882a593Smuzhiyun     DECODE_PRINTF("LODS\tBYTE\n");
8069*4882a593Smuzhiyun     TRACE_AND_STEP();
8070*4882a593Smuzhiyun     if (ACCESS_FLAG(F_DF))      /* down */
8071*4882a593Smuzhiyun         inc = -1;
8072*4882a593Smuzhiyun     else
8073*4882a593Smuzhiyun         inc = 1;
8074*4882a593Smuzhiyun     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8075*4882a593Smuzhiyun         /* dont care whether REPE or REPNE */
8076*4882a593Smuzhiyun         /* move them until CX is ZERO. */
8077*4882a593Smuzhiyun         while (M.x86.R_CX != 0) {
8078*4882a593Smuzhiyun             M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
8079*4882a593Smuzhiyun             M.x86.R_CX -= 1;
8080*4882a593Smuzhiyun             M.x86.R_SI += inc;
8081*4882a593Smuzhiyun         }
8082*4882a593Smuzhiyun         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8083*4882a593Smuzhiyun     }
8084*4882a593Smuzhiyun     else {
8085*4882a593Smuzhiyun         M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
8086*4882a593Smuzhiyun         M.x86.R_SI += inc;
8087*4882a593Smuzhiyun     }
8088*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8089*4882a593Smuzhiyun     END_OF_INSTR();
8090*4882a593Smuzhiyun }
8091*4882a593Smuzhiyun 
8092*4882a593Smuzhiyun /****************************************************************************
8093*4882a593Smuzhiyun REMARKS:
8094*4882a593Smuzhiyun Handles opcode 0xad
8095*4882a593Smuzhiyun ****************************************************************************/
8096*4882a593Smuzhiyun static void
x86emuOp_lods_word(u8 X86EMU_UNUSED (op1))8097*4882a593Smuzhiyun x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
8098*4882a593Smuzhiyun {
8099*4882a593Smuzhiyun     int inc;
8100*4882a593Smuzhiyun     u32 count;
8101*4882a593Smuzhiyun 
8102*4882a593Smuzhiyun     START_OF_INSTR();
8103*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8104*4882a593Smuzhiyun         DECODE_PRINTF("LODS\tDWORD\n");
8105*4882a593Smuzhiyun         if (ACCESS_FLAG(F_DF))  /* down */
8106*4882a593Smuzhiyun             inc = -4;
8107*4882a593Smuzhiyun         else
8108*4882a593Smuzhiyun             inc = 4;
8109*4882a593Smuzhiyun     }
8110*4882a593Smuzhiyun     else {
8111*4882a593Smuzhiyun         DECODE_PRINTF("LODS\tWORD\n");
8112*4882a593Smuzhiyun         if (ACCESS_FLAG(F_DF))  /* down */
8113*4882a593Smuzhiyun             inc = -2;
8114*4882a593Smuzhiyun         else
8115*4882a593Smuzhiyun             inc = 2;
8116*4882a593Smuzhiyun     }
8117*4882a593Smuzhiyun     TRACE_AND_STEP();
8118*4882a593Smuzhiyun     count = 1;
8119*4882a593Smuzhiyun     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8120*4882a593Smuzhiyun         /* dont care whether REPE or REPNE */
8121*4882a593Smuzhiyun         /* move them until CX is ZERO. */
8122*4882a593Smuzhiyun         count = M.x86.R_CX;
8123*4882a593Smuzhiyun         M.x86.R_CX = 0;
8124*4882a593Smuzhiyun         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8125*4882a593Smuzhiyun     }
8126*4882a593Smuzhiyun     while (count--) {
8127*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8128*4882a593Smuzhiyun             M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
8129*4882a593Smuzhiyun         }
8130*4882a593Smuzhiyun         else {
8131*4882a593Smuzhiyun             M.x86.R_AX = fetch_data_word(M.x86.R_SI);
8132*4882a593Smuzhiyun         }
8133*4882a593Smuzhiyun         M.x86.R_SI += inc;
8134*4882a593Smuzhiyun     }
8135*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8136*4882a593Smuzhiyun     END_OF_INSTR();
8137*4882a593Smuzhiyun }
8138*4882a593Smuzhiyun 
8139*4882a593Smuzhiyun /****************************************************************************
8140*4882a593Smuzhiyun REMARKS:
8141*4882a593Smuzhiyun Handles opcode 0xae
8142*4882a593Smuzhiyun ****************************************************************************/
8143*4882a593Smuzhiyun static void
x86emuOp_scas_byte(u8 X86EMU_UNUSED (op1))8144*4882a593Smuzhiyun x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
8145*4882a593Smuzhiyun {
8146*4882a593Smuzhiyun     s8 val2;
8147*4882a593Smuzhiyun     int inc;
8148*4882a593Smuzhiyun 
8149*4882a593Smuzhiyun     START_OF_INSTR();
8150*4882a593Smuzhiyun     DECODE_PRINTF("SCAS\tBYTE\n");
8151*4882a593Smuzhiyun     TRACE_AND_STEP();
8152*4882a593Smuzhiyun     if (ACCESS_FLAG(F_DF))      /* down */
8153*4882a593Smuzhiyun         inc = -1;
8154*4882a593Smuzhiyun     else
8155*4882a593Smuzhiyun         inc = 1;
8156*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
8157*4882a593Smuzhiyun         /* REPE  */
8158*4882a593Smuzhiyun         /* move them until CX is ZERO. */
8159*4882a593Smuzhiyun         while (M.x86.R_CX != 0) {
8160*4882a593Smuzhiyun             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8161*4882a593Smuzhiyun             cmp_byte(M.x86.R_AL, val2);
8162*4882a593Smuzhiyun             M.x86.R_CX -= 1;
8163*4882a593Smuzhiyun             M.x86.R_DI += inc;
8164*4882a593Smuzhiyun             if (ACCESS_FLAG(F_ZF) == 0)
8165*4882a593Smuzhiyun                 break;
8166*4882a593Smuzhiyun         }
8167*4882a593Smuzhiyun         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8168*4882a593Smuzhiyun     }
8169*4882a593Smuzhiyun     else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
8170*4882a593Smuzhiyun         /* REPNE  */
8171*4882a593Smuzhiyun         /* move them until CX is ZERO. */
8172*4882a593Smuzhiyun         while (M.x86.R_CX != 0) {
8173*4882a593Smuzhiyun             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8174*4882a593Smuzhiyun             cmp_byte(M.x86.R_AL, val2);
8175*4882a593Smuzhiyun             M.x86.R_CX -= 1;
8176*4882a593Smuzhiyun             M.x86.R_DI += inc;
8177*4882a593Smuzhiyun             if (ACCESS_FLAG(F_ZF))
8178*4882a593Smuzhiyun                 break;          /* zero flag set means equal */
8179*4882a593Smuzhiyun         }
8180*4882a593Smuzhiyun         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8181*4882a593Smuzhiyun     }
8182*4882a593Smuzhiyun     else {
8183*4882a593Smuzhiyun         val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8184*4882a593Smuzhiyun         cmp_byte(M.x86.R_AL, val2);
8185*4882a593Smuzhiyun         M.x86.R_DI += inc;
8186*4882a593Smuzhiyun     }
8187*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8188*4882a593Smuzhiyun     END_OF_INSTR();
8189*4882a593Smuzhiyun }
8190*4882a593Smuzhiyun 
8191*4882a593Smuzhiyun /****************************************************************************
8192*4882a593Smuzhiyun REMARKS:
8193*4882a593Smuzhiyun Handles opcode 0xaf
8194*4882a593Smuzhiyun ****************************************************************************/
8195*4882a593Smuzhiyun static void
x86emuOp_scas_word(u8 X86EMU_UNUSED (op1))8196*4882a593Smuzhiyun x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
8197*4882a593Smuzhiyun {
8198*4882a593Smuzhiyun     int inc;
8199*4882a593Smuzhiyun     u32 val;
8200*4882a593Smuzhiyun 
8201*4882a593Smuzhiyun     START_OF_INSTR();
8202*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8203*4882a593Smuzhiyun         DECODE_PRINTF("SCAS\tDWORD\n");
8204*4882a593Smuzhiyun         if (ACCESS_FLAG(F_DF))  /* down */
8205*4882a593Smuzhiyun             inc = -4;
8206*4882a593Smuzhiyun         else
8207*4882a593Smuzhiyun             inc = 4;
8208*4882a593Smuzhiyun     }
8209*4882a593Smuzhiyun     else {
8210*4882a593Smuzhiyun         DECODE_PRINTF("SCAS\tWORD\n");
8211*4882a593Smuzhiyun         if (ACCESS_FLAG(F_DF))  /* down */
8212*4882a593Smuzhiyun             inc = -2;
8213*4882a593Smuzhiyun         else
8214*4882a593Smuzhiyun             inc = 2;
8215*4882a593Smuzhiyun     }
8216*4882a593Smuzhiyun     TRACE_AND_STEP();
8217*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
8218*4882a593Smuzhiyun         /* REPE  */
8219*4882a593Smuzhiyun         /* move them until CX is ZERO. */
8220*4882a593Smuzhiyun         while (M.x86.R_CX != 0) {
8221*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8222*4882a593Smuzhiyun                 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8223*4882a593Smuzhiyun                 cmp_long(M.x86.R_EAX, val);
8224*4882a593Smuzhiyun             }
8225*4882a593Smuzhiyun             else {
8226*4882a593Smuzhiyun                 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8227*4882a593Smuzhiyun                 cmp_word(M.x86.R_AX, (u16) val);
8228*4882a593Smuzhiyun             }
8229*4882a593Smuzhiyun             M.x86.R_CX -= 1;
8230*4882a593Smuzhiyun             M.x86.R_DI += inc;
8231*4882a593Smuzhiyun             if (ACCESS_FLAG(F_ZF) == 0)
8232*4882a593Smuzhiyun                 break;
8233*4882a593Smuzhiyun         }
8234*4882a593Smuzhiyun         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8235*4882a593Smuzhiyun     }
8236*4882a593Smuzhiyun     else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
8237*4882a593Smuzhiyun         /* REPNE  */
8238*4882a593Smuzhiyun         /* move them until CX is ZERO. */
8239*4882a593Smuzhiyun         while (M.x86.R_CX != 0) {
8240*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8241*4882a593Smuzhiyun                 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8242*4882a593Smuzhiyun                 cmp_long(M.x86.R_EAX, val);
8243*4882a593Smuzhiyun             }
8244*4882a593Smuzhiyun             else {
8245*4882a593Smuzhiyun                 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8246*4882a593Smuzhiyun                 cmp_word(M.x86.R_AX, (u16) val);
8247*4882a593Smuzhiyun             }
8248*4882a593Smuzhiyun             M.x86.R_CX -= 1;
8249*4882a593Smuzhiyun             M.x86.R_DI += inc;
8250*4882a593Smuzhiyun             if (ACCESS_FLAG(F_ZF))
8251*4882a593Smuzhiyun                 break;          /* zero flag set means equal */
8252*4882a593Smuzhiyun         }
8253*4882a593Smuzhiyun         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8254*4882a593Smuzhiyun     }
8255*4882a593Smuzhiyun     else {
8256*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8257*4882a593Smuzhiyun             val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8258*4882a593Smuzhiyun             cmp_long(M.x86.R_EAX, val);
8259*4882a593Smuzhiyun         }
8260*4882a593Smuzhiyun         else {
8261*4882a593Smuzhiyun             val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8262*4882a593Smuzhiyun             cmp_word(M.x86.R_AX, (u16) val);
8263*4882a593Smuzhiyun         }
8264*4882a593Smuzhiyun         M.x86.R_DI += inc;
8265*4882a593Smuzhiyun     }
8266*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8267*4882a593Smuzhiyun     END_OF_INSTR();
8268*4882a593Smuzhiyun }
8269*4882a593Smuzhiyun 
8270*4882a593Smuzhiyun /****************************************************************************
8271*4882a593Smuzhiyun REMARKS:
8272*4882a593Smuzhiyun Handles opcode 0xb0
8273*4882a593Smuzhiyun ****************************************************************************/
8274*4882a593Smuzhiyun static void
x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED (op1))8275*4882a593Smuzhiyun x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
8276*4882a593Smuzhiyun {
8277*4882a593Smuzhiyun     u8 imm;
8278*4882a593Smuzhiyun 
8279*4882a593Smuzhiyun     START_OF_INSTR();
8280*4882a593Smuzhiyun     DECODE_PRINTF("MOV\tAL,");
8281*4882a593Smuzhiyun     imm = fetch_byte_imm();
8282*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", imm);
8283*4882a593Smuzhiyun     TRACE_AND_STEP();
8284*4882a593Smuzhiyun     M.x86.R_AL = imm;
8285*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8286*4882a593Smuzhiyun     END_OF_INSTR();
8287*4882a593Smuzhiyun }
8288*4882a593Smuzhiyun 
8289*4882a593Smuzhiyun /****************************************************************************
8290*4882a593Smuzhiyun REMARKS:
8291*4882a593Smuzhiyun Handles opcode 0xb1
8292*4882a593Smuzhiyun ****************************************************************************/
8293*4882a593Smuzhiyun static void
x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED (op1))8294*4882a593Smuzhiyun x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
8295*4882a593Smuzhiyun {
8296*4882a593Smuzhiyun     u8 imm;
8297*4882a593Smuzhiyun 
8298*4882a593Smuzhiyun     START_OF_INSTR();
8299*4882a593Smuzhiyun     DECODE_PRINTF("MOV\tCL,");
8300*4882a593Smuzhiyun     imm = fetch_byte_imm();
8301*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", imm);
8302*4882a593Smuzhiyun     TRACE_AND_STEP();
8303*4882a593Smuzhiyun     M.x86.R_CL = imm;
8304*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8305*4882a593Smuzhiyun     END_OF_INSTR();
8306*4882a593Smuzhiyun }
8307*4882a593Smuzhiyun 
8308*4882a593Smuzhiyun /****************************************************************************
8309*4882a593Smuzhiyun REMARKS:
8310*4882a593Smuzhiyun Handles opcode 0xb2
8311*4882a593Smuzhiyun ****************************************************************************/
8312*4882a593Smuzhiyun static void
x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED (op1))8313*4882a593Smuzhiyun x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
8314*4882a593Smuzhiyun {
8315*4882a593Smuzhiyun     u8 imm;
8316*4882a593Smuzhiyun 
8317*4882a593Smuzhiyun     START_OF_INSTR();
8318*4882a593Smuzhiyun     DECODE_PRINTF("MOV\tDL,");
8319*4882a593Smuzhiyun     imm = fetch_byte_imm();
8320*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", imm);
8321*4882a593Smuzhiyun     TRACE_AND_STEP();
8322*4882a593Smuzhiyun     M.x86.R_DL = imm;
8323*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8324*4882a593Smuzhiyun     END_OF_INSTR();
8325*4882a593Smuzhiyun }
8326*4882a593Smuzhiyun 
8327*4882a593Smuzhiyun /****************************************************************************
8328*4882a593Smuzhiyun REMARKS:
8329*4882a593Smuzhiyun Handles opcode 0xb3
8330*4882a593Smuzhiyun ****************************************************************************/
8331*4882a593Smuzhiyun static void
x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED (op1))8332*4882a593Smuzhiyun x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
8333*4882a593Smuzhiyun {
8334*4882a593Smuzhiyun     u8 imm;
8335*4882a593Smuzhiyun 
8336*4882a593Smuzhiyun     START_OF_INSTR();
8337*4882a593Smuzhiyun     DECODE_PRINTF("MOV\tBL,");
8338*4882a593Smuzhiyun     imm = fetch_byte_imm();
8339*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", imm);
8340*4882a593Smuzhiyun     TRACE_AND_STEP();
8341*4882a593Smuzhiyun     M.x86.R_BL = imm;
8342*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8343*4882a593Smuzhiyun     END_OF_INSTR();
8344*4882a593Smuzhiyun }
8345*4882a593Smuzhiyun 
8346*4882a593Smuzhiyun /****************************************************************************
8347*4882a593Smuzhiyun REMARKS:
8348*4882a593Smuzhiyun Handles opcode 0xb4
8349*4882a593Smuzhiyun ****************************************************************************/
8350*4882a593Smuzhiyun static void
x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED (op1))8351*4882a593Smuzhiyun x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
8352*4882a593Smuzhiyun {
8353*4882a593Smuzhiyun     u8 imm;
8354*4882a593Smuzhiyun 
8355*4882a593Smuzhiyun     START_OF_INSTR();
8356*4882a593Smuzhiyun     DECODE_PRINTF("MOV\tAH,");
8357*4882a593Smuzhiyun     imm = fetch_byte_imm();
8358*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", imm);
8359*4882a593Smuzhiyun     TRACE_AND_STEP();
8360*4882a593Smuzhiyun     M.x86.R_AH = imm;
8361*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8362*4882a593Smuzhiyun     END_OF_INSTR();
8363*4882a593Smuzhiyun }
8364*4882a593Smuzhiyun 
8365*4882a593Smuzhiyun /****************************************************************************
8366*4882a593Smuzhiyun REMARKS:
8367*4882a593Smuzhiyun Handles opcode 0xb5
8368*4882a593Smuzhiyun ****************************************************************************/
8369*4882a593Smuzhiyun static void
x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED (op1))8370*4882a593Smuzhiyun x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
8371*4882a593Smuzhiyun {
8372*4882a593Smuzhiyun     u8 imm;
8373*4882a593Smuzhiyun 
8374*4882a593Smuzhiyun     START_OF_INSTR();
8375*4882a593Smuzhiyun     DECODE_PRINTF("MOV\tCH,");
8376*4882a593Smuzhiyun     imm = fetch_byte_imm();
8377*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", imm);
8378*4882a593Smuzhiyun     TRACE_AND_STEP();
8379*4882a593Smuzhiyun     M.x86.R_CH = imm;
8380*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8381*4882a593Smuzhiyun     END_OF_INSTR();
8382*4882a593Smuzhiyun }
8383*4882a593Smuzhiyun 
8384*4882a593Smuzhiyun /****************************************************************************
8385*4882a593Smuzhiyun REMARKS:
8386*4882a593Smuzhiyun Handles opcode 0xb6
8387*4882a593Smuzhiyun ****************************************************************************/
8388*4882a593Smuzhiyun static void
x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED (op1))8389*4882a593Smuzhiyun x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
8390*4882a593Smuzhiyun {
8391*4882a593Smuzhiyun     u8 imm;
8392*4882a593Smuzhiyun 
8393*4882a593Smuzhiyun     START_OF_INSTR();
8394*4882a593Smuzhiyun     DECODE_PRINTF("MOV\tDH,");
8395*4882a593Smuzhiyun     imm = fetch_byte_imm();
8396*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", imm);
8397*4882a593Smuzhiyun     TRACE_AND_STEP();
8398*4882a593Smuzhiyun     M.x86.R_DH = imm;
8399*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8400*4882a593Smuzhiyun     END_OF_INSTR();
8401*4882a593Smuzhiyun }
8402*4882a593Smuzhiyun 
8403*4882a593Smuzhiyun /****************************************************************************
8404*4882a593Smuzhiyun REMARKS:
8405*4882a593Smuzhiyun Handles opcode 0xb7
8406*4882a593Smuzhiyun ****************************************************************************/
8407*4882a593Smuzhiyun static void
x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED (op1))8408*4882a593Smuzhiyun x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
8409*4882a593Smuzhiyun {
8410*4882a593Smuzhiyun     u8 imm;
8411*4882a593Smuzhiyun 
8412*4882a593Smuzhiyun     START_OF_INSTR();
8413*4882a593Smuzhiyun     DECODE_PRINTF("MOV\tBH,");
8414*4882a593Smuzhiyun     imm = fetch_byte_imm();
8415*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", imm);
8416*4882a593Smuzhiyun     TRACE_AND_STEP();
8417*4882a593Smuzhiyun     M.x86.R_BH = imm;
8418*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8419*4882a593Smuzhiyun     END_OF_INSTR();
8420*4882a593Smuzhiyun }
8421*4882a593Smuzhiyun 
8422*4882a593Smuzhiyun /****************************************************************************
8423*4882a593Smuzhiyun REMARKS:
8424*4882a593Smuzhiyun Handles opcode 0xb8
8425*4882a593Smuzhiyun ****************************************************************************/
8426*4882a593Smuzhiyun static void
x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED (op1))8427*4882a593Smuzhiyun x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
8428*4882a593Smuzhiyun {
8429*4882a593Smuzhiyun     u32 srcval;
8430*4882a593Smuzhiyun 
8431*4882a593Smuzhiyun     START_OF_INSTR();
8432*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8433*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tEAX,");
8434*4882a593Smuzhiyun         srcval = fetch_long_imm();
8435*4882a593Smuzhiyun     }
8436*4882a593Smuzhiyun     else {
8437*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tAX,");
8438*4882a593Smuzhiyun         srcval = fetch_word_imm();
8439*4882a593Smuzhiyun     }
8440*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
8441*4882a593Smuzhiyun     TRACE_AND_STEP();
8442*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8443*4882a593Smuzhiyun         M.x86.R_EAX = srcval;
8444*4882a593Smuzhiyun     }
8445*4882a593Smuzhiyun     else {
8446*4882a593Smuzhiyun         M.x86.R_AX = (u16) srcval;
8447*4882a593Smuzhiyun     }
8448*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8449*4882a593Smuzhiyun     END_OF_INSTR();
8450*4882a593Smuzhiyun }
8451*4882a593Smuzhiyun 
8452*4882a593Smuzhiyun /****************************************************************************
8453*4882a593Smuzhiyun REMARKS:
8454*4882a593Smuzhiyun Handles opcode 0xb9
8455*4882a593Smuzhiyun ****************************************************************************/
8456*4882a593Smuzhiyun static void
x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED (op1))8457*4882a593Smuzhiyun x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
8458*4882a593Smuzhiyun {
8459*4882a593Smuzhiyun     u32 srcval;
8460*4882a593Smuzhiyun 
8461*4882a593Smuzhiyun     START_OF_INSTR();
8462*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8463*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tECX,");
8464*4882a593Smuzhiyun         srcval = fetch_long_imm();
8465*4882a593Smuzhiyun     }
8466*4882a593Smuzhiyun     else {
8467*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tCX,");
8468*4882a593Smuzhiyun         srcval = fetch_word_imm();
8469*4882a593Smuzhiyun     }
8470*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
8471*4882a593Smuzhiyun     TRACE_AND_STEP();
8472*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8473*4882a593Smuzhiyun         M.x86.R_ECX = srcval;
8474*4882a593Smuzhiyun     }
8475*4882a593Smuzhiyun     else {
8476*4882a593Smuzhiyun         M.x86.R_CX = (u16) srcval;
8477*4882a593Smuzhiyun     }
8478*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8479*4882a593Smuzhiyun     END_OF_INSTR();
8480*4882a593Smuzhiyun }
8481*4882a593Smuzhiyun 
8482*4882a593Smuzhiyun /****************************************************************************
8483*4882a593Smuzhiyun REMARKS:
8484*4882a593Smuzhiyun Handles opcode 0xba
8485*4882a593Smuzhiyun ****************************************************************************/
8486*4882a593Smuzhiyun static void
x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED (op1))8487*4882a593Smuzhiyun x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
8488*4882a593Smuzhiyun {
8489*4882a593Smuzhiyun     u32 srcval;
8490*4882a593Smuzhiyun 
8491*4882a593Smuzhiyun     START_OF_INSTR();
8492*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8493*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tEDX,");
8494*4882a593Smuzhiyun         srcval = fetch_long_imm();
8495*4882a593Smuzhiyun     }
8496*4882a593Smuzhiyun     else {
8497*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tDX,");
8498*4882a593Smuzhiyun         srcval = fetch_word_imm();
8499*4882a593Smuzhiyun     }
8500*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
8501*4882a593Smuzhiyun     TRACE_AND_STEP();
8502*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8503*4882a593Smuzhiyun         M.x86.R_EDX = srcval;
8504*4882a593Smuzhiyun     }
8505*4882a593Smuzhiyun     else {
8506*4882a593Smuzhiyun         M.x86.R_DX = (u16) srcval;
8507*4882a593Smuzhiyun     }
8508*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8509*4882a593Smuzhiyun     END_OF_INSTR();
8510*4882a593Smuzhiyun }
8511*4882a593Smuzhiyun 
8512*4882a593Smuzhiyun /****************************************************************************
8513*4882a593Smuzhiyun REMARKS:
8514*4882a593Smuzhiyun Handles opcode 0xbb
8515*4882a593Smuzhiyun ****************************************************************************/
8516*4882a593Smuzhiyun static void
x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED (op1))8517*4882a593Smuzhiyun x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8518*4882a593Smuzhiyun {
8519*4882a593Smuzhiyun     u32 srcval;
8520*4882a593Smuzhiyun 
8521*4882a593Smuzhiyun     START_OF_INSTR();
8522*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8523*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tEBX,");
8524*4882a593Smuzhiyun         srcval = fetch_long_imm();
8525*4882a593Smuzhiyun     }
8526*4882a593Smuzhiyun     else {
8527*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tBX,");
8528*4882a593Smuzhiyun         srcval = fetch_word_imm();
8529*4882a593Smuzhiyun     }
8530*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
8531*4882a593Smuzhiyun     TRACE_AND_STEP();
8532*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8533*4882a593Smuzhiyun         M.x86.R_EBX = srcval;
8534*4882a593Smuzhiyun     }
8535*4882a593Smuzhiyun     else {
8536*4882a593Smuzhiyun         M.x86.R_BX = (u16) srcval;
8537*4882a593Smuzhiyun     }
8538*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8539*4882a593Smuzhiyun     END_OF_INSTR();
8540*4882a593Smuzhiyun }
8541*4882a593Smuzhiyun 
8542*4882a593Smuzhiyun /****************************************************************************
8543*4882a593Smuzhiyun REMARKS:
8544*4882a593Smuzhiyun Handles opcode 0xbc
8545*4882a593Smuzhiyun ****************************************************************************/
8546*4882a593Smuzhiyun static void
x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED (op1))8547*4882a593Smuzhiyun x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8548*4882a593Smuzhiyun {
8549*4882a593Smuzhiyun     u32 srcval;
8550*4882a593Smuzhiyun 
8551*4882a593Smuzhiyun     START_OF_INSTR();
8552*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8553*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tESP,");
8554*4882a593Smuzhiyun         srcval = fetch_long_imm();
8555*4882a593Smuzhiyun     }
8556*4882a593Smuzhiyun     else {
8557*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tSP,");
8558*4882a593Smuzhiyun         srcval = fetch_word_imm();
8559*4882a593Smuzhiyun     }
8560*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
8561*4882a593Smuzhiyun     TRACE_AND_STEP();
8562*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8563*4882a593Smuzhiyun         M.x86.R_ESP = srcval;
8564*4882a593Smuzhiyun     }
8565*4882a593Smuzhiyun     else {
8566*4882a593Smuzhiyun         M.x86.R_SP = (u16) srcval;
8567*4882a593Smuzhiyun     }
8568*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8569*4882a593Smuzhiyun     END_OF_INSTR();
8570*4882a593Smuzhiyun }
8571*4882a593Smuzhiyun 
8572*4882a593Smuzhiyun /****************************************************************************
8573*4882a593Smuzhiyun REMARKS:
8574*4882a593Smuzhiyun Handles opcode 0xbd
8575*4882a593Smuzhiyun ****************************************************************************/
8576*4882a593Smuzhiyun static void
x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED (op1))8577*4882a593Smuzhiyun x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8578*4882a593Smuzhiyun {
8579*4882a593Smuzhiyun     u32 srcval;
8580*4882a593Smuzhiyun 
8581*4882a593Smuzhiyun     START_OF_INSTR();
8582*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8583*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tEBP,");
8584*4882a593Smuzhiyun         srcval = fetch_long_imm();
8585*4882a593Smuzhiyun     }
8586*4882a593Smuzhiyun     else {
8587*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tBP,");
8588*4882a593Smuzhiyun         srcval = fetch_word_imm();
8589*4882a593Smuzhiyun     }
8590*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
8591*4882a593Smuzhiyun     TRACE_AND_STEP();
8592*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8593*4882a593Smuzhiyun         M.x86.R_EBP = srcval;
8594*4882a593Smuzhiyun     }
8595*4882a593Smuzhiyun     else {
8596*4882a593Smuzhiyun         M.x86.R_BP = (u16) srcval;
8597*4882a593Smuzhiyun     }
8598*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8599*4882a593Smuzhiyun     END_OF_INSTR();
8600*4882a593Smuzhiyun }
8601*4882a593Smuzhiyun 
8602*4882a593Smuzhiyun /****************************************************************************
8603*4882a593Smuzhiyun REMARKS:
8604*4882a593Smuzhiyun Handles opcode 0xbe
8605*4882a593Smuzhiyun ****************************************************************************/
8606*4882a593Smuzhiyun static void
x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED (op1))8607*4882a593Smuzhiyun x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8608*4882a593Smuzhiyun {
8609*4882a593Smuzhiyun     u32 srcval;
8610*4882a593Smuzhiyun 
8611*4882a593Smuzhiyun     START_OF_INSTR();
8612*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8613*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tESI,");
8614*4882a593Smuzhiyun         srcval = fetch_long_imm();
8615*4882a593Smuzhiyun     }
8616*4882a593Smuzhiyun     else {
8617*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tSI,");
8618*4882a593Smuzhiyun         srcval = fetch_word_imm();
8619*4882a593Smuzhiyun     }
8620*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
8621*4882a593Smuzhiyun     TRACE_AND_STEP();
8622*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8623*4882a593Smuzhiyun         M.x86.R_ESI = srcval;
8624*4882a593Smuzhiyun     }
8625*4882a593Smuzhiyun     else {
8626*4882a593Smuzhiyun         M.x86.R_SI = (u16) srcval;
8627*4882a593Smuzhiyun     }
8628*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8629*4882a593Smuzhiyun     END_OF_INSTR();
8630*4882a593Smuzhiyun }
8631*4882a593Smuzhiyun 
8632*4882a593Smuzhiyun /****************************************************************************
8633*4882a593Smuzhiyun REMARKS:
8634*4882a593Smuzhiyun Handles opcode 0xbf
8635*4882a593Smuzhiyun ****************************************************************************/
8636*4882a593Smuzhiyun static void
x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED (op1))8637*4882a593Smuzhiyun x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8638*4882a593Smuzhiyun {
8639*4882a593Smuzhiyun     u32 srcval;
8640*4882a593Smuzhiyun 
8641*4882a593Smuzhiyun     START_OF_INSTR();
8642*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8643*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tEDI,");
8644*4882a593Smuzhiyun         srcval = fetch_long_imm();
8645*4882a593Smuzhiyun     }
8646*4882a593Smuzhiyun     else {
8647*4882a593Smuzhiyun         DECODE_PRINTF("MOV\tDI,");
8648*4882a593Smuzhiyun         srcval = fetch_word_imm();
8649*4882a593Smuzhiyun     }
8650*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", srcval);
8651*4882a593Smuzhiyun     TRACE_AND_STEP();
8652*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8653*4882a593Smuzhiyun         M.x86.R_EDI = srcval;
8654*4882a593Smuzhiyun     }
8655*4882a593Smuzhiyun     else {
8656*4882a593Smuzhiyun         M.x86.R_DI = (u16) srcval;
8657*4882a593Smuzhiyun     }
8658*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8659*4882a593Smuzhiyun     END_OF_INSTR();
8660*4882a593Smuzhiyun }
8661*4882a593Smuzhiyun 
8662*4882a593Smuzhiyun /* used by opcodes c0, d0, and d2. */
8663*4882a593Smuzhiyun static u8(*opcD0_byte_operation[]) (u8 d, u8 s) = {
8664*4882a593Smuzhiyun     rol_byte, ror_byte, rcl_byte, rcr_byte, shl_byte, shr_byte, shl_byte,       /* sal_byte === shl_byte  by definition */
8665*4882a593Smuzhiyun sar_byte,};
8666*4882a593Smuzhiyun 
8667*4882a593Smuzhiyun /****************************************************************************
8668*4882a593Smuzhiyun REMARKS:
8669*4882a593Smuzhiyun Handles opcode 0xc0
8670*4882a593Smuzhiyun ****************************************************************************/
8671*4882a593Smuzhiyun static void
x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED (op1))8672*4882a593Smuzhiyun x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8673*4882a593Smuzhiyun {
8674*4882a593Smuzhiyun     int mod, rl, rh;
8675*4882a593Smuzhiyun     u8 *destreg;
8676*4882a593Smuzhiyun     uint destoffset;
8677*4882a593Smuzhiyun     u8 destval;
8678*4882a593Smuzhiyun     u8 amt;
8679*4882a593Smuzhiyun 
8680*4882a593Smuzhiyun     /*
8681*4882a593Smuzhiyun      * Yet another weirdo special case instruction format.  Part of
8682*4882a593Smuzhiyun      * the opcode held below in "RH".  Doubly nested case would
8683*4882a593Smuzhiyun      * result, except that the decoded instruction
8684*4882a593Smuzhiyun      */
8685*4882a593Smuzhiyun     START_OF_INSTR();
8686*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
8687*4882a593Smuzhiyun #ifdef DEBUG
8688*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
8689*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
8690*4882a593Smuzhiyun            general, so that it is important to leave the strings
8691*4882a593Smuzhiyun            in the same format, even though the result is that the
8692*4882a593Smuzhiyun            above test is done twice. */
8693*4882a593Smuzhiyun 
8694*4882a593Smuzhiyun         switch (rh) {
8695*4882a593Smuzhiyun         case 0:
8696*4882a593Smuzhiyun             DECODE_PRINTF("ROL\t");
8697*4882a593Smuzhiyun             break;
8698*4882a593Smuzhiyun         case 1:
8699*4882a593Smuzhiyun             DECODE_PRINTF("ROR\t");
8700*4882a593Smuzhiyun             break;
8701*4882a593Smuzhiyun         case 2:
8702*4882a593Smuzhiyun             DECODE_PRINTF("RCL\t");
8703*4882a593Smuzhiyun             break;
8704*4882a593Smuzhiyun         case 3:
8705*4882a593Smuzhiyun             DECODE_PRINTF("RCR\t");
8706*4882a593Smuzhiyun             break;
8707*4882a593Smuzhiyun         case 4:
8708*4882a593Smuzhiyun             DECODE_PRINTF("SHL\t");
8709*4882a593Smuzhiyun             break;
8710*4882a593Smuzhiyun         case 5:
8711*4882a593Smuzhiyun             DECODE_PRINTF("SHR\t");
8712*4882a593Smuzhiyun             break;
8713*4882a593Smuzhiyun         case 6:
8714*4882a593Smuzhiyun             DECODE_PRINTF("SAL\t");
8715*4882a593Smuzhiyun             break;
8716*4882a593Smuzhiyun         case 7:
8717*4882a593Smuzhiyun             DECODE_PRINTF("SAR\t");
8718*4882a593Smuzhiyun             break;
8719*4882a593Smuzhiyun         }
8720*4882a593Smuzhiyun     }
8721*4882a593Smuzhiyun #endif
8722*4882a593Smuzhiyun     /* know operation, decode the mod byte to find the addressing
8723*4882a593Smuzhiyun        mode. */
8724*4882a593Smuzhiyun     switch (mod) {
8725*4882a593Smuzhiyun     case 0:
8726*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
8727*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
8728*4882a593Smuzhiyun         amt = fetch_byte_imm();
8729*4882a593Smuzhiyun         DECODE_PRINTF2(",%x\n", amt);
8730*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
8731*4882a593Smuzhiyun         TRACE_AND_STEP();
8732*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8733*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
8734*4882a593Smuzhiyun         break;
8735*4882a593Smuzhiyun     case 1:
8736*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
8737*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
8738*4882a593Smuzhiyun         amt = fetch_byte_imm();
8739*4882a593Smuzhiyun         DECODE_PRINTF2(",%x\n", amt);
8740*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
8741*4882a593Smuzhiyun         TRACE_AND_STEP();
8742*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8743*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
8744*4882a593Smuzhiyun         break;
8745*4882a593Smuzhiyun     case 2:
8746*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
8747*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
8748*4882a593Smuzhiyun         amt = fetch_byte_imm();
8749*4882a593Smuzhiyun         DECODE_PRINTF2(",%x\n", amt);
8750*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
8751*4882a593Smuzhiyun         TRACE_AND_STEP();
8752*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8753*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
8754*4882a593Smuzhiyun         break;
8755*4882a593Smuzhiyun     case 3:                    /* register to register */
8756*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
8757*4882a593Smuzhiyun         amt = fetch_byte_imm();
8758*4882a593Smuzhiyun         DECODE_PRINTF2(",%x\n", amt);
8759*4882a593Smuzhiyun         TRACE_AND_STEP();
8760*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8761*4882a593Smuzhiyun         *destreg = destval;
8762*4882a593Smuzhiyun         break;
8763*4882a593Smuzhiyun     }
8764*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8765*4882a593Smuzhiyun     END_OF_INSTR();
8766*4882a593Smuzhiyun }
8767*4882a593Smuzhiyun 
8768*4882a593Smuzhiyun /* used by opcodes c1, d1, and d3. */
8769*4882a593Smuzhiyun static u16(*opcD1_word_operation[]) (u16 s, u8 d) = {
8770*4882a593Smuzhiyun     rol_word, ror_word, rcl_word, rcr_word, shl_word, shr_word, shl_word,       /* sal_byte === shl_byte  by definition */
8771*4882a593Smuzhiyun sar_word,};
8772*4882a593Smuzhiyun 
8773*4882a593Smuzhiyun /* used by opcodes c1, d1, and d3. */
8774*4882a593Smuzhiyun static u32(*opcD1_long_operation[]) (u32 s, u8 d) = {
8775*4882a593Smuzhiyun     rol_long, ror_long, rcl_long, rcr_long, shl_long, shr_long, shl_long,       /* sal_byte === shl_byte  by definition */
8776*4882a593Smuzhiyun sar_long,};
8777*4882a593Smuzhiyun 
8778*4882a593Smuzhiyun /****************************************************************************
8779*4882a593Smuzhiyun REMARKS:
8780*4882a593Smuzhiyun Handles opcode 0xc1
8781*4882a593Smuzhiyun ****************************************************************************/
8782*4882a593Smuzhiyun static void
x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED (op1))8783*4882a593Smuzhiyun x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8784*4882a593Smuzhiyun {
8785*4882a593Smuzhiyun     int mod, rl, rh;
8786*4882a593Smuzhiyun     uint destoffset;
8787*4882a593Smuzhiyun     u8 amt;
8788*4882a593Smuzhiyun 
8789*4882a593Smuzhiyun     /*
8790*4882a593Smuzhiyun      * Yet another weirdo special case instruction format.  Part of
8791*4882a593Smuzhiyun      * the opcode held below in "RH".  Doubly nested case would
8792*4882a593Smuzhiyun      * result, except that the decoded instruction
8793*4882a593Smuzhiyun      */
8794*4882a593Smuzhiyun     START_OF_INSTR();
8795*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
8796*4882a593Smuzhiyun #ifdef DEBUG
8797*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
8798*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
8799*4882a593Smuzhiyun            general, so that it is important to leave the strings
8800*4882a593Smuzhiyun            in the same format, even though the result is that the
8801*4882a593Smuzhiyun            above test is done twice. */
8802*4882a593Smuzhiyun 
8803*4882a593Smuzhiyun         switch (rh) {
8804*4882a593Smuzhiyun         case 0:
8805*4882a593Smuzhiyun             DECODE_PRINTF("ROL\t");
8806*4882a593Smuzhiyun             break;
8807*4882a593Smuzhiyun         case 1:
8808*4882a593Smuzhiyun             DECODE_PRINTF("ROR\t");
8809*4882a593Smuzhiyun             break;
8810*4882a593Smuzhiyun         case 2:
8811*4882a593Smuzhiyun             DECODE_PRINTF("RCL\t");
8812*4882a593Smuzhiyun             break;
8813*4882a593Smuzhiyun         case 3:
8814*4882a593Smuzhiyun             DECODE_PRINTF("RCR\t");
8815*4882a593Smuzhiyun             break;
8816*4882a593Smuzhiyun         case 4:
8817*4882a593Smuzhiyun             DECODE_PRINTF("SHL\t");
8818*4882a593Smuzhiyun             break;
8819*4882a593Smuzhiyun         case 5:
8820*4882a593Smuzhiyun             DECODE_PRINTF("SHR\t");
8821*4882a593Smuzhiyun             break;
8822*4882a593Smuzhiyun         case 6:
8823*4882a593Smuzhiyun             DECODE_PRINTF("SAL\t");
8824*4882a593Smuzhiyun             break;
8825*4882a593Smuzhiyun         case 7:
8826*4882a593Smuzhiyun             DECODE_PRINTF("SAR\t");
8827*4882a593Smuzhiyun             break;
8828*4882a593Smuzhiyun         }
8829*4882a593Smuzhiyun     }
8830*4882a593Smuzhiyun #endif
8831*4882a593Smuzhiyun     /* know operation, decode the mod byte to find the addressing
8832*4882a593Smuzhiyun        mode. */
8833*4882a593Smuzhiyun     switch (mod) {
8834*4882a593Smuzhiyun     case 0:
8835*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8836*4882a593Smuzhiyun             u32 destval;
8837*4882a593Smuzhiyun 
8838*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
8839*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
8840*4882a593Smuzhiyun             amt = fetch_byte_imm();
8841*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", amt);
8842*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
8843*4882a593Smuzhiyun             TRACE_AND_STEP();
8844*4882a593Smuzhiyun             destval = (*opcD1_long_operation[rh]) (destval, amt);
8845*4882a593Smuzhiyun             store_data_long(destoffset, destval);
8846*4882a593Smuzhiyun         }
8847*4882a593Smuzhiyun         else {
8848*4882a593Smuzhiyun             u16 destval;
8849*4882a593Smuzhiyun 
8850*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
8851*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
8852*4882a593Smuzhiyun             amt = fetch_byte_imm();
8853*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", amt);
8854*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
8855*4882a593Smuzhiyun             TRACE_AND_STEP();
8856*4882a593Smuzhiyun             destval = (*opcD1_word_operation[rh]) (destval, amt);
8857*4882a593Smuzhiyun             store_data_word(destoffset, destval);
8858*4882a593Smuzhiyun         }
8859*4882a593Smuzhiyun         break;
8860*4882a593Smuzhiyun     case 1:
8861*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8862*4882a593Smuzhiyun             u32 destval;
8863*4882a593Smuzhiyun 
8864*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
8865*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
8866*4882a593Smuzhiyun             amt = fetch_byte_imm();
8867*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", amt);
8868*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
8869*4882a593Smuzhiyun             TRACE_AND_STEP();
8870*4882a593Smuzhiyun             destval = (*opcD1_long_operation[rh]) (destval, amt);
8871*4882a593Smuzhiyun             store_data_long(destoffset, destval);
8872*4882a593Smuzhiyun         }
8873*4882a593Smuzhiyun         else {
8874*4882a593Smuzhiyun             u16 destval;
8875*4882a593Smuzhiyun 
8876*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
8877*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
8878*4882a593Smuzhiyun             amt = fetch_byte_imm();
8879*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", amt);
8880*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
8881*4882a593Smuzhiyun             TRACE_AND_STEP();
8882*4882a593Smuzhiyun             destval = (*opcD1_word_operation[rh]) (destval, amt);
8883*4882a593Smuzhiyun             store_data_word(destoffset, destval);
8884*4882a593Smuzhiyun         }
8885*4882a593Smuzhiyun         break;
8886*4882a593Smuzhiyun     case 2:
8887*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8888*4882a593Smuzhiyun             u32 destval;
8889*4882a593Smuzhiyun 
8890*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
8891*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
8892*4882a593Smuzhiyun             amt = fetch_byte_imm();
8893*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", amt);
8894*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
8895*4882a593Smuzhiyun             TRACE_AND_STEP();
8896*4882a593Smuzhiyun             destval = (*opcD1_long_operation[rh]) (destval, amt);
8897*4882a593Smuzhiyun             store_data_long(destoffset, destval);
8898*4882a593Smuzhiyun         }
8899*4882a593Smuzhiyun         else {
8900*4882a593Smuzhiyun             u16 destval;
8901*4882a593Smuzhiyun 
8902*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
8903*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
8904*4882a593Smuzhiyun             amt = fetch_byte_imm();
8905*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", amt);
8906*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
8907*4882a593Smuzhiyun             TRACE_AND_STEP();
8908*4882a593Smuzhiyun             destval = (*opcD1_word_operation[rh]) (destval, amt);
8909*4882a593Smuzhiyun             store_data_word(destoffset, destval);
8910*4882a593Smuzhiyun         }
8911*4882a593Smuzhiyun         break;
8912*4882a593Smuzhiyun     case 3:                    /* register to register */
8913*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8914*4882a593Smuzhiyun             u32 *destreg;
8915*4882a593Smuzhiyun 
8916*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
8917*4882a593Smuzhiyun             amt = fetch_byte_imm();
8918*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", amt);
8919*4882a593Smuzhiyun             TRACE_AND_STEP();
8920*4882a593Smuzhiyun             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8921*4882a593Smuzhiyun         }
8922*4882a593Smuzhiyun         else {
8923*4882a593Smuzhiyun             u16 *destreg;
8924*4882a593Smuzhiyun 
8925*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
8926*4882a593Smuzhiyun             amt = fetch_byte_imm();
8927*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", amt);
8928*4882a593Smuzhiyun             TRACE_AND_STEP();
8929*4882a593Smuzhiyun             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8930*4882a593Smuzhiyun         }
8931*4882a593Smuzhiyun         break;
8932*4882a593Smuzhiyun     }
8933*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8934*4882a593Smuzhiyun     END_OF_INSTR();
8935*4882a593Smuzhiyun }
8936*4882a593Smuzhiyun 
8937*4882a593Smuzhiyun /****************************************************************************
8938*4882a593Smuzhiyun REMARKS:
8939*4882a593Smuzhiyun Handles opcode 0xc2
8940*4882a593Smuzhiyun ****************************************************************************/
8941*4882a593Smuzhiyun static void
x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED (op1))8942*4882a593Smuzhiyun x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8943*4882a593Smuzhiyun {
8944*4882a593Smuzhiyun     u16 imm;
8945*4882a593Smuzhiyun 
8946*4882a593Smuzhiyun     START_OF_INSTR();
8947*4882a593Smuzhiyun     DECODE_PRINTF("RET\t");
8948*4882a593Smuzhiyun     imm = fetch_word_imm();
8949*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", imm);
8950*4882a593Smuzhiyun     RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8951*4882a593Smuzhiyun     TRACE_AND_STEP();
8952*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8953*4882a593Smuzhiyun         M.x86.R_EIP = pop_long();
8954*4882a593Smuzhiyun     } else {
8955*4882a593Smuzhiyun         M.x86.R_IP = pop_word();
8956*4882a593Smuzhiyun     }
8957*4882a593Smuzhiyun     M.x86.R_SP += imm;
8958*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8959*4882a593Smuzhiyun     END_OF_INSTR();
8960*4882a593Smuzhiyun }
8961*4882a593Smuzhiyun 
8962*4882a593Smuzhiyun /****************************************************************************
8963*4882a593Smuzhiyun REMARKS:
8964*4882a593Smuzhiyun Handles opcode 0xc3
8965*4882a593Smuzhiyun ****************************************************************************/
8966*4882a593Smuzhiyun static void
x86emuOp_ret_near(u8 X86EMU_UNUSED (op1))8967*4882a593Smuzhiyun x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8968*4882a593Smuzhiyun {
8969*4882a593Smuzhiyun     START_OF_INSTR();
8970*4882a593Smuzhiyun     DECODE_PRINTF("RET\n");
8971*4882a593Smuzhiyun     RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8972*4882a593Smuzhiyun     TRACE_AND_STEP();
8973*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8974*4882a593Smuzhiyun         M.x86.R_EIP = pop_long();
8975*4882a593Smuzhiyun     } else {
8976*4882a593Smuzhiyun         M.x86.R_IP = pop_word();
8977*4882a593Smuzhiyun     }
8978*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
8979*4882a593Smuzhiyun     END_OF_INSTR();
8980*4882a593Smuzhiyun }
8981*4882a593Smuzhiyun 
8982*4882a593Smuzhiyun /****************************************************************************
8983*4882a593Smuzhiyun REMARKS:
8984*4882a593Smuzhiyun Handles opcode 0xc4
8985*4882a593Smuzhiyun ****************************************************************************/
8986*4882a593Smuzhiyun static void
x86emuOp_les_R_IMM(u8 X86EMU_UNUSED (op1))8987*4882a593Smuzhiyun x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8988*4882a593Smuzhiyun {
8989*4882a593Smuzhiyun     int mod, rh, rl;
8990*4882a593Smuzhiyun     u16 *dstreg;
8991*4882a593Smuzhiyun     uint srcoffset;
8992*4882a593Smuzhiyun 
8993*4882a593Smuzhiyun     START_OF_INSTR();
8994*4882a593Smuzhiyun     DECODE_PRINTF("LES\t");
8995*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
8996*4882a593Smuzhiyun     switch (mod) {
8997*4882a593Smuzhiyun     case 0:
8998*4882a593Smuzhiyun         dstreg = DECODE_RM_WORD_REGISTER(rh);
8999*4882a593Smuzhiyun         DECODE_PRINTF(",");
9000*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
9001*4882a593Smuzhiyun         DECODE_PRINTF("\n");
9002*4882a593Smuzhiyun         TRACE_AND_STEP();
9003*4882a593Smuzhiyun         *dstreg = fetch_data_word(srcoffset);
9004*4882a593Smuzhiyun         M.x86.R_ES = fetch_data_word(srcoffset + 2);
9005*4882a593Smuzhiyun         break;
9006*4882a593Smuzhiyun     case 1:
9007*4882a593Smuzhiyun         dstreg = DECODE_RM_WORD_REGISTER(rh);
9008*4882a593Smuzhiyun         DECODE_PRINTF(",");
9009*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
9010*4882a593Smuzhiyun         DECODE_PRINTF("\n");
9011*4882a593Smuzhiyun         TRACE_AND_STEP();
9012*4882a593Smuzhiyun         *dstreg = fetch_data_word(srcoffset);
9013*4882a593Smuzhiyun         M.x86.R_ES = fetch_data_word(srcoffset + 2);
9014*4882a593Smuzhiyun         break;
9015*4882a593Smuzhiyun     case 2:
9016*4882a593Smuzhiyun         dstreg = DECODE_RM_WORD_REGISTER(rh);
9017*4882a593Smuzhiyun         DECODE_PRINTF(",");
9018*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
9019*4882a593Smuzhiyun         DECODE_PRINTF("\n");
9020*4882a593Smuzhiyun         TRACE_AND_STEP();
9021*4882a593Smuzhiyun         *dstreg = fetch_data_word(srcoffset);
9022*4882a593Smuzhiyun         M.x86.R_ES = fetch_data_word(srcoffset + 2);
9023*4882a593Smuzhiyun         break;
9024*4882a593Smuzhiyun     case 3:                    /* register to register */
9025*4882a593Smuzhiyun         /* UNDEFINED! */
9026*4882a593Smuzhiyun         TRACE_AND_STEP();
9027*4882a593Smuzhiyun     }
9028*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9029*4882a593Smuzhiyun     END_OF_INSTR();
9030*4882a593Smuzhiyun }
9031*4882a593Smuzhiyun 
9032*4882a593Smuzhiyun /****************************************************************************
9033*4882a593Smuzhiyun REMARKS:
9034*4882a593Smuzhiyun Handles opcode 0xc5
9035*4882a593Smuzhiyun ****************************************************************************/
9036*4882a593Smuzhiyun static void
x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED (op1))9037*4882a593Smuzhiyun x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
9038*4882a593Smuzhiyun {
9039*4882a593Smuzhiyun     int mod, rh, rl;
9040*4882a593Smuzhiyun     u16 *dstreg;
9041*4882a593Smuzhiyun     uint srcoffset;
9042*4882a593Smuzhiyun 
9043*4882a593Smuzhiyun     START_OF_INSTR();
9044*4882a593Smuzhiyun     DECODE_PRINTF("LDS\t");
9045*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
9046*4882a593Smuzhiyun     switch (mod) {
9047*4882a593Smuzhiyun     case 0:
9048*4882a593Smuzhiyun         dstreg = DECODE_RM_WORD_REGISTER(rh);
9049*4882a593Smuzhiyun         DECODE_PRINTF(",");
9050*4882a593Smuzhiyun         srcoffset = decode_rm00_address(rl);
9051*4882a593Smuzhiyun         DECODE_PRINTF("\n");
9052*4882a593Smuzhiyun         TRACE_AND_STEP();
9053*4882a593Smuzhiyun         *dstreg = fetch_data_word(srcoffset);
9054*4882a593Smuzhiyun         M.x86.R_DS = fetch_data_word(srcoffset + 2);
9055*4882a593Smuzhiyun         break;
9056*4882a593Smuzhiyun     case 1:
9057*4882a593Smuzhiyun         dstreg = DECODE_RM_WORD_REGISTER(rh);
9058*4882a593Smuzhiyun         DECODE_PRINTF(",");
9059*4882a593Smuzhiyun         srcoffset = decode_rm01_address(rl);
9060*4882a593Smuzhiyun         DECODE_PRINTF("\n");
9061*4882a593Smuzhiyun         TRACE_AND_STEP();
9062*4882a593Smuzhiyun         *dstreg = fetch_data_word(srcoffset);
9063*4882a593Smuzhiyun         M.x86.R_DS = fetch_data_word(srcoffset + 2);
9064*4882a593Smuzhiyun         break;
9065*4882a593Smuzhiyun     case 2:
9066*4882a593Smuzhiyun         dstreg = DECODE_RM_WORD_REGISTER(rh);
9067*4882a593Smuzhiyun         DECODE_PRINTF(",");
9068*4882a593Smuzhiyun         srcoffset = decode_rm10_address(rl);
9069*4882a593Smuzhiyun         DECODE_PRINTF("\n");
9070*4882a593Smuzhiyun         TRACE_AND_STEP();
9071*4882a593Smuzhiyun         *dstreg = fetch_data_word(srcoffset);
9072*4882a593Smuzhiyun         M.x86.R_DS = fetch_data_word(srcoffset + 2);
9073*4882a593Smuzhiyun         break;
9074*4882a593Smuzhiyun     case 3:                    /* register to register */
9075*4882a593Smuzhiyun         /* UNDEFINED! */
9076*4882a593Smuzhiyun         TRACE_AND_STEP();
9077*4882a593Smuzhiyun     }
9078*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9079*4882a593Smuzhiyun     END_OF_INSTR();
9080*4882a593Smuzhiyun }
9081*4882a593Smuzhiyun 
9082*4882a593Smuzhiyun /****************************************************************************
9083*4882a593Smuzhiyun REMARKS:
9084*4882a593Smuzhiyun Handles opcode 0xc6
9085*4882a593Smuzhiyun ****************************************************************************/
9086*4882a593Smuzhiyun static void
x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED (op1))9087*4882a593Smuzhiyun x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
9088*4882a593Smuzhiyun {
9089*4882a593Smuzhiyun     int mod, rl, rh;
9090*4882a593Smuzhiyun     u8 *destreg;
9091*4882a593Smuzhiyun     uint destoffset;
9092*4882a593Smuzhiyun     u8 imm;
9093*4882a593Smuzhiyun 
9094*4882a593Smuzhiyun     START_OF_INSTR();
9095*4882a593Smuzhiyun     DECODE_PRINTF("MOV\t");
9096*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
9097*4882a593Smuzhiyun     if (rh != 0) {
9098*4882a593Smuzhiyun         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
9099*4882a593Smuzhiyun         HALT_SYS();
9100*4882a593Smuzhiyun     }
9101*4882a593Smuzhiyun     switch (mod) {
9102*4882a593Smuzhiyun     case 0:
9103*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
9104*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
9105*4882a593Smuzhiyun         imm = fetch_byte_imm();
9106*4882a593Smuzhiyun         DECODE_PRINTF2(",%2x\n", imm);
9107*4882a593Smuzhiyun         TRACE_AND_STEP();
9108*4882a593Smuzhiyun         store_data_byte(destoffset, imm);
9109*4882a593Smuzhiyun         break;
9110*4882a593Smuzhiyun     case 1:
9111*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
9112*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
9113*4882a593Smuzhiyun         imm = fetch_byte_imm();
9114*4882a593Smuzhiyun         DECODE_PRINTF2(",%2x\n", imm);
9115*4882a593Smuzhiyun         TRACE_AND_STEP();
9116*4882a593Smuzhiyun         store_data_byte(destoffset, imm);
9117*4882a593Smuzhiyun         break;
9118*4882a593Smuzhiyun     case 2:
9119*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
9120*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
9121*4882a593Smuzhiyun         imm = fetch_byte_imm();
9122*4882a593Smuzhiyun         DECODE_PRINTF2(",%2x\n", imm);
9123*4882a593Smuzhiyun         TRACE_AND_STEP();
9124*4882a593Smuzhiyun         store_data_byte(destoffset, imm);
9125*4882a593Smuzhiyun         break;
9126*4882a593Smuzhiyun     case 3:                    /* register to register */
9127*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
9128*4882a593Smuzhiyun         imm = fetch_byte_imm();
9129*4882a593Smuzhiyun         DECODE_PRINTF2(",%2x\n", imm);
9130*4882a593Smuzhiyun         TRACE_AND_STEP();
9131*4882a593Smuzhiyun         *destreg = imm;
9132*4882a593Smuzhiyun         break;
9133*4882a593Smuzhiyun     }
9134*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9135*4882a593Smuzhiyun     END_OF_INSTR();
9136*4882a593Smuzhiyun }
9137*4882a593Smuzhiyun 
9138*4882a593Smuzhiyun /****************************************************************************
9139*4882a593Smuzhiyun REMARKS:
9140*4882a593Smuzhiyun Handles opcode 0xc7
9141*4882a593Smuzhiyun ****************************************************************************/
9142*4882a593Smuzhiyun static void
x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED (op1))9143*4882a593Smuzhiyun x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
9144*4882a593Smuzhiyun {
9145*4882a593Smuzhiyun     int mod, rl, rh;
9146*4882a593Smuzhiyun     uint destoffset;
9147*4882a593Smuzhiyun 
9148*4882a593Smuzhiyun     START_OF_INSTR();
9149*4882a593Smuzhiyun     DECODE_PRINTF("MOV\t");
9150*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
9151*4882a593Smuzhiyun     if (rh != 0) {
9152*4882a593Smuzhiyun         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
9153*4882a593Smuzhiyun         HALT_SYS();
9154*4882a593Smuzhiyun     }
9155*4882a593Smuzhiyun     switch (mod) {
9156*4882a593Smuzhiyun     case 0:
9157*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9158*4882a593Smuzhiyun             u32 imm;
9159*4882a593Smuzhiyun 
9160*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
9161*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
9162*4882a593Smuzhiyun             imm = fetch_long_imm();
9163*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
9164*4882a593Smuzhiyun             TRACE_AND_STEP();
9165*4882a593Smuzhiyun             store_data_long(destoffset, imm);
9166*4882a593Smuzhiyun         }
9167*4882a593Smuzhiyun         else {
9168*4882a593Smuzhiyun             u16 imm;
9169*4882a593Smuzhiyun 
9170*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
9171*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
9172*4882a593Smuzhiyun             imm = fetch_word_imm();
9173*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
9174*4882a593Smuzhiyun             TRACE_AND_STEP();
9175*4882a593Smuzhiyun             store_data_word(destoffset, imm);
9176*4882a593Smuzhiyun         }
9177*4882a593Smuzhiyun         break;
9178*4882a593Smuzhiyun     case 1:
9179*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9180*4882a593Smuzhiyun             u32 imm;
9181*4882a593Smuzhiyun 
9182*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
9183*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
9184*4882a593Smuzhiyun             imm = fetch_long_imm();
9185*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
9186*4882a593Smuzhiyun             TRACE_AND_STEP();
9187*4882a593Smuzhiyun             store_data_long(destoffset, imm);
9188*4882a593Smuzhiyun         }
9189*4882a593Smuzhiyun         else {
9190*4882a593Smuzhiyun             u16 imm;
9191*4882a593Smuzhiyun 
9192*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
9193*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
9194*4882a593Smuzhiyun             imm = fetch_word_imm();
9195*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
9196*4882a593Smuzhiyun             TRACE_AND_STEP();
9197*4882a593Smuzhiyun             store_data_word(destoffset, imm);
9198*4882a593Smuzhiyun         }
9199*4882a593Smuzhiyun         break;
9200*4882a593Smuzhiyun     case 2:
9201*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9202*4882a593Smuzhiyun             u32 imm;
9203*4882a593Smuzhiyun 
9204*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
9205*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
9206*4882a593Smuzhiyun             imm = fetch_long_imm();
9207*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
9208*4882a593Smuzhiyun             TRACE_AND_STEP();
9209*4882a593Smuzhiyun             store_data_long(destoffset, imm);
9210*4882a593Smuzhiyun         }
9211*4882a593Smuzhiyun         else {
9212*4882a593Smuzhiyun             u16 imm;
9213*4882a593Smuzhiyun 
9214*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
9215*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
9216*4882a593Smuzhiyun             imm = fetch_word_imm();
9217*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
9218*4882a593Smuzhiyun             TRACE_AND_STEP();
9219*4882a593Smuzhiyun             store_data_word(destoffset, imm);
9220*4882a593Smuzhiyun         }
9221*4882a593Smuzhiyun         break;
9222*4882a593Smuzhiyun     case 3:                    /* register to register */
9223*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9224*4882a593Smuzhiyun             u32 *destreg;
9225*4882a593Smuzhiyun             u32 imm;
9226*4882a593Smuzhiyun 
9227*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
9228*4882a593Smuzhiyun             imm = fetch_long_imm();
9229*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
9230*4882a593Smuzhiyun             TRACE_AND_STEP();
9231*4882a593Smuzhiyun             *destreg = imm;
9232*4882a593Smuzhiyun         }
9233*4882a593Smuzhiyun         else {
9234*4882a593Smuzhiyun             u16 *destreg;
9235*4882a593Smuzhiyun             u16 imm;
9236*4882a593Smuzhiyun 
9237*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
9238*4882a593Smuzhiyun             imm = fetch_word_imm();
9239*4882a593Smuzhiyun             DECODE_PRINTF2(",%x\n", imm);
9240*4882a593Smuzhiyun             TRACE_AND_STEP();
9241*4882a593Smuzhiyun             *destreg = imm;
9242*4882a593Smuzhiyun         }
9243*4882a593Smuzhiyun         break;
9244*4882a593Smuzhiyun     }
9245*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9246*4882a593Smuzhiyun     END_OF_INSTR();
9247*4882a593Smuzhiyun }
9248*4882a593Smuzhiyun 
9249*4882a593Smuzhiyun /****************************************************************************
9250*4882a593Smuzhiyun REMARKS:
9251*4882a593Smuzhiyun Handles opcode 0xc8
9252*4882a593Smuzhiyun ****************************************************************************/
9253*4882a593Smuzhiyun static void
x86emuOp_enter(u8 X86EMU_UNUSED (op1))9254*4882a593Smuzhiyun x86emuOp_enter(u8 X86EMU_UNUSED(op1))
9255*4882a593Smuzhiyun {
9256*4882a593Smuzhiyun     u16 local, frame_pointer;
9257*4882a593Smuzhiyun     u8 nesting;
9258*4882a593Smuzhiyun     int i;
9259*4882a593Smuzhiyun 
9260*4882a593Smuzhiyun     START_OF_INSTR();
9261*4882a593Smuzhiyun     local = fetch_word_imm();
9262*4882a593Smuzhiyun     nesting = fetch_byte_imm();
9263*4882a593Smuzhiyun     DECODE_PRINTF2("ENTER %x\n", local);
9264*4882a593Smuzhiyun     DECODE_PRINTF2(",%x\n", nesting);
9265*4882a593Smuzhiyun     TRACE_AND_STEP();
9266*4882a593Smuzhiyun     push_word(M.x86.R_BP);
9267*4882a593Smuzhiyun     frame_pointer = M.x86.R_SP;
9268*4882a593Smuzhiyun     if (nesting > 0) {
9269*4882a593Smuzhiyun         for (i = 1; i < nesting; i++) {
9270*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9271*4882a593Smuzhiyun                 M.x86.R_BP -= 4;
9272*4882a593Smuzhiyun                 push_long(fetch_data_long_abs(M.x86.R_SS, M.x86.R_BP));
9273*4882a593Smuzhiyun             } else {
9274*4882a593Smuzhiyun                 M.x86.R_BP -= 2;
9275*4882a593Smuzhiyun                 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
9276*4882a593Smuzhiyun             }
9277*4882a593Smuzhiyun         }
9278*4882a593Smuzhiyun         push_word(frame_pointer);
9279*4882a593Smuzhiyun     }
9280*4882a593Smuzhiyun     M.x86.R_BP = frame_pointer;
9281*4882a593Smuzhiyun     M.x86.R_SP = (u16) (M.x86.R_SP - local);
9282*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9283*4882a593Smuzhiyun     END_OF_INSTR();
9284*4882a593Smuzhiyun }
9285*4882a593Smuzhiyun 
9286*4882a593Smuzhiyun /****************************************************************************
9287*4882a593Smuzhiyun REMARKS:
9288*4882a593Smuzhiyun Handles opcode 0xc9
9289*4882a593Smuzhiyun ****************************************************************************/
9290*4882a593Smuzhiyun static void
x86emuOp_leave(u8 X86EMU_UNUSED (op1))9291*4882a593Smuzhiyun x86emuOp_leave(u8 X86EMU_UNUSED(op1))
9292*4882a593Smuzhiyun {
9293*4882a593Smuzhiyun     START_OF_INSTR();
9294*4882a593Smuzhiyun     DECODE_PRINTF("LEAVE\n");
9295*4882a593Smuzhiyun     TRACE_AND_STEP();
9296*4882a593Smuzhiyun     M.x86.R_SP = M.x86.R_BP;
9297*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9298*4882a593Smuzhiyun         M.x86.R_EBP = pop_long();
9299*4882a593Smuzhiyun     } else {
9300*4882a593Smuzhiyun         M.x86.R_BP = pop_word();
9301*4882a593Smuzhiyun     }
9302*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9303*4882a593Smuzhiyun     END_OF_INSTR();
9304*4882a593Smuzhiyun }
9305*4882a593Smuzhiyun 
9306*4882a593Smuzhiyun /****************************************************************************
9307*4882a593Smuzhiyun REMARKS:
9308*4882a593Smuzhiyun Handles opcode 0xca
9309*4882a593Smuzhiyun ****************************************************************************/
9310*4882a593Smuzhiyun static void
x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED (op1))9311*4882a593Smuzhiyun x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
9312*4882a593Smuzhiyun {
9313*4882a593Smuzhiyun     u16 imm;
9314*4882a593Smuzhiyun 
9315*4882a593Smuzhiyun     START_OF_INSTR();
9316*4882a593Smuzhiyun     DECODE_PRINTF("RETF\t");
9317*4882a593Smuzhiyun     imm = fetch_word_imm();
9318*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", imm);
9319*4882a593Smuzhiyun     RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9320*4882a593Smuzhiyun     TRACE_AND_STEP();
9321*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9322*4882a593Smuzhiyun         M.x86.R_EIP = pop_long();
9323*4882a593Smuzhiyun         M.x86.R_CS = pop_long() & 0xffff;
9324*4882a593Smuzhiyun     } else {
9325*4882a593Smuzhiyun         M.x86.R_IP = pop_word();
9326*4882a593Smuzhiyun         M.x86.R_CS = pop_word();
9327*4882a593Smuzhiyun     }
9328*4882a593Smuzhiyun     M.x86.R_SP += imm;
9329*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9330*4882a593Smuzhiyun     END_OF_INSTR();
9331*4882a593Smuzhiyun }
9332*4882a593Smuzhiyun 
9333*4882a593Smuzhiyun /****************************************************************************
9334*4882a593Smuzhiyun REMARKS:
9335*4882a593Smuzhiyun Handles opcode 0xcb
9336*4882a593Smuzhiyun ****************************************************************************/
9337*4882a593Smuzhiyun static void
x86emuOp_ret_far(u8 X86EMU_UNUSED (op1))9338*4882a593Smuzhiyun x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
9339*4882a593Smuzhiyun {
9340*4882a593Smuzhiyun     START_OF_INSTR();
9341*4882a593Smuzhiyun     DECODE_PRINTF("RETF\n");
9342*4882a593Smuzhiyun     RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9343*4882a593Smuzhiyun     TRACE_AND_STEP();
9344*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9345*4882a593Smuzhiyun         M.x86.R_EIP = pop_long();
9346*4882a593Smuzhiyun         M.x86.R_CS = pop_long() & 0xffff;
9347*4882a593Smuzhiyun     } else {
9348*4882a593Smuzhiyun         M.x86.R_IP = pop_word();
9349*4882a593Smuzhiyun         M.x86.R_CS = pop_word();
9350*4882a593Smuzhiyun     }
9351*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9352*4882a593Smuzhiyun     END_OF_INSTR();
9353*4882a593Smuzhiyun }
9354*4882a593Smuzhiyun 
9355*4882a593Smuzhiyun /****************************************************************************
9356*4882a593Smuzhiyun REMARKS:
9357*4882a593Smuzhiyun Handles opcode 0xcc
9358*4882a593Smuzhiyun ****************************************************************************/
9359*4882a593Smuzhiyun static void
x86emuOp_int3(u8 X86EMU_UNUSED (op1))9360*4882a593Smuzhiyun x86emuOp_int3(u8 X86EMU_UNUSED(op1))
9361*4882a593Smuzhiyun {
9362*4882a593Smuzhiyun     START_OF_INSTR();
9363*4882a593Smuzhiyun     DECODE_PRINTF("INT 3\n");
9364*4882a593Smuzhiyun     TRACE_AND_STEP();
9365*4882a593Smuzhiyun     if (_X86EMU_intrTab[3]) {
9366*4882a593Smuzhiyun         (*_X86EMU_intrTab[3]) (3);
9367*4882a593Smuzhiyun     }
9368*4882a593Smuzhiyun     else {
9369*4882a593Smuzhiyun         push_word((u16) M.x86.R_FLG);
9370*4882a593Smuzhiyun         CLEAR_FLAG(F_IF);
9371*4882a593Smuzhiyun         CLEAR_FLAG(F_TF);
9372*4882a593Smuzhiyun         push_word(M.x86.R_CS);
9373*4882a593Smuzhiyun         M.x86.R_CS = mem_access_word(3 * 4 + 2);
9374*4882a593Smuzhiyun         push_word(M.x86.R_IP);
9375*4882a593Smuzhiyun         M.x86.R_IP = mem_access_word(3 * 4);
9376*4882a593Smuzhiyun     }
9377*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9378*4882a593Smuzhiyun     END_OF_INSTR();
9379*4882a593Smuzhiyun }
9380*4882a593Smuzhiyun 
9381*4882a593Smuzhiyun /****************************************************************************
9382*4882a593Smuzhiyun REMARKS:
9383*4882a593Smuzhiyun Handles opcode 0xcd
9384*4882a593Smuzhiyun ****************************************************************************/
9385*4882a593Smuzhiyun static void
x86emuOp_int_IMM(u8 X86EMU_UNUSED (op1))9386*4882a593Smuzhiyun x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
9387*4882a593Smuzhiyun {
9388*4882a593Smuzhiyun     u8 intnum;
9389*4882a593Smuzhiyun 
9390*4882a593Smuzhiyun     START_OF_INSTR();
9391*4882a593Smuzhiyun     DECODE_PRINTF("INT\t");
9392*4882a593Smuzhiyun     intnum = fetch_byte_imm();
9393*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", intnum);
9394*4882a593Smuzhiyun     TRACE_AND_STEP();
9395*4882a593Smuzhiyun     if (_X86EMU_intrTab[intnum]) {
9396*4882a593Smuzhiyun         (*_X86EMU_intrTab[intnum]) (intnum);
9397*4882a593Smuzhiyun     }
9398*4882a593Smuzhiyun     else {
9399*4882a593Smuzhiyun         push_word((u16) M.x86.R_FLG);
9400*4882a593Smuzhiyun         CLEAR_FLAG(F_IF);
9401*4882a593Smuzhiyun         CLEAR_FLAG(F_TF);
9402*4882a593Smuzhiyun         push_word(M.x86.R_CS);
9403*4882a593Smuzhiyun         M.x86.R_CS = mem_access_word(intnum * 4 + 2);
9404*4882a593Smuzhiyun         push_word(M.x86.R_IP);
9405*4882a593Smuzhiyun         M.x86.R_IP = mem_access_word(intnum * 4);
9406*4882a593Smuzhiyun     }
9407*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9408*4882a593Smuzhiyun     END_OF_INSTR();
9409*4882a593Smuzhiyun }
9410*4882a593Smuzhiyun 
9411*4882a593Smuzhiyun /****************************************************************************
9412*4882a593Smuzhiyun REMARKS:
9413*4882a593Smuzhiyun Handles opcode 0xce
9414*4882a593Smuzhiyun ****************************************************************************/
9415*4882a593Smuzhiyun static void
x86emuOp_into(u8 X86EMU_UNUSED (op1))9416*4882a593Smuzhiyun x86emuOp_into(u8 X86EMU_UNUSED(op1))
9417*4882a593Smuzhiyun {
9418*4882a593Smuzhiyun     START_OF_INSTR();
9419*4882a593Smuzhiyun     DECODE_PRINTF("INTO\n");
9420*4882a593Smuzhiyun     TRACE_AND_STEP();
9421*4882a593Smuzhiyun     if (ACCESS_FLAG(F_OF)) {
9422*4882a593Smuzhiyun         if (_X86EMU_intrTab[4]) {
9423*4882a593Smuzhiyun             (*_X86EMU_intrTab[4]) (4);
9424*4882a593Smuzhiyun         }
9425*4882a593Smuzhiyun         else {
9426*4882a593Smuzhiyun             push_word((u16) M.x86.R_FLG);
9427*4882a593Smuzhiyun             CLEAR_FLAG(F_IF);
9428*4882a593Smuzhiyun             CLEAR_FLAG(F_TF);
9429*4882a593Smuzhiyun             push_word(M.x86.R_CS);
9430*4882a593Smuzhiyun             M.x86.R_CS = mem_access_word(4 * 4 + 2);
9431*4882a593Smuzhiyun             push_word(M.x86.R_IP);
9432*4882a593Smuzhiyun             M.x86.R_IP = mem_access_word(4 * 4);
9433*4882a593Smuzhiyun         }
9434*4882a593Smuzhiyun     }
9435*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9436*4882a593Smuzhiyun     END_OF_INSTR();
9437*4882a593Smuzhiyun }
9438*4882a593Smuzhiyun 
9439*4882a593Smuzhiyun /****************************************************************************
9440*4882a593Smuzhiyun REMARKS:
9441*4882a593Smuzhiyun Handles opcode 0xcf
9442*4882a593Smuzhiyun ****************************************************************************/
9443*4882a593Smuzhiyun static void
x86emuOp_iret(u8 X86EMU_UNUSED (op1))9444*4882a593Smuzhiyun x86emuOp_iret(u8 X86EMU_UNUSED(op1))
9445*4882a593Smuzhiyun {
9446*4882a593Smuzhiyun     START_OF_INSTR();
9447*4882a593Smuzhiyun     DECODE_PRINTF("IRET\n");
9448*4882a593Smuzhiyun 
9449*4882a593Smuzhiyun     TRACE_AND_STEP();
9450*4882a593Smuzhiyun 
9451*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9452*4882a593Smuzhiyun         M.x86.R_EIP = pop_long();
9453*4882a593Smuzhiyun         M.x86.R_CS = pop_long() & 0xffff;
9454*4882a593Smuzhiyun         M.x86.R_EFLG = (pop_long() & 0x257FD5) | (M.x86.R_EFLG & 0x1A0000);
9455*4882a593Smuzhiyun     } else {
9456*4882a593Smuzhiyun         M.x86.R_IP = pop_word();
9457*4882a593Smuzhiyun         M.x86.R_CS = pop_word();
9458*4882a593Smuzhiyun         M.x86.R_FLG = pop_word();
9459*4882a593Smuzhiyun     }
9460*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9461*4882a593Smuzhiyun     END_OF_INSTR();
9462*4882a593Smuzhiyun }
9463*4882a593Smuzhiyun 
9464*4882a593Smuzhiyun /****************************************************************************
9465*4882a593Smuzhiyun REMARKS:
9466*4882a593Smuzhiyun Handles opcode 0xd0
9467*4882a593Smuzhiyun ****************************************************************************/
9468*4882a593Smuzhiyun static void
x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED (op1))9469*4882a593Smuzhiyun x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
9470*4882a593Smuzhiyun {
9471*4882a593Smuzhiyun     int mod, rl, rh;
9472*4882a593Smuzhiyun     u8 *destreg;
9473*4882a593Smuzhiyun     uint destoffset;
9474*4882a593Smuzhiyun     u8 destval;
9475*4882a593Smuzhiyun 
9476*4882a593Smuzhiyun     /*
9477*4882a593Smuzhiyun      * Yet another weirdo special case instruction format.  Part of
9478*4882a593Smuzhiyun      * the opcode held below in "RH".  Doubly nested case would
9479*4882a593Smuzhiyun      * result, except that the decoded instruction
9480*4882a593Smuzhiyun      */
9481*4882a593Smuzhiyun     START_OF_INSTR();
9482*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
9483*4882a593Smuzhiyun #ifdef DEBUG
9484*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
9485*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
9486*4882a593Smuzhiyun            general, so that it is important to leave the strings
9487*4882a593Smuzhiyun            in the same format, even though the result is that the
9488*4882a593Smuzhiyun            above test is done twice. */
9489*4882a593Smuzhiyun         switch (rh) {
9490*4882a593Smuzhiyun         case 0:
9491*4882a593Smuzhiyun             DECODE_PRINTF("ROL\t");
9492*4882a593Smuzhiyun             break;
9493*4882a593Smuzhiyun         case 1:
9494*4882a593Smuzhiyun             DECODE_PRINTF("ROR\t");
9495*4882a593Smuzhiyun             break;
9496*4882a593Smuzhiyun         case 2:
9497*4882a593Smuzhiyun             DECODE_PRINTF("RCL\t");
9498*4882a593Smuzhiyun             break;
9499*4882a593Smuzhiyun         case 3:
9500*4882a593Smuzhiyun             DECODE_PRINTF("RCR\t");
9501*4882a593Smuzhiyun             break;
9502*4882a593Smuzhiyun         case 4:
9503*4882a593Smuzhiyun             DECODE_PRINTF("SHL\t");
9504*4882a593Smuzhiyun             break;
9505*4882a593Smuzhiyun         case 5:
9506*4882a593Smuzhiyun             DECODE_PRINTF("SHR\t");
9507*4882a593Smuzhiyun             break;
9508*4882a593Smuzhiyun         case 6:
9509*4882a593Smuzhiyun             DECODE_PRINTF("SAL\t");
9510*4882a593Smuzhiyun             break;
9511*4882a593Smuzhiyun         case 7:
9512*4882a593Smuzhiyun             DECODE_PRINTF("SAR\t");
9513*4882a593Smuzhiyun             break;
9514*4882a593Smuzhiyun         }
9515*4882a593Smuzhiyun     }
9516*4882a593Smuzhiyun #endif
9517*4882a593Smuzhiyun     /* know operation, decode the mod byte to find the addressing
9518*4882a593Smuzhiyun        mode. */
9519*4882a593Smuzhiyun     switch (mod) {
9520*4882a593Smuzhiyun     case 0:
9521*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
9522*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
9523*4882a593Smuzhiyun         DECODE_PRINTF(",1\n");
9524*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
9525*4882a593Smuzhiyun         TRACE_AND_STEP();
9526*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9527*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
9528*4882a593Smuzhiyun         break;
9529*4882a593Smuzhiyun     case 1:
9530*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
9531*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
9532*4882a593Smuzhiyun         DECODE_PRINTF(",1\n");
9533*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
9534*4882a593Smuzhiyun         TRACE_AND_STEP();
9535*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9536*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
9537*4882a593Smuzhiyun         break;
9538*4882a593Smuzhiyun     case 2:
9539*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
9540*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
9541*4882a593Smuzhiyun         DECODE_PRINTF(",1\n");
9542*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
9543*4882a593Smuzhiyun         TRACE_AND_STEP();
9544*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9545*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
9546*4882a593Smuzhiyun         break;
9547*4882a593Smuzhiyun     case 3:                    /* register to register */
9548*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
9549*4882a593Smuzhiyun         DECODE_PRINTF(",1\n");
9550*4882a593Smuzhiyun         TRACE_AND_STEP();
9551*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9552*4882a593Smuzhiyun         *destreg = destval;
9553*4882a593Smuzhiyun         break;
9554*4882a593Smuzhiyun     }
9555*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9556*4882a593Smuzhiyun     END_OF_INSTR();
9557*4882a593Smuzhiyun }
9558*4882a593Smuzhiyun 
9559*4882a593Smuzhiyun /****************************************************************************
9560*4882a593Smuzhiyun REMARKS:
9561*4882a593Smuzhiyun Handles opcode 0xd1
9562*4882a593Smuzhiyun ****************************************************************************/
9563*4882a593Smuzhiyun static void
x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED (op1))9564*4882a593Smuzhiyun x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9565*4882a593Smuzhiyun {
9566*4882a593Smuzhiyun     int mod, rl, rh;
9567*4882a593Smuzhiyun     uint destoffset;
9568*4882a593Smuzhiyun 
9569*4882a593Smuzhiyun     /*
9570*4882a593Smuzhiyun      * Yet another weirdo special case instruction format.  Part of
9571*4882a593Smuzhiyun      * the opcode held below in "RH".  Doubly nested case would
9572*4882a593Smuzhiyun      * result, except that the decoded instruction
9573*4882a593Smuzhiyun      */
9574*4882a593Smuzhiyun     START_OF_INSTR();
9575*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
9576*4882a593Smuzhiyun #ifdef DEBUG
9577*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
9578*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
9579*4882a593Smuzhiyun            general, so that it is important to leave the strings
9580*4882a593Smuzhiyun            in the same format, even though the result is that the
9581*4882a593Smuzhiyun            above test is done twice. */
9582*4882a593Smuzhiyun         switch (rh) {
9583*4882a593Smuzhiyun         case 0:
9584*4882a593Smuzhiyun             DECODE_PRINTF("ROL\t");
9585*4882a593Smuzhiyun             break;
9586*4882a593Smuzhiyun         case 1:
9587*4882a593Smuzhiyun             DECODE_PRINTF("ROR\t");
9588*4882a593Smuzhiyun             break;
9589*4882a593Smuzhiyun         case 2:
9590*4882a593Smuzhiyun             DECODE_PRINTF("RCL\t");
9591*4882a593Smuzhiyun             break;
9592*4882a593Smuzhiyun         case 3:
9593*4882a593Smuzhiyun             DECODE_PRINTF("RCR\t");
9594*4882a593Smuzhiyun             break;
9595*4882a593Smuzhiyun         case 4:
9596*4882a593Smuzhiyun             DECODE_PRINTF("SHL\t");
9597*4882a593Smuzhiyun             break;
9598*4882a593Smuzhiyun         case 5:
9599*4882a593Smuzhiyun             DECODE_PRINTF("SHR\t");
9600*4882a593Smuzhiyun             break;
9601*4882a593Smuzhiyun         case 6:
9602*4882a593Smuzhiyun             DECODE_PRINTF("SAL\t");
9603*4882a593Smuzhiyun             break;
9604*4882a593Smuzhiyun         case 7:
9605*4882a593Smuzhiyun             DECODE_PRINTF("SAR\t");
9606*4882a593Smuzhiyun             break;
9607*4882a593Smuzhiyun         }
9608*4882a593Smuzhiyun     }
9609*4882a593Smuzhiyun #endif
9610*4882a593Smuzhiyun     /* know operation, decode the mod byte to find the addressing
9611*4882a593Smuzhiyun        mode. */
9612*4882a593Smuzhiyun     switch (mod) {
9613*4882a593Smuzhiyun     case 0:
9614*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9615*4882a593Smuzhiyun             u32 destval;
9616*4882a593Smuzhiyun 
9617*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
9618*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
9619*4882a593Smuzhiyun             DECODE_PRINTF(",1\n");
9620*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
9621*4882a593Smuzhiyun             TRACE_AND_STEP();
9622*4882a593Smuzhiyun             destval = (*opcD1_long_operation[rh]) (destval, 1);
9623*4882a593Smuzhiyun             store_data_long(destoffset, destval);
9624*4882a593Smuzhiyun         }
9625*4882a593Smuzhiyun         else {
9626*4882a593Smuzhiyun             u16 destval;
9627*4882a593Smuzhiyun 
9628*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
9629*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
9630*4882a593Smuzhiyun             DECODE_PRINTF(",1\n");
9631*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
9632*4882a593Smuzhiyun             TRACE_AND_STEP();
9633*4882a593Smuzhiyun             destval = (*opcD1_word_operation[rh]) (destval, 1);
9634*4882a593Smuzhiyun             store_data_word(destoffset, destval);
9635*4882a593Smuzhiyun         }
9636*4882a593Smuzhiyun         break;
9637*4882a593Smuzhiyun     case 1:
9638*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9639*4882a593Smuzhiyun             u32 destval;
9640*4882a593Smuzhiyun 
9641*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
9642*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
9643*4882a593Smuzhiyun             DECODE_PRINTF(",1\n");
9644*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
9645*4882a593Smuzhiyun             TRACE_AND_STEP();
9646*4882a593Smuzhiyun             destval = (*opcD1_long_operation[rh]) (destval, 1);
9647*4882a593Smuzhiyun             store_data_long(destoffset, destval);
9648*4882a593Smuzhiyun         }
9649*4882a593Smuzhiyun         else {
9650*4882a593Smuzhiyun             u16 destval;
9651*4882a593Smuzhiyun 
9652*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
9653*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
9654*4882a593Smuzhiyun             DECODE_PRINTF(",1\n");
9655*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
9656*4882a593Smuzhiyun             TRACE_AND_STEP();
9657*4882a593Smuzhiyun             destval = (*opcD1_word_operation[rh]) (destval, 1);
9658*4882a593Smuzhiyun             store_data_word(destoffset, destval);
9659*4882a593Smuzhiyun         }
9660*4882a593Smuzhiyun         break;
9661*4882a593Smuzhiyun     case 2:
9662*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9663*4882a593Smuzhiyun             u32 destval;
9664*4882a593Smuzhiyun 
9665*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
9666*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
9667*4882a593Smuzhiyun             DECODE_PRINTF(",1\n");
9668*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
9669*4882a593Smuzhiyun             TRACE_AND_STEP();
9670*4882a593Smuzhiyun             destval = (*opcD1_long_operation[rh]) (destval, 1);
9671*4882a593Smuzhiyun             store_data_long(destoffset, destval);
9672*4882a593Smuzhiyun         }
9673*4882a593Smuzhiyun         else {
9674*4882a593Smuzhiyun             u16 destval;
9675*4882a593Smuzhiyun 
9676*4882a593Smuzhiyun             DECODE_PRINTF("BYTE PTR ");
9677*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
9678*4882a593Smuzhiyun             DECODE_PRINTF(",1\n");
9679*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
9680*4882a593Smuzhiyun             TRACE_AND_STEP();
9681*4882a593Smuzhiyun             destval = (*opcD1_word_operation[rh]) (destval, 1);
9682*4882a593Smuzhiyun             store_data_word(destoffset, destval);
9683*4882a593Smuzhiyun         }
9684*4882a593Smuzhiyun         break;
9685*4882a593Smuzhiyun     case 3:                    /* register to register */
9686*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9687*4882a593Smuzhiyun             u32 destval;
9688*4882a593Smuzhiyun             u32 *destreg;
9689*4882a593Smuzhiyun 
9690*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
9691*4882a593Smuzhiyun             DECODE_PRINTF(",1\n");
9692*4882a593Smuzhiyun             TRACE_AND_STEP();
9693*4882a593Smuzhiyun             destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9694*4882a593Smuzhiyun             *destreg = destval;
9695*4882a593Smuzhiyun         }
9696*4882a593Smuzhiyun         else {
9697*4882a593Smuzhiyun             u16 destval;
9698*4882a593Smuzhiyun             u16 *destreg;
9699*4882a593Smuzhiyun 
9700*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
9701*4882a593Smuzhiyun             DECODE_PRINTF(",1\n");
9702*4882a593Smuzhiyun             TRACE_AND_STEP();
9703*4882a593Smuzhiyun             destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9704*4882a593Smuzhiyun             *destreg = destval;
9705*4882a593Smuzhiyun         }
9706*4882a593Smuzhiyun         break;
9707*4882a593Smuzhiyun     }
9708*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9709*4882a593Smuzhiyun     END_OF_INSTR();
9710*4882a593Smuzhiyun }
9711*4882a593Smuzhiyun 
9712*4882a593Smuzhiyun /****************************************************************************
9713*4882a593Smuzhiyun REMARKS:
9714*4882a593Smuzhiyun Handles opcode 0xd2
9715*4882a593Smuzhiyun ****************************************************************************/
9716*4882a593Smuzhiyun static void
x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED (op1))9717*4882a593Smuzhiyun x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9718*4882a593Smuzhiyun {
9719*4882a593Smuzhiyun     int mod, rl, rh;
9720*4882a593Smuzhiyun     u8 *destreg;
9721*4882a593Smuzhiyun     uint destoffset;
9722*4882a593Smuzhiyun     u8 destval;
9723*4882a593Smuzhiyun     u8 amt;
9724*4882a593Smuzhiyun 
9725*4882a593Smuzhiyun     /*
9726*4882a593Smuzhiyun      * Yet another weirdo special case instruction format.  Part of
9727*4882a593Smuzhiyun      * the opcode held below in "RH".  Doubly nested case would
9728*4882a593Smuzhiyun      * result, except that the decoded instruction
9729*4882a593Smuzhiyun      */
9730*4882a593Smuzhiyun     START_OF_INSTR();
9731*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
9732*4882a593Smuzhiyun #ifdef DEBUG
9733*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
9734*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
9735*4882a593Smuzhiyun            general, so that it is important to leave the strings
9736*4882a593Smuzhiyun            in the same format, even though the result is that the
9737*4882a593Smuzhiyun            above test is done twice. */
9738*4882a593Smuzhiyun         switch (rh) {
9739*4882a593Smuzhiyun         case 0:
9740*4882a593Smuzhiyun             DECODE_PRINTF("ROL\t");
9741*4882a593Smuzhiyun             break;
9742*4882a593Smuzhiyun         case 1:
9743*4882a593Smuzhiyun             DECODE_PRINTF("ROR\t");
9744*4882a593Smuzhiyun             break;
9745*4882a593Smuzhiyun         case 2:
9746*4882a593Smuzhiyun             DECODE_PRINTF("RCL\t");
9747*4882a593Smuzhiyun             break;
9748*4882a593Smuzhiyun         case 3:
9749*4882a593Smuzhiyun             DECODE_PRINTF("RCR\t");
9750*4882a593Smuzhiyun             break;
9751*4882a593Smuzhiyun         case 4:
9752*4882a593Smuzhiyun             DECODE_PRINTF("SHL\t");
9753*4882a593Smuzhiyun             break;
9754*4882a593Smuzhiyun         case 5:
9755*4882a593Smuzhiyun             DECODE_PRINTF("SHR\t");
9756*4882a593Smuzhiyun             break;
9757*4882a593Smuzhiyun         case 6:
9758*4882a593Smuzhiyun             DECODE_PRINTF("SAL\t");
9759*4882a593Smuzhiyun             break;
9760*4882a593Smuzhiyun         case 7:
9761*4882a593Smuzhiyun             DECODE_PRINTF("SAR\t");
9762*4882a593Smuzhiyun             break;
9763*4882a593Smuzhiyun         }
9764*4882a593Smuzhiyun     }
9765*4882a593Smuzhiyun #endif
9766*4882a593Smuzhiyun     /* know operation, decode the mod byte to find the addressing
9767*4882a593Smuzhiyun        mode. */
9768*4882a593Smuzhiyun     amt = M.x86.R_CL;
9769*4882a593Smuzhiyun     switch (mod) {
9770*4882a593Smuzhiyun     case 0:
9771*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
9772*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
9773*4882a593Smuzhiyun         DECODE_PRINTF(",CL\n");
9774*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
9775*4882a593Smuzhiyun         TRACE_AND_STEP();
9776*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9777*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
9778*4882a593Smuzhiyun         break;
9779*4882a593Smuzhiyun     case 1:
9780*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
9781*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
9782*4882a593Smuzhiyun         DECODE_PRINTF(",CL\n");
9783*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
9784*4882a593Smuzhiyun         TRACE_AND_STEP();
9785*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9786*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
9787*4882a593Smuzhiyun         break;
9788*4882a593Smuzhiyun     case 2:
9789*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
9790*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
9791*4882a593Smuzhiyun         DECODE_PRINTF(",CL\n");
9792*4882a593Smuzhiyun         destval = fetch_data_byte(destoffset);
9793*4882a593Smuzhiyun         TRACE_AND_STEP();
9794*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9795*4882a593Smuzhiyun         store_data_byte(destoffset, destval);
9796*4882a593Smuzhiyun         break;
9797*4882a593Smuzhiyun     case 3:                    /* register to register */
9798*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
9799*4882a593Smuzhiyun         DECODE_PRINTF(",CL\n");
9800*4882a593Smuzhiyun         TRACE_AND_STEP();
9801*4882a593Smuzhiyun         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9802*4882a593Smuzhiyun         *destreg = destval;
9803*4882a593Smuzhiyun         break;
9804*4882a593Smuzhiyun     }
9805*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9806*4882a593Smuzhiyun     END_OF_INSTR();
9807*4882a593Smuzhiyun }
9808*4882a593Smuzhiyun 
9809*4882a593Smuzhiyun /****************************************************************************
9810*4882a593Smuzhiyun REMARKS:
9811*4882a593Smuzhiyun Handles opcode 0xd3
9812*4882a593Smuzhiyun ****************************************************************************/
9813*4882a593Smuzhiyun static void
x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED (op1))9814*4882a593Smuzhiyun x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9815*4882a593Smuzhiyun {
9816*4882a593Smuzhiyun     int mod, rl, rh;
9817*4882a593Smuzhiyun     uint destoffset;
9818*4882a593Smuzhiyun     u8 amt;
9819*4882a593Smuzhiyun 
9820*4882a593Smuzhiyun     /*
9821*4882a593Smuzhiyun      * Yet another weirdo special case instruction format.  Part of
9822*4882a593Smuzhiyun      * the opcode held below in "RH".  Doubly nested case would
9823*4882a593Smuzhiyun      * result, except that the decoded instruction
9824*4882a593Smuzhiyun      */
9825*4882a593Smuzhiyun     START_OF_INSTR();
9826*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
9827*4882a593Smuzhiyun #ifdef DEBUG
9828*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
9829*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
9830*4882a593Smuzhiyun            general, so that it is important to leave the strings
9831*4882a593Smuzhiyun            in the same format, even though the result is that the
9832*4882a593Smuzhiyun            above test is done twice. */
9833*4882a593Smuzhiyun         switch (rh) {
9834*4882a593Smuzhiyun         case 0:
9835*4882a593Smuzhiyun             DECODE_PRINTF("ROL\t");
9836*4882a593Smuzhiyun             break;
9837*4882a593Smuzhiyun         case 1:
9838*4882a593Smuzhiyun             DECODE_PRINTF("ROR\t");
9839*4882a593Smuzhiyun             break;
9840*4882a593Smuzhiyun         case 2:
9841*4882a593Smuzhiyun             DECODE_PRINTF("RCL\t");
9842*4882a593Smuzhiyun             break;
9843*4882a593Smuzhiyun         case 3:
9844*4882a593Smuzhiyun             DECODE_PRINTF("RCR\t");
9845*4882a593Smuzhiyun             break;
9846*4882a593Smuzhiyun         case 4:
9847*4882a593Smuzhiyun             DECODE_PRINTF("SHL\t");
9848*4882a593Smuzhiyun             break;
9849*4882a593Smuzhiyun         case 5:
9850*4882a593Smuzhiyun             DECODE_PRINTF("SHR\t");
9851*4882a593Smuzhiyun             break;
9852*4882a593Smuzhiyun         case 6:
9853*4882a593Smuzhiyun             DECODE_PRINTF("SAL\t");
9854*4882a593Smuzhiyun             break;
9855*4882a593Smuzhiyun         case 7:
9856*4882a593Smuzhiyun             DECODE_PRINTF("SAR\t");
9857*4882a593Smuzhiyun             break;
9858*4882a593Smuzhiyun         }
9859*4882a593Smuzhiyun     }
9860*4882a593Smuzhiyun #endif
9861*4882a593Smuzhiyun     /* know operation, decode the mod byte to find the addressing
9862*4882a593Smuzhiyun        mode. */
9863*4882a593Smuzhiyun     amt = M.x86.R_CL;
9864*4882a593Smuzhiyun     switch (mod) {
9865*4882a593Smuzhiyun     case 0:
9866*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9867*4882a593Smuzhiyun             u32 destval;
9868*4882a593Smuzhiyun 
9869*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
9870*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
9871*4882a593Smuzhiyun             DECODE_PRINTF(",CL\n");
9872*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
9873*4882a593Smuzhiyun             TRACE_AND_STEP();
9874*4882a593Smuzhiyun             destval = (*opcD1_long_operation[rh]) (destval, amt);
9875*4882a593Smuzhiyun             store_data_long(destoffset, destval);
9876*4882a593Smuzhiyun         }
9877*4882a593Smuzhiyun         else {
9878*4882a593Smuzhiyun             u16 destval;
9879*4882a593Smuzhiyun 
9880*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
9881*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
9882*4882a593Smuzhiyun             DECODE_PRINTF(",CL\n");
9883*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
9884*4882a593Smuzhiyun             TRACE_AND_STEP();
9885*4882a593Smuzhiyun             destval = (*opcD1_word_operation[rh]) (destval, amt);
9886*4882a593Smuzhiyun             store_data_word(destoffset, destval);
9887*4882a593Smuzhiyun         }
9888*4882a593Smuzhiyun         break;
9889*4882a593Smuzhiyun     case 1:
9890*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9891*4882a593Smuzhiyun             u32 destval;
9892*4882a593Smuzhiyun 
9893*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
9894*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
9895*4882a593Smuzhiyun             DECODE_PRINTF(",CL\n");
9896*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
9897*4882a593Smuzhiyun             TRACE_AND_STEP();
9898*4882a593Smuzhiyun             destval = (*opcD1_long_operation[rh]) (destval, amt);
9899*4882a593Smuzhiyun             store_data_long(destoffset, destval);
9900*4882a593Smuzhiyun         }
9901*4882a593Smuzhiyun         else {
9902*4882a593Smuzhiyun             u16 destval;
9903*4882a593Smuzhiyun 
9904*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
9905*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
9906*4882a593Smuzhiyun             DECODE_PRINTF(",CL\n");
9907*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
9908*4882a593Smuzhiyun             TRACE_AND_STEP();
9909*4882a593Smuzhiyun             destval = (*opcD1_word_operation[rh]) (destval, amt);
9910*4882a593Smuzhiyun             store_data_word(destoffset, destval);
9911*4882a593Smuzhiyun         }
9912*4882a593Smuzhiyun         break;
9913*4882a593Smuzhiyun     case 2:
9914*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9915*4882a593Smuzhiyun             u32 destval;
9916*4882a593Smuzhiyun 
9917*4882a593Smuzhiyun             DECODE_PRINTF("DWORD PTR ");
9918*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
9919*4882a593Smuzhiyun             DECODE_PRINTF(",CL\n");
9920*4882a593Smuzhiyun             destval = fetch_data_long(destoffset);
9921*4882a593Smuzhiyun             TRACE_AND_STEP();
9922*4882a593Smuzhiyun             destval = (*opcD1_long_operation[rh]) (destval, amt);
9923*4882a593Smuzhiyun             store_data_long(destoffset, destval);
9924*4882a593Smuzhiyun         }
9925*4882a593Smuzhiyun         else {
9926*4882a593Smuzhiyun             u16 destval;
9927*4882a593Smuzhiyun 
9928*4882a593Smuzhiyun             DECODE_PRINTF("WORD PTR ");
9929*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
9930*4882a593Smuzhiyun             DECODE_PRINTF(",CL\n");
9931*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
9932*4882a593Smuzhiyun             TRACE_AND_STEP();
9933*4882a593Smuzhiyun             destval = (*opcD1_word_operation[rh]) (destval, amt);
9934*4882a593Smuzhiyun             store_data_word(destoffset, destval);
9935*4882a593Smuzhiyun         }
9936*4882a593Smuzhiyun         break;
9937*4882a593Smuzhiyun     case 3:                    /* register to register */
9938*4882a593Smuzhiyun         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9939*4882a593Smuzhiyun             u32 *destreg;
9940*4882a593Smuzhiyun 
9941*4882a593Smuzhiyun             destreg = DECODE_RM_LONG_REGISTER(rl);
9942*4882a593Smuzhiyun             DECODE_PRINTF(",CL\n");
9943*4882a593Smuzhiyun             TRACE_AND_STEP();
9944*4882a593Smuzhiyun             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9945*4882a593Smuzhiyun         }
9946*4882a593Smuzhiyun         else {
9947*4882a593Smuzhiyun             u16 *destreg;
9948*4882a593Smuzhiyun 
9949*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
9950*4882a593Smuzhiyun             DECODE_PRINTF(",CL\n");
9951*4882a593Smuzhiyun             TRACE_AND_STEP();
9952*4882a593Smuzhiyun             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9953*4882a593Smuzhiyun         }
9954*4882a593Smuzhiyun         break;
9955*4882a593Smuzhiyun     }
9956*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9957*4882a593Smuzhiyun     END_OF_INSTR();
9958*4882a593Smuzhiyun }
9959*4882a593Smuzhiyun 
9960*4882a593Smuzhiyun /****************************************************************************
9961*4882a593Smuzhiyun REMARKS:
9962*4882a593Smuzhiyun Handles opcode 0xd4
9963*4882a593Smuzhiyun ****************************************************************************/
9964*4882a593Smuzhiyun static void
x86emuOp_aam(u8 X86EMU_UNUSED (op1))9965*4882a593Smuzhiyun x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9966*4882a593Smuzhiyun {
9967*4882a593Smuzhiyun     u8 a;
9968*4882a593Smuzhiyun 
9969*4882a593Smuzhiyun     START_OF_INSTR();
9970*4882a593Smuzhiyun     DECODE_PRINTF("AAM\n");
9971*4882a593Smuzhiyun     a = fetch_byte_imm();       /* this is a stupid encoding. */
9972*4882a593Smuzhiyun     if (a != 10) {
9973*4882a593Smuzhiyun         /* fix: add base decoding
9974*4882a593Smuzhiyun            aam_word(u8 val, int base a) */
9975*4882a593Smuzhiyun         DECODE_PRINTF("ERROR DECODING AAM\n");
9976*4882a593Smuzhiyun         TRACE_REGS();
9977*4882a593Smuzhiyun         HALT_SYS();
9978*4882a593Smuzhiyun     }
9979*4882a593Smuzhiyun     TRACE_AND_STEP();
9980*4882a593Smuzhiyun     /* note the type change here --- returning AL and AH in AX. */
9981*4882a593Smuzhiyun     M.x86.R_AX = aam_word(M.x86.R_AL);
9982*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
9983*4882a593Smuzhiyun     END_OF_INSTR();
9984*4882a593Smuzhiyun }
9985*4882a593Smuzhiyun 
9986*4882a593Smuzhiyun /****************************************************************************
9987*4882a593Smuzhiyun REMARKS:
9988*4882a593Smuzhiyun Handles opcode 0xd5
9989*4882a593Smuzhiyun ****************************************************************************/
9990*4882a593Smuzhiyun static void
x86emuOp_aad(u8 X86EMU_UNUSED (op1))9991*4882a593Smuzhiyun x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9992*4882a593Smuzhiyun {
9993*4882a593Smuzhiyun     u8 a;
9994*4882a593Smuzhiyun 
9995*4882a593Smuzhiyun     START_OF_INSTR();
9996*4882a593Smuzhiyun     DECODE_PRINTF("AAD\n");
9997*4882a593Smuzhiyun     a = fetch_byte_imm();
9998*4882a593Smuzhiyun     if (a != 10) {
9999*4882a593Smuzhiyun         /* fix: add base decoding
10000*4882a593Smuzhiyun            aad_word(u16 val, int base a) */
10001*4882a593Smuzhiyun         DECODE_PRINTF("ERROR DECODING AAM\n");
10002*4882a593Smuzhiyun         TRACE_REGS();
10003*4882a593Smuzhiyun         HALT_SYS();
10004*4882a593Smuzhiyun     }
10005*4882a593Smuzhiyun     TRACE_AND_STEP();
10006*4882a593Smuzhiyun     M.x86.R_AX = aad_word(M.x86.R_AX);
10007*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10008*4882a593Smuzhiyun     END_OF_INSTR();
10009*4882a593Smuzhiyun }
10010*4882a593Smuzhiyun 
10011*4882a593Smuzhiyun /* opcode 0xd6 ILLEGAL OPCODE */
10012*4882a593Smuzhiyun 
10013*4882a593Smuzhiyun /****************************************************************************
10014*4882a593Smuzhiyun REMARKS:
10015*4882a593Smuzhiyun Handles opcode 0xd7
10016*4882a593Smuzhiyun ****************************************************************************/
10017*4882a593Smuzhiyun static void
x86emuOp_xlat(u8 X86EMU_UNUSED (op1))10018*4882a593Smuzhiyun x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
10019*4882a593Smuzhiyun {
10020*4882a593Smuzhiyun     u16 addr;
10021*4882a593Smuzhiyun 
10022*4882a593Smuzhiyun     START_OF_INSTR();
10023*4882a593Smuzhiyun     DECODE_PRINTF("XLAT\n");
10024*4882a593Smuzhiyun     TRACE_AND_STEP();
10025*4882a593Smuzhiyun     addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL);
10026*4882a593Smuzhiyun     M.x86.R_AL = fetch_data_byte(addr);
10027*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10028*4882a593Smuzhiyun     END_OF_INSTR();
10029*4882a593Smuzhiyun }
10030*4882a593Smuzhiyun 
10031*4882a593Smuzhiyun /* instuctions  D8 .. DF are in i87_ops.c */
10032*4882a593Smuzhiyun 
10033*4882a593Smuzhiyun /****************************************************************************
10034*4882a593Smuzhiyun REMARKS:
10035*4882a593Smuzhiyun Handles opcode 0xe0
10036*4882a593Smuzhiyun ****************************************************************************/
10037*4882a593Smuzhiyun static void
x86emuOp_loopne(u8 X86EMU_UNUSED (op1))10038*4882a593Smuzhiyun x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
10039*4882a593Smuzhiyun {
10040*4882a593Smuzhiyun     s16 ip;
10041*4882a593Smuzhiyun 
10042*4882a593Smuzhiyun     START_OF_INSTR();
10043*4882a593Smuzhiyun     DECODE_PRINTF("LOOPNE\t");
10044*4882a593Smuzhiyun     ip = (s8) fetch_byte_imm();
10045*4882a593Smuzhiyun     ip += (s16) M.x86.R_IP;
10046*4882a593Smuzhiyun     DECODE_PRINTF2("%04x\n", ip);
10047*4882a593Smuzhiyun     TRACE_AND_STEP();
10048*4882a593Smuzhiyun     M.x86.R_CX -= 1;
10049*4882a593Smuzhiyun     if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))  /* CX != 0 and !ZF */
10050*4882a593Smuzhiyun         M.x86.R_IP = ip;
10051*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10052*4882a593Smuzhiyun     END_OF_INSTR();
10053*4882a593Smuzhiyun }
10054*4882a593Smuzhiyun 
10055*4882a593Smuzhiyun /****************************************************************************
10056*4882a593Smuzhiyun REMARKS:
10057*4882a593Smuzhiyun Handles opcode 0xe1
10058*4882a593Smuzhiyun ****************************************************************************/
10059*4882a593Smuzhiyun static void
x86emuOp_loope(u8 X86EMU_UNUSED (op1))10060*4882a593Smuzhiyun x86emuOp_loope(u8 X86EMU_UNUSED(op1))
10061*4882a593Smuzhiyun {
10062*4882a593Smuzhiyun     s16 ip;
10063*4882a593Smuzhiyun 
10064*4882a593Smuzhiyun     START_OF_INSTR();
10065*4882a593Smuzhiyun     DECODE_PRINTF("LOOPE\t");
10066*4882a593Smuzhiyun     ip = (s8) fetch_byte_imm();
10067*4882a593Smuzhiyun     ip += (s16) M.x86.R_IP;
10068*4882a593Smuzhiyun     DECODE_PRINTF2("%04x\n", ip);
10069*4882a593Smuzhiyun     TRACE_AND_STEP();
10070*4882a593Smuzhiyun     M.x86.R_CX -= 1;
10071*4882a593Smuzhiyun     if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))   /* CX != 0 and ZF */
10072*4882a593Smuzhiyun         M.x86.R_IP = ip;
10073*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10074*4882a593Smuzhiyun     END_OF_INSTR();
10075*4882a593Smuzhiyun }
10076*4882a593Smuzhiyun 
10077*4882a593Smuzhiyun /****************************************************************************
10078*4882a593Smuzhiyun REMARKS:
10079*4882a593Smuzhiyun Handles opcode 0xe2
10080*4882a593Smuzhiyun ****************************************************************************/
10081*4882a593Smuzhiyun static void
x86emuOp_loop(u8 X86EMU_UNUSED (op1))10082*4882a593Smuzhiyun x86emuOp_loop(u8 X86EMU_UNUSED(op1))
10083*4882a593Smuzhiyun {
10084*4882a593Smuzhiyun     s16 ip;
10085*4882a593Smuzhiyun 
10086*4882a593Smuzhiyun     START_OF_INSTR();
10087*4882a593Smuzhiyun     DECODE_PRINTF("LOOP\t");
10088*4882a593Smuzhiyun     ip = (s8) fetch_byte_imm();
10089*4882a593Smuzhiyun     ip += (s16) M.x86.R_IP;
10090*4882a593Smuzhiyun     DECODE_PRINTF2("%04x\n", ip);
10091*4882a593Smuzhiyun     TRACE_AND_STEP();
10092*4882a593Smuzhiyun     M.x86.R_CX -= 1;
10093*4882a593Smuzhiyun     if (M.x86.R_CX != 0)
10094*4882a593Smuzhiyun         M.x86.R_IP = ip;
10095*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10096*4882a593Smuzhiyun     END_OF_INSTR();
10097*4882a593Smuzhiyun }
10098*4882a593Smuzhiyun 
10099*4882a593Smuzhiyun /****************************************************************************
10100*4882a593Smuzhiyun REMARKS:
10101*4882a593Smuzhiyun Handles opcode 0xe3
10102*4882a593Smuzhiyun ****************************************************************************/
10103*4882a593Smuzhiyun static void
x86emuOp_jcxz(u8 X86EMU_UNUSED (op1))10104*4882a593Smuzhiyun x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
10105*4882a593Smuzhiyun {
10106*4882a593Smuzhiyun     u16 target;
10107*4882a593Smuzhiyun     s8 offset;
10108*4882a593Smuzhiyun 
10109*4882a593Smuzhiyun     /* jump to byte offset if overflow flag is set */
10110*4882a593Smuzhiyun     START_OF_INSTR();
10111*4882a593Smuzhiyun     DECODE_PRINTF("JCXZ\t");
10112*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
10113*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + offset);
10114*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
10115*4882a593Smuzhiyun     TRACE_AND_STEP();
10116*4882a593Smuzhiyun     if (M.x86.R_CX == 0)
10117*4882a593Smuzhiyun         M.x86.R_IP = target;
10118*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10119*4882a593Smuzhiyun     END_OF_INSTR();
10120*4882a593Smuzhiyun }
10121*4882a593Smuzhiyun 
10122*4882a593Smuzhiyun /****************************************************************************
10123*4882a593Smuzhiyun REMARKS:
10124*4882a593Smuzhiyun Handles opcode 0xe4
10125*4882a593Smuzhiyun ****************************************************************************/
10126*4882a593Smuzhiyun static void
x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED (op1))10127*4882a593Smuzhiyun x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
10128*4882a593Smuzhiyun {
10129*4882a593Smuzhiyun     u8 port;
10130*4882a593Smuzhiyun 
10131*4882a593Smuzhiyun     START_OF_INSTR();
10132*4882a593Smuzhiyun     DECODE_PRINTF("IN\t");
10133*4882a593Smuzhiyun     port = (u8) fetch_byte_imm();
10134*4882a593Smuzhiyun     DECODE_PRINTF2("%x,AL\n", port);
10135*4882a593Smuzhiyun     TRACE_AND_STEP();
10136*4882a593Smuzhiyun     M.x86.R_AL = (*sys_inb) (port);
10137*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10138*4882a593Smuzhiyun     END_OF_INSTR();
10139*4882a593Smuzhiyun }
10140*4882a593Smuzhiyun 
10141*4882a593Smuzhiyun /****************************************************************************
10142*4882a593Smuzhiyun REMARKS:
10143*4882a593Smuzhiyun Handles opcode 0xe5
10144*4882a593Smuzhiyun ****************************************************************************/
10145*4882a593Smuzhiyun static void
x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED (op1))10146*4882a593Smuzhiyun x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
10147*4882a593Smuzhiyun {
10148*4882a593Smuzhiyun     u8 port;
10149*4882a593Smuzhiyun 
10150*4882a593Smuzhiyun     START_OF_INSTR();
10151*4882a593Smuzhiyun     DECODE_PRINTF("IN\t");
10152*4882a593Smuzhiyun     port = (u8) fetch_byte_imm();
10153*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10154*4882a593Smuzhiyun         DECODE_PRINTF2("EAX,%x\n", port);
10155*4882a593Smuzhiyun     }
10156*4882a593Smuzhiyun     else {
10157*4882a593Smuzhiyun         DECODE_PRINTF2("AX,%x\n", port);
10158*4882a593Smuzhiyun     }
10159*4882a593Smuzhiyun     TRACE_AND_STEP();
10160*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10161*4882a593Smuzhiyun         M.x86.R_EAX = (*sys_inl) (port);
10162*4882a593Smuzhiyun     }
10163*4882a593Smuzhiyun     else {
10164*4882a593Smuzhiyun         M.x86.R_AX = (*sys_inw) (port);
10165*4882a593Smuzhiyun     }
10166*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10167*4882a593Smuzhiyun     END_OF_INSTR();
10168*4882a593Smuzhiyun }
10169*4882a593Smuzhiyun 
10170*4882a593Smuzhiyun /****************************************************************************
10171*4882a593Smuzhiyun REMARKS:
10172*4882a593Smuzhiyun Handles opcode 0xe6
10173*4882a593Smuzhiyun ****************************************************************************/
10174*4882a593Smuzhiyun static void
x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED (op1))10175*4882a593Smuzhiyun x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
10176*4882a593Smuzhiyun {
10177*4882a593Smuzhiyun     u8 port;
10178*4882a593Smuzhiyun 
10179*4882a593Smuzhiyun     START_OF_INSTR();
10180*4882a593Smuzhiyun     DECODE_PRINTF("OUT\t");
10181*4882a593Smuzhiyun     port = (u8) fetch_byte_imm();
10182*4882a593Smuzhiyun     DECODE_PRINTF2("%x,AL\n", port);
10183*4882a593Smuzhiyun     TRACE_AND_STEP();
10184*4882a593Smuzhiyun     (*sys_outb) (port, M.x86.R_AL);
10185*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10186*4882a593Smuzhiyun     END_OF_INSTR();
10187*4882a593Smuzhiyun }
10188*4882a593Smuzhiyun 
10189*4882a593Smuzhiyun /****************************************************************************
10190*4882a593Smuzhiyun REMARKS:
10191*4882a593Smuzhiyun Handles opcode 0xe7
10192*4882a593Smuzhiyun ****************************************************************************/
10193*4882a593Smuzhiyun static void
x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED (op1))10194*4882a593Smuzhiyun x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
10195*4882a593Smuzhiyun {
10196*4882a593Smuzhiyun     u8 port;
10197*4882a593Smuzhiyun 
10198*4882a593Smuzhiyun     START_OF_INSTR();
10199*4882a593Smuzhiyun     DECODE_PRINTF("OUT\t");
10200*4882a593Smuzhiyun     port = (u8) fetch_byte_imm();
10201*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10202*4882a593Smuzhiyun         DECODE_PRINTF2("%x,EAX\n", port);
10203*4882a593Smuzhiyun     }
10204*4882a593Smuzhiyun     else {
10205*4882a593Smuzhiyun         DECODE_PRINTF2("%x,AX\n", port);
10206*4882a593Smuzhiyun     }
10207*4882a593Smuzhiyun     TRACE_AND_STEP();
10208*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10209*4882a593Smuzhiyun         (*sys_outl) (port, M.x86.R_EAX);
10210*4882a593Smuzhiyun     }
10211*4882a593Smuzhiyun     else {
10212*4882a593Smuzhiyun         (*sys_outw) (port, M.x86.R_AX);
10213*4882a593Smuzhiyun     }
10214*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10215*4882a593Smuzhiyun     END_OF_INSTR();
10216*4882a593Smuzhiyun }
10217*4882a593Smuzhiyun 
10218*4882a593Smuzhiyun /****************************************************************************
10219*4882a593Smuzhiyun REMARKS:
10220*4882a593Smuzhiyun Handles opcode 0xe8
10221*4882a593Smuzhiyun ****************************************************************************/
10222*4882a593Smuzhiyun static void
x86emuOp_call_near_IMM(u8 X86EMU_UNUSED (op1))10223*4882a593Smuzhiyun x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
10224*4882a593Smuzhiyun {
10225*4882a593Smuzhiyun     s16 ip16 = 0;
10226*4882a593Smuzhiyun     s32 ip32 = 0;
10227*4882a593Smuzhiyun 
10228*4882a593Smuzhiyun     START_OF_INSTR();
10229*4882a593Smuzhiyun     DECODE_PRINTF("CALL\t");
10230*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10231*4882a593Smuzhiyun         ip32 = (s32) fetch_long_imm();
10232*4882a593Smuzhiyun         ip32 += (s16) M.x86.R_IP;       /* CHECK SIGN */
10233*4882a593Smuzhiyun         DECODE_PRINTF2("%04x\n", (u16) ip32);
10234*4882a593Smuzhiyun         CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
10235*4882a593Smuzhiyun     }
10236*4882a593Smuzhiyun     else {
10237*4882a593Smuzhiyun         ip16 = (s16) fetch_word_imm();
10238*4882a593Smuzhiyun         ip16 += (s16) M.x86.R_IP;       /* CHECK SIGN */
10239*4882a593Smuzhiyun         DECODE_PRINTF2("%04x\n", (u16) ip16);
10240*4882a593Smuzhiyun         CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
10241*4882a593Smuzhiyun     }
10242*4882a593Smuzhiyun     TRACE_AND_STEP();
10243*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10244*4882a593Smuzhiyun         push_long(M.x86.R_EIP);
10245*4882a593Smuzhiyun         M.x86.R_EIP = ip32 & 0xffff;
10246*4882a593Smuzhiyun     }
10247*4882a593Smuzhiyun     else {
10248*4882a593Smuzhiyun         push_word(M.x86.R_IP);
10249*4882a593Smuzhiyun         M.x86.R_EIP = ip16;
10250*4882a593Smuzhiyun     }
10251*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10252*4882a593Smuzhiyun     END_OF_INSTR();
10253*4882a593Smuzhiyun }
10254*4882a593Smuzhiyun 
10255*4882a593Smuzhiyun /****************************************************************************
10256*4882a593Smuzhiyun REMARKS:
10257*4882a593Smuzhiyun Handles opcode 0xe9
10258*4882a593Smuzhiyun ****************************************************************************/
10259*4882a593Smuzhiyun static void
x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED (op1))10260*4882a593Smuzhiyun x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
10261*4882a593Smuzhiyun {
10262*4882a593Smuzhiyun     u32 ip;
10263*4882a593Smuzhiyun 
10264*4882a593Smuzhiyun     START_OF_INSTR();
10265*4882a593Smuzhiyun     DECODE_PRINTF("JMP\t");
10266*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10267*4882a593Smuzhiyun         ip = (u32) fetch_long_imm();
10268*4882a593Smuzhiyun         ip += (u32) M.x86.R_EIP;
10269*4882a593Smuzhiyun         DECODE_PRINTF2("%08x\n", (u32) ip);
10270*4882a593Smuzhiyun         TRACE_AND_STEP();
10271*4882a593Smuzhiyun         M.x86.R_EIP = (u32) ip;
10272*4882a593Smuzhiyun     }
10273*4882a593Smuzhiyun     else {
10274*4882a593Smuzhiyun         ip = (s16) fetch_word_imm();
10275*4882a593Smuzhiyun         ip += (s16) M.x86.R_IP;
10276*4882a593Smuzhiyun         DECODE_PRINTF2("%04x\n", (u16) ip);
10277*4882a593Smuzhiyun         TRACE_AND_STEP();
10278*4882a593Smuzhiyun         M.x86.R_IP = (u16) ip;
10279*4882a593Smuzhiyun     }
10280*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10281*4882a593Smuzhiyun     END_OF_INSTR();
10282*4882a593Smuzhiyun }
10283*4882a593Smuzhiyun 
10284*4882a593Smuzhiyun /****************************************************************************
10285*4882a593Smuzhiyun REMARKS:
10286*4882a593Smuzhiyun Handles opcode 0xea
10287*4882a593Smuzhiyun ****************************************************************************/
10288*4882a593Smuzhiyun static void
x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED (op1))10289*4882a593Smuzhiyun x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
10290*4882a593Smuzhiyun {
10291*4882a593Smuzhiyun     u16 cs;
10292*4882a593Smuzhiyun     u32 ip;
10293*4882a593Smuzhiyun 
10294*4882a593Smuzhiyun     START_OF_INSTR();
10295*4882a593Smuzhiyun     DECODE_PRINTF("JMP\tFAR ");
10296*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10297*4882a593Smuzhiyun         ip = fetch_long_imm();
10298*4882a593Smuzhiyun     }
10299*4882a593Smuzhiyun     else {
10300*4882a593Smuzhiyun         ip = fetch_word_imm();
10301*4882a593Smuzhiyun     }
10302*4882a593Smuzhiyun     cs = fetch_word_imm();
10303*4882a593Smuzhiyun     DECODE_PRINTF2("%04x:", cs);
10304*4882a593Smuzhiyun     DECODE_PRINTF2("%04x\n", ip);
10305*4882a593Smuzhiyun     TRACE_AND_STEP();
10306*4882a593Smuzhiyun     M.x86.R_EIP = ip & 0xffff;
10307*4882a593Smuzhiyun     M.x86.R_CS = cs;
10308*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10309*4882a593Smuzhiyun     END_OF_INSTR();
10310*4882a593Smuzhiyun }
10311*4882a593Smuzhiyun 
10312*4882a593Smuzhiyun /****************************************************************************
10313*4882a593Smuzhiyun REMARKS:
10314*4882a593Smuzhiyun Handles opcode 0xeb
10315*4882a593Smuzhiyun ****************************************************************************/
10316*4882a593Smuzhiyun static void
x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED (op1))10317*4882a593Smuzhiyun x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
10318*4882a593Smuzhiyun {
10319*4882a593Smuzhiyun     u16 target;
10320*4882a593Smuzhiyun     s8 offset;
10321*4882a593Smuzhiyun 
10322*4882a593Smuzhiyun     START_OF_INSTR();
10323*4882a593Smuzhiyun     DECODE_PRINTF("JMP\t");
10324*4882a593Smuzhiyun     offset = (s8) fetch_byte_imm();
10325*4882a593Smuzhiyun     target = (u16) (M.x86.R_IP + offset);
10326*4882a593Smuzhiyun     DECODE_PRINTF2("%x\n", target);
10327*4882a593Smuzhiyun     TRACE_AND_STEP();
10328*4882a593Smuzhiyun     M.x86.R_IP = target;
10329*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10330*4882a593Smuzhiyun     END_OF_INSTR();
10331*4882a593Smuzhiyun }
10332*4882a593Smuzhiyun 
10333*4882a593Smuzhiyun /****************************************************************************
10334*4882a593Smuzhiyun REMARKS:
10335*4882a593Smuzhiyun Handles opcode 0xec
10336*4882a593Smuzhiyun ****************************************************************************/
10337*4882a593Smuzhiyun static void
x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED (op1))10338*4882a593Smuzhiyun x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
10339*4882a593Smuzhiyun {
10340*4882a593Smuzhiyun     START_OF_INSTR();
10341*4882a593Smuzhiyun     DECODE_PRINTF("IN\tAL,DX\n");
10342*4882a593Smuzhiyun     TRACE_AND_STEP();
10343*4882a593Smuzhiyun     M.x86.R_AL = (*sys_inb) (M.x86.R_DX);
10344*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10345*4882a593Smuzhiyun     END_OF_INSTR();
10346*4882a593Smuzhiyun }
10347*4882a593Smuzhiyun 
10348*4882a593Smuzhiyun /****************************************************************************
10349*4882a593Smuzhiyun REMARKS:
10350*4882a593Smuzhiyun Handles opcode 0xed
10351*4882a593Smuzhiyun ****************************************************************************/
10352*4882a593Smuzhiyun static void
x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED (op1))10353*4882a593Smuzhiyun x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
10354*4882a593Smuzhiyun {
10355*4882a593Smuzhiyun     START_OF_INSTR();
10356*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10357*4882a593Smuzhiyun         DECODE_PRINTF("IN\tEAX,DX\n");
10358*4882a593Smuzhiyun     }
10359*4882a593Smuzhiyun     else {
10360*4882a593Smuzhiyun         DECODE_PRINTF("IN\tAX,DX\n");
10361*4882a593Smuzhiyun     }
10362*4882a593Smuzhiyun     TRACE_AND_STEP();
10363*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10364*4882a593Smuzhiyun         M.x86.R_EAX = (*sys_inl) (M.x86.R_DX);
10365*4882a593Smuzhiyun     }
10366*4882a593Smuzhiyun     else {
10367*4882a593Smuzhiyun         M.x86.R_AX = (*sys_inw) (M.x86.R_DX);
10368*4882a593Smuzhiyun     }
10369*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10370*4882a593Smuzhiyun     END_OF_INSTR();
10371*4882a593Smuzhiyun }
10372*4882a593Smuzhiyun 
10373*4882a593Smuzhiyun /****************************************************************************
10374*4882a593Smuzhiyun REMARKS:
10375*4882a593Smuzhiyun Handles opcode 0xee
10376*4882a593Smuzhiyun ****************************************************************************/
10377*4882a593Smuzhiyun static void
x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED (op1))10378*4882a593Smuzhiyun x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
10379*4882a593Smuzhiyun {
10380*4882a593Smuzhiyun     START_OF_INSTR();
10381*4882a593Smuzhiyun     DECODE_PRINTF("OUT\tDX,AL\n");
10382*4882a593Smuzhiyun     TRACE_AND_STEP();
10383*4882a593Smuzhiyun     (*sys_outb) (M.x86.R_DX, M.x86.R_AL);
10384*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10385*4882a593Smuzhiyun     END_OF_INSTR();
10386*4882a593Smuzhiyun }
10387*4882a593Smuzhiyun 
10388*4882a593Smuzhiyun /****************************************************************************
10389*4882a593Smuzhiyun REMARKS:
10390*4882a593Smuzhiyun Handles opcode 0xef
10391*4882a593Smuzhiyun ****************************************************************************/
10392*4882a593Smuzhiyun static void
x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED (op1))10393*4882a593Smuzhiyun x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
10394*4882a593Smuzhiyun {
10395*4882a593Smuzhiyun     START_OF_INSTR();
10396*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10397*4882a593Smuzhiyun         DECODE_PRINTF("OUT\tDX,EAX\n");
10398*4882a593Smuzhiyun     }
10399*4882a593Smuzhiyun     else {
10400*4882a593Smuzhiyun         DECODE_PRINTF("OUT\tDX,AX\n");
10401*4882a593Smuzhiyun     }
10402*4882a593Smuzhiyun     TRACE_AND_STEP();
10403*4882a593Smuzhiyun     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10404*4882a593Smuzhiyun         (*sys_outl) (M.x86.R_DX, M.x86.R_EAX);
10405*4882a593Smuzhiyun     }
10406*4882a593Smuzhiyun     else {
10407*4882a593Smuzhiyun         (*sys_outw) (M.x86.R_DX, M.x86.R_AX);
10408*4882a593Smuzhiyun     }
10409*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10410*4882a593Smuzhiyun     END_OF_INSTR();
10411*4882a593Smuzhiyun }
10412*4882a593Smuzhiyun 
10413*4882a593Smuzhiyun /****************************************************************************
10414*4882a593Smuzhiyun REMARKS:
10415*4882a593Smuzhiyun Handles opcode 0xf0
10416*4882a593Smuzhiyun ****************************************************************************/
10417*4882a593Smuzhiyun static void
x86emuOp_lock(u8 X86EMU_UNUSED (op1))10418*4882a593Smuzhiyun x86emuOp_lock(u8 X86EMU_UNUSED(op1))
10419*4882a593Smuzhiyun {
10420*4882a593Smuzhiyun     START_OF_INSTR();
10421*4882a593Smuzhiyun     DECODE_PRINTF("LOCK:\n");
10422*4882a593Smuzhiyun     TRACE_AND_STEP();
10423*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10424*4882a593Smuzhiyun     END_OF_INSTR();
10425*4882a593Smuzhiyun }
10426*4882a593Smuzhiyun 
10427*4882a593Smuzhiyun /*opcode 0xf1 ILLEGAL OPERATION */
10428*4882a593Smuzhiyun 
10429*4882a593Smuzhiyun /****************************************************************************
10430*4882a593Smuzhiyun REMARKS:
10431*4882a593Smuzhiyun Handles opcode 0xf2
10432*4882a593Smuzhiyun ****************************************************************************/
10433*4882a593Smuzhiyun static void
x86emuOp_repne(u8 X86EMU_UNUSED (op1))10434*4882a593Smuzhiyun x86emuOp_repne(u8 X86EMU_UNUSED(op1))
10435*4882a593Smuzhiyun {
10436*4882a593Smuzhiyun     START_OF_INSTR();
10437*4882a593Smuzhiyun     DECODE_PRINTF("REPNE\n");
10438*4882a593Smuzhiyun     TRACE_AND_STEP();
10439*4882a593Smuzhiyun     M.x86.mode |= SYSMODE_PREFIX_REPNE;
10440*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10441*4882a593Smuzhiyun     END_OF_INSTR();
10442*4882a593Smuzhiyun }
10443*4882a593Smuzhiyun 
10444*4882a593Smuzhiyun /****************************************************************************
10445*4882a593Smuzhiyun REMARKS:
10446*4882a593Smuzhiyun Handles opcode 0xf3
10447*4882a593Smuzhiyun ****************************************************************************/
10448*4882a593Smuzhiyun static void
x86emuOp_repe(u8 X86EMU_UNUSED (op1))10449*4882a593Smuzhiyun x86emuOp_repe(u8 X86EMU_UNUSED(op1))
10450*4882a593Smuzhiyun {
10451*4882a593Smuzhiyun     START_OF_INSTR();
10452*4882a593Smuzhiyun     DECODE_PRINTF("REPE\n");
10453*4882a593Smuzhiyun     TRACE_AND_STEP();
10454*4882a593Smuzhiyun     M.x86.mode |= SYSMODE_PREFIX_REPE;
10455*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10456*4882a593Smuzhiyun     END_OF_INSTR();
10457*4882a593Smuzhiyun }
10458*4882a593Smuzhiyun 
10459*4882a593Smuzhiyun /****************************************************************************
10460*4882a593Smuzhiyun REMARKS:
10461*4882a593Smuzhiyun Handles opcode 0xf4
10462*4882a593Smuzhiyun ****************************************************************************/
10463*4882a593Smuzhiyun static void
x86emuOp_halt(u8 X86EMU_UNUSED (op1))10464*4882a593Smuzhiyun x86emuOp_halt(u8 X86EMU_UNUSED(op1))
10465*4882a593Smuzhiyun {
10466*4882a593Smuzhiyun     START_OF_INSTR();
10467*4882a593Smuzhiyun     DECODE_PRINTF("HALT\n");
10468*4882a593Smuzhiyun     TRACE_AND_STEP();
10469*4882a593Smuzhiyun     HALT_SYS();
10470*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10471*4882a593Smuzhiyun     END_OF_INSTR();
10472*4882a593Smuzhiyun }
10473*4882a593Smuzhiyun 
10474*4882a593Smuzhiyun /****************************************************************************
10475*4882a593Smuzhiyun REMARKS:
10476*4882a593Smuzhiyun Handles opcode 0xf5
10477*4882a593Smuzhiyun ****************************************************************************/
10478*4882a593Smuzhiyun static void
x86emuOp_cmc(u8 X86EMU_UNUSED (op1))10479*4882a593Smuzhiyun x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
10480*4882a593Smuzhiyun {
10481*4882a593Smuzhiyun     /* complement the carry flag. */
10482*4882a593Smuzhiyun     START_OF_INSTR();
10483*4882a593Smuzhiyun     DECODE_PRINTF("CMC\n");
10484*4882a593Smuzhiyun     TRACE_AND_STEP();
10485*4882a593Smuzhiyun     TOGGLE_FLAG(F_CF);
10486*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10487*4882a593Smuzhiyun     END_OF_INSTR();
10488*4882a593Smuzhiyun }
10489*4882a593Smuzhiyun 
10490*4882a593Smuzhiyun /****************************************************************************
10491*4882a593Smuzhiyun REMARKS:
10492*4882a593Smuzhiyun Handles opcode 0xf6
10493*4882a593Smuzhiyun ****************************************************************************/
10494*4882a593Smuzhiyun static void
x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED (op1))10495*4882a593Smuzhiyun x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
10496*4882a593Smuzhiyun {
10497*4882a593Smuzhiyun     int mod, rl, rh;
10498*4882a593Smuzhiyun     u8 *destreg;
10499*4882a593Smuzhiyun     uint destoffset;
10500*4882a593Smuzhiyun     u8 destval, srcval;
10501*4882a593Smuzhiyun 
10502*4882a593Smuzhiyun     /* long, drawn out code follows.  Double switch for a total
10503*4882a593Smuzhiyun        of 32 cases.  */
10504*4882a593Smuzhiyun     START_OF_INSTR();
10505*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
10506*4882a593Smuzhiyun     switch (mod) {
10507*4882a593Smuzhiyun     case 0:                    /* mod=00 */
10508*4882a593Smuzhiyun         switch (rh) {
10509*4882a593Smuzhiyun         case 0:                /* test byte imm */
10510*4882a593Smuzhiyun             DECODE_PRINTF("TEST\tBYTE PTR ");
10511*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
10512*4882a593Smuzhiyun             DECODE_PRINTF(",");
10513*4882a593Smuzhiyun             srcval = fetch_byte_imm();
10514*4882a593Smuzhiyun             DECODE_PRINTF2("%02x\n", srcval);
10515*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10516*4882a593Smuzhiyun             TRACE_AND_STEP();
10517*4882a593Smuzhiyun             test_byte(destval, srcval);
10518*4882a593Smuzhiyun             break;
10519*4882a593Smuzhiyun         case 1:
10520*4882a593Smuzhiyun             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10521*4882a593Smuzhiyun             HALT_SYS();
10522*4882a593Smuzhiyun             break;
10523*4882a593Smuzhiyun         case 2:
10524*4882a593Smuzhiyun             DECODE_PRINTF("NOT\tBYTE PTR ");
10525*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
10526*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10527*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10528*4882a593Smuzhiyun             TRACE_AND_STEP();
10529*4882a593Smuzhiyun             destval = not_byte(destval);
10530*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
10531*4882a593Smuzhiyun             break;
10532*4882a593Smuzhiyun         case 3:
10533*4882a593Smuzhiyun             DECODE_PRINTF("NEG\tBYTE PTR ");
10534*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
10535*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10536*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10537*4882a593Smuzhiyun             TRACE_AND_STEP();
10538*4882a593Smuzhiyun             destval = neg_byte(destval);
10539*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
10540*4882a593Smuzhiyun             break;
10541*4882a593Smuzhiyun         case 4:
10542*4882a593Smuzhiyun             DECODE_PRINTF("MUL\tBYTE PTR ");
10543*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
10544*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10545*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10546*4882a593Smuzhiyun             TRACE_AND_STEP();
10547*4882a593Smuzhiyun             mul_byte(destval);
10548*4882a593Smuzhiyun             break;
10549*4882a593Smuzhiyun         case 5:
10550*4882a593Smuzhiyun             DECODE_PRINTF("IMUL\tBYTE PTR ");
10551*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
10552*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10553*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10554*4882a593Smuzhiyun             TRACE_AND_STEP();
10555*4882a593Smuzhiyun             imul_byte(destval);
10556*4882a593Smuzhiyun             break;
10557*4882a593Smuzhiyun         case 6:
10558*4882a593Smuzhiyun             DECODE_PRINTF("DIV\tBYTE PTR ");
10559*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
10560*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10561*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10562*4882a593Smuzhiyun             TRACE_AND_STEP();
10563*4882a593Smuzhiyun             div_byte(destval);
10564*4882a593Smuzhiyun             break;
10565*4882a593Smuzhiyun         case 7:
10566*4882a593Smuzhiyun             DECODE_PRINTF("IDIV\tBYTE PTR ");
10567*4882a593Smuzhiyun             destoffset = decode_rm00_address(rl);
10568*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10569*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10570*4882a593Smuzhiyun             TRACE_AND_STEP();
10571*4882a593Smuzhiyun             idiv_byte(destval);
10572*4882a593Smuzhiyun             break;
10573*4882a593Smuzhiyun         }
10574*4882a593Smuzhiyun         break;                  /* end mod==00 */
10575*4882a593Smuzhiyun     case 1:                    /* mod=01 */
10576*4882a593Smuzhiyun         switch (rh) {
10577*4882a593Smuzhiyun         case 0:                /* test byte imm */
10578*4882a593Smuzhiyun             DECODE_PRINTF("TEST\tBYTE PTR ");
10579*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
10580*4882a593Smuzhiyun             DECODE_PRINTF(",");
10581*4882a593Smuzhiyun             srcval = fetch_byte_imm();
10582*4882a593Smuzhiyun             DECODE_PRINTF2("%02x\n", srcval);
10583*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10584*4882a593Smuzhiyun             TRACE_AND_STEP();
10585*4882a593Smuzhiyun             test_byte(destval, srcval);
10586*4882a593Smuzhiyun             break;
10587*4882a593Smuzhiyun         case 1:
10588*4882a593Smuzhiyun             DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10589*4882a593Smuzhiyun             HALT_SYS();
10590*4882a593Smuzhiyun             break;
10591*4882a593Smuzhiyun         case 2:
10592*4882a593Smuzhiyun             DECODE_PRINTF("NOT\tBYTE PTR ");
10593*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
10594*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10595*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10596*4882a593Smuzhiyun             TRACE_AND_STEP();
10597*4882a593Smuzhiyun             destval = not_byte(destval);
10598*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
10599*4882a593Smuzhiyun             break;
10600*4882a593Smuzhiyun         case 3:
10601*4882a593Smuzhiyun             DECODE_PRINTF("NEG\tBYTE PTR ");
10602*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
10603*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10604*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10605*4882a593Smuzhiyun             TRACE_AND_STEP();
10606*4882a593Smuzhiyun             destval = neg_byte(destval);
10607*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
10608*4882a593Smuzhiyun             break;
10609*4882a593Smuzhiyun         case 4:
10610*4882a593Smuzhiyun             DECODE_PRINTF("MUL\tBYTE PTR ");
10611*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
10612*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10613*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10614*4882a593Smuzhiyun             TRACE_AND_STEP();
10615*4882a593Smuzhiyun             mul_byte(destval);
10616*4882a593Smuzhiyun             break;
10617*4882a593Smuzhiyun         case 5:
10618*4882a593Smuzhiyun             DECODE_PRINTF("IMUL\tBYTE PTR ");
10619*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
10620*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10621*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10622*4882a593Smuzhiyun             TRACE_AND_STEP();
10623*4882a593Smuzhiyun             imul_byte(destval);
10624*4882a593Smuzhiyun             break;
10625*4882a593Smuzhiyun         case 6:
10626*4882a593Smuzhiyun             DECODE_PRINTF("DIV\tBYTE PTR ");
10627*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
10628*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10629*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10630*4882a593Smuzhiyun             TRACE_AND_STEP();
10631*4882a593Smuzhiyun             div_byte(destval);
10632*4882a593Smuzhiyun             break;
10633*4882a593Smuzhiyun         case 7:
10634*4882a593Smuzhiyun             DECODE_PRINTF("IDIV\tBYTE PTR ");
10635*4882a593Smuzhiyun             destoffset = decode_rm01_address(rl);
10636*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10637*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10638*4882a593Smuzhiyun             TRACE_AND_STEP();
10639*4882a593Smuzhiyun             idiv_byte(destval);
10640*4882a593Smuzhiyun             break;
10641*4882a593Smuzhiyun         }
10642*4882a593Smuzhiyun         break;                  /* end mod==01 */
10643*4882a593Smuzhiyun     case 2:                    /* mod=10 */
10644*4882a593Smuzhiyun         switch (rh) {
10645*4882a593Smuzhiyun         case 0:                /* test byte imm */
10646*4882a593Smuzhiyun             DECODE_PRINTF("TEST\tBYTE PTR ");
10647*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
10648*4882a593Smuzhiyun             DECODE_PRINTF(",");
10649*4882a593Smuzhiyun             srcval = fetch_byte_imm();
10650*4882a593Smuzhiyun             DECODE_PRINTF2("%02x\n", srcval);
10651*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10652*4882a593Smuzhiyun             TRACE_AND_STEP();
10653*4882a593Smuzhiyun             test_byte(destval, srcval);
10654*4882a593Smuzhiyun             break;
10655*4882a593Smuzhiyun         case 1:
10656*4882a593Smuzhiyun             DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10657*4882a593Smuzhiyun             HALT_SYS();
10658*4882a593Smuzhiyun             break;
10659*4882a593Smuzhiyun         case 2:
10660*4882a593Smuzhiyun             DECODE_PRINTF("NOT\tBYTE PTR ");
10661*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
10662*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10663*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10664*4882a593Smuzhiyun             TRACE_AND_STEP();
10665*4882a593Smuzhiyun             destval = not_byte(destval);
10666*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
10667*4882a593Smuzhiyun             break;
10668*4882a593Smuzhiyun         case 3:
10669*4882a593Smuzhiyun             DECODE_PRINTF("NEG\tBYTE PTR ");
10670*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
10671*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10672*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10673*4882a593Smuzhiyun             TRACE_AND_STEP();
10674*4882a593Smuzhiyun             destval = neg_byte(destval);
10675*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
10676*4882a593Smuzhiyun             break;
10677*4882a593Smuzhiyun         case 4:
10678*4882a593Smuzhiyun             DECODE_PRINTF("MUL\tBYTE PTR ");
10679*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
10680*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10681*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10682*4882a593Smuzhiyun             TRACE_AND_STEP();
10683*4882a593Smuzhiyun             mul_byte(destval);
10684*4882a593Smuzhiyun             break;
10685*4882a593Smuzhiyun         case 5:
10686*4882a593Smuzhiyun             DECODE_PRINTF("IMUL\tBYTE PTR ");
10687*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
10688*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10689*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10690*4882a593Smuzhiyun             TRACE_AND_STEP();
10691*4882a593Smuzhiyun             imul_byte(destval);
10692*4882a593Smuzhiyun             break;
10693*4882a593Smuzhiyun         case 6:
10694*4882a593Smuzhiyun             DECODE_PRINTF("DIV\tBYTE PTR ");
10695*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
10696*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10697*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10698*4882a593Smuzhiyun             TRACE_AND_STEP();
10699*4882a593Smuzhiyun             div_byte(destval);
10700*4882a593Smuzhiyun             break;
10701*4882a593Smuzhiyun         case 7:
10702*4882a593Smuzhiyun             DECODE_PRINTF("IDIV\tBYTE PTR ");
10703*4882a593Smuzhiyun             destoffset = decode_rm10_address(rl);
10704*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10705*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
10706*4882a593Smuzhiyun             TRACE_AND_STEP();
10707*4882a593Smuzhiyun             idiv_byte(destval);
10708*4882a593Smuzhiyun             break;
10709*4882a593Smuzhiyun         }
10710*4882a593Smuzhiyun         break;                  /* end mod==10 */
10711*4882a593Smuzhiyun     case 3:                    /* mod=11 */
10712*4882a593Smuzhiyun         switch (rh) {
10713*4882a593Smuzhiyun         case 0:                /* test byte imm */
10714*4882a593Smuzhiyun             DECODE_PRINTF("TEST\t");
10715*4882a593Smuzhiyun             destreg = DECODE_RM_BYTE_REGISTER(rl);
10716*4882a593Smuzhiyun             DECODE_PRINTF(",");
10717*4882a593Smuzhiyun             srcval = fetch_byte_imm();
10718*4882a593Smuzhiyun             DECODE_PRINTF2("%02x\n", srcval);
10719*4882a593Smuzhiyun             TRACE_AND_STEP();
10720*4882a593Smuzhiyun             test_byte(*destreg, srcval);
10721*4882a593Smuzhiyun             break;
10722*4882a593Smuzhiyun         case 1:
10723*4882a593Smuzhiyun             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10724*4882a593Smuzhiyun             HALT_SYS();
10725*4882a593Smuzhiyun             break;
10726*4882a593Smuzhiyun         case 2:
10727*4882a593Smuzhiyun             DECODE_PRINTF("NOT\t");
10728*4882a593Smuzhiyun             destreg = DECODE_RM_BYTE_REGISTER(rl);
10729*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10730*4882a593Smuzhiyun             TRACE_AND_STEP();
10731*4882a593Smuzhiyun             *destreg = not_byte(*destreg);
10732*4882a593Smuzhiyun             break;
10733*4882a593Smuzhiyun         case 3:
10734*4882a593Smuzhiyun             DECODE_PRINTF("NEG\t");
10735*4882a593Smuzhiyun             destreg = DECODE_RM_BYTE_REGISTER(rl);
10736*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10737*4882a593Smuzhiyun             TRACE_AND_STEP();
10738*4882a593Smuzhiyun             *destreg = neg_byte(*destreg);
10739*4882a593Smuzhiyun             break;
10740*4882a593Smuzhiyun         case 4:
10741*4882a593Smuzhiyun             DECODE_PRINTF("MUL\t");
10742*4882a593Smuzhiyun             destreg = DECODE_RM_BYTE_REGISTER(rl);
10743*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10744*4882a593Smuzhiyun             TRACE_AND_STEP();
10745*4882a593Smuzhiyun             mul_byte(*destreg); /*!!!  */
10746*4882a593Smuzhiyun             break;
10747*4882a593Smuzhiyun         case 5:
10748*4882a593Smuzhiyun             DECODE_PRINTF("IMUL\t");
10749*4882a593Smuzhiyun             destreg = DECODE_RM_BYTE_REGISTER(rl);
10750*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10751*4882a593Smuzhiyun             TRACE_AND_STEP();
10752*4882a593Smuzhiyun             imul_byte(*destreg);
10753*4882a593Smuzhiyun             break;
10754*4882a593Smuzhiyun         case 6:
10755*4882a593Smuzhiyun             DECODE_PRINTF("DIV\t");
10756*4882a593Smuzhiyun             destreg = DECODE_RM_BYTE_REGISTER(rl);
10757*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10758*4882a593Smuzhiyun             TRACE_AND_STEP();
10759*4882a593Smuzhiyun             div_byte(*destreg);
10760*4882a593Smuzhiyun             break;
10761*4882a593Smuzhiyun         case 7:
10762*4882a593Smuzhiyun             DECODE_PRINTF("IDIV\t");
10763*4882a593Smuzhiyun             destreg = DECODE_RM_BYTE_REGISTER(rl);
10764*4882a593Smuzhiyun             DECODE_PRINTF("\n");
10765*4882a593Smuzhiyun             TRACE_AND_STEP();
10766*4882a593Smuzhiyun             idiv_byte(*destreg);
10767*4882a593Smuzhiyun             break;
10768*4882a593Smuzhiyun         }
10769*4882a593Smuzhiyun         break;                  /* end mod==11 */
10770*4882a593Smuzhiyun     }
10771*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
10772*4882a593Smuzhiyun     END_OF_INSTR();
10773*4882a593Smuzhiyun }
10774*4882a593Smuzhiyun 
10775*4882a593Smuzhiyun /****************************************************************************
10776*4882a593Smuzhiyun REMARKS:
10777*4882a593Smuzhiyun Handles opcode 0xf7
10778*4882a593Smuzhiyun ****************************************************************************/
10779*4882a593Smuzhiyun static void
x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED (op1))10780*4882a593Smuzhiyun x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10781*4882a593Smuzhiyun {
10782*4882a593Smuzhiyun     int mod, rl, rh;
10783*4882a593Smuzhiyun     uint destoffset;
10784*4882a593Smuzhiyun 
10785*4882a593Smuzhiyun     /* long, drawn out code follows.  Double switch for a total
10786*4882a593Smuzhiyun        of 32 cases.  */
10787*4882a593Smuzhiyun     START_OF_INSTR();
10788*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
10789*4882a593Smuzhiyun     switch (mod) {
10790*4882a593Smuzhiyun     case 0:                    /* mod=00 */
10791*4882a593Smuzhiyun         switch (rh) {
10792*4882a593Smuzhiyun         case 0:                /* test word imm */
10793*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10794*4882a593Smuzhiyun                 u32 destval, srcval;
10795*4882a593Smuzhiyun 
10796*4882a593Smuzhiyun                 DECODE_PRINTF("TEST\tDWORD PTR ");
10797*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10798*4882a593Smuzhiyun                 DECODE_PRINTF(",");
10799*4882a593Smuzhiyun                 srcval = fetch_long_imm();
10800*4882a593Smuzhiyun                 DECODE_PRINTF2("%x\n", srcval);
10801*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
10802*4882a593Smuzhiyun                 TRACE_AND_STEP();
10803*4882a593Smuzhiyun                 test_long(destval, srcval);
10804*4882a593Smuzhiyun             }
10805*4882a593Smuzhiyun             else {
10806*4882a593Smuzhiyun                 u16 destval, srcval;
10807*4882a593Smuzhiyun 
10808*4882a593Smuzhiyun                 DECODE_PRINTF("TEST\tWORD PTR ");
10809*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10810*4882a593Smuzhiyun                 DECODE_PRINTF(",");
10811*4882a593Smuzhiyun                 srcval = fetch_word_imm();
10812*4882a593Smuzhiyun                 DECODE_PRINTF2("%x\n", srcval);
10813*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
10814*4882a593Smuzhiyun                 TRACE_AND_STEP();
10815*4882a593Smuzhiyun                 test_word(destval, srcval);
10816*4882a593Smuzhiyun             }
10817*4882a593Smuzhiyun             break;
10818*4882a593Smuzhiyun         case 1:
10819*4882a593Smuzhiyun             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10820*4882a593Smuzhiyun             HALT_SYS();
10821*4882a593Smuzhiyun             break;
10822*4882a593Smuzhiyun         case 2:
10823*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10824*4882a593Smuzhiyun                 u32 destval;
10825*4882a593Smuzhiyun 
10826*4882a593Smuzhiyun                 DECODE_PRINTF("NOT\tDWORD PTR ");
10827*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10828*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10829*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
10830*4882a593Smuzhiyun                 TRACE_AND_STEP();
10831*4882a593Smuzhiyun                 destval = not_long(destval);
10832*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
10833*4882a593Smuzhiyun             }
10834*4882a593Smuzhiyun             else {
10835*4882a593Smuzhiyun                 u16 destval;
10836*4882a593Smuzhiyun 
10837*4882a593Smuzhiyun                 DECODE_PRINTF("NOT\tWORD PTR ");
10838*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10839*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10840*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
10841*4882a593Smuzhiyun                 TRACE_AND_STEP();
10842*4882a593Smuzhiyun                 destval = not_word(destval);
10843*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
10844*4882a593Smuzhiyun             }
10845*4882a593Smuzhiyun             break;
10846*4882a593Smuzhiyun         case 3:
10847*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10848*4882a593Smuzhiyun                 u32 destval;
10849*4882a593Smuzhiyun 
10850*4882a593Smuzhiyun                 DECODE_PRINTF("NEG\tDWORD PTR ");
10851*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10852*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10853*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
10854*4882a593Smuzhiyun                 TRACE_AND_STEP();
10855*4882a593Smuzhiyun                 destval = neg_long(destval);
10856*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
10857*4882a593Smuzhiyun             }
10858*4882a593Smuzhiyun             else {
10859*4882a593Smuzhiyun                 u16 destval;
10860*4882a593Smuzhiyun 
10861*4882a593Smuzhiyun                 DECODE_PRINTF("NEG\tWORD PTR ");
10862*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10863*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10864*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
10865*4882a593Smuzhiyun                 TRACE_AND_STEP();
10866*4882a593Smuzhiyun                 destval = neg_word(destval);
10867*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
10868*4882a593Smuzhiyun             }
10869*4882a593Smuzhiyun             break;
10870*4882a593Smuzhiyun         case 4:
10871*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10872*4882a593Smuzhiyun                 u32 destval;
10873*4882a593Smuzhiyun 
10874*4882a593Smuzhiyun                 DECODE_PRINTF("MUL\tDWORD PTR ");
10875*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10876*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10877*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
10878*4882a593Smuzhiyun                 TRACE_AND_STEP();
10879*4882a593Smuzhiyun                 mul_long(destval);
10880*4882a593Smuzhiyun             }
10881*4882a593Smuzhiyun             else {
10882*4882a593Smuzhiyun                 u16 destval;
10883*4882a593Smuzhiyun 
10884*4882a593Smuzhiyun                 DECODE_PRINTF("MUL\tWORD PTR ");
10885*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10886*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10887*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
10888*4882a593Smuzhiyun                 TRACE_AND_STEP();
10889*4882a593Smuzhiyun                 mul_word(destval);
10890*4882a593Smuzhiyun             }
10891*4882a593Smuzhiyun             break;
10892*4882a593Smuzhiyun         case 5:
10893*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10894*4882a593Smuzhiyun                 u32 destval;
10895*4882a593Smuzhiyun 
10896*4882a593Smuzhiyun                 DECODE_PRINTF("IMUL\tDWORD PTR ");
10897*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10898*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10899*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
10900*4882a593Smuzhiyun                 TRACE_AND_STEP();
10901*4882a593Smuzhiyun                 imul_long(destval);
10902*4882a593Smuzhiyun             }
10903*4882a593Smuzhiyun             else {
10904*4882a593Smuzhiyun                 u16 destval;
10905*4882a593Smuzhiyun 
10906*4882a593Smuzhiyun                 DECODE_PRINTF("IMUL\tWORD PTR ");
10907*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10908*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10909*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
10910*4882a593Smuzhiyun                 TRACE_AND_STEP();
10911*4882a593Smuzhiyun                 imul_word(destval);
10912*4882a593Smuzhiyun             }
10913*4882a593Smuzhiyun             break;
10914*4882a593Smuzhiyun         case 6:
10915*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10916*4882a593Smuzhiyun                 u32 destval;
10917*4882a593Smuzhiyun 
10918*4882a593Smuzhiyun                 DECODE_PRINTF("DIV\tDWORD PTR ");
10919*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10920*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10921*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
10922*4882a593Smuzhiyun                 TRACE_AND_STEP();
10923*4882a593Smuzhiyun                 div_long(destval);
10924*4882a593Smuzhiyun             }
10925*4882a593Smuzhiyun             else {
10926*4882a593Smuzhiyun                 u16 destval;
10927*4882a593Smuzhiyun 
10928*4882a593Smuzhiyun                 DECODE_PRINTF("DIV\tWORD PTR ");
10929*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10930*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10931*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
10932*4882a593Smuzhiyun                 TRACE_AND_STEP();
10933*4882a593Smuzhiyun                 div_word(destval);
10934*4882a593Smuzhiyun             }
10935*4882a593Smuzhiyun             break;
10936*4882a593Smuzhiyun         case 7:
10937*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10938*4882a593Smuzhiyun                 u32 destval;
10939*4882a593Smuzhiyun 
10940*4882a593Smuzhiyun                 DECODE_PRINTF("IDIV\tDWORD PTR ");
10941*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10942*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10943*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
10944*4882a593Smuzhiyun                 TRACE_AND_STEP();
10945*4882a593Smuzhiyun                 idiv_long(destval);
10946*4882a593Smuzhiyun             }
10947*4882a593Smuzhiyun             else {
10948*4882a593Smuzhiyun                 u16 destval;
10949*4882a593Smuzhiyun 
10950*4882a593Smuzhiyun                 DECODE_PRINTF("IDIV\tWORD PTR ");
10951*4882a593Smuzhiyun                 destoffset = decode_rm00_address(rl);
10952*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10953*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
10954*4882a593Smuzhiyun                 TRACE_AND_STEP();
10955*4882a593Smuzhiyun                 idiv_word(destval);
10956*4882a593Smuzhiyun             }
10957*4882a593Smuzhiyun             break;
10958*4882a593Smuzhiyun         }
10959*4882a593Smuzhiyun         break;                  /* end mod==00 */
10960*4882a593Smuzhiyun     case 1:                    /* mod=01 */
10961*4882a593Smuzhiyun         switch (rh) {
10962*4882a593Smuzhiyun         case 0:                /* test word imm */
10963*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10964*4882a593Smuzhiyun                 u32 destval, srcval;
10965*4882a593Smuzhiyun 
10966*4882a593Smuzhiyun                 DECODE_PRINTF("TEST\tDWORD PTR ");
10967*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
10968*4882a593Smuzhiyun                 DECODE_PRINTF(",");
10969*4882a593Smuzhiyun                 srcval = fetch_long_imm();
10970*4882a593Smuzhiyun                 DECODE_PRINTF2("%x\n", srcval);
10971*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
10972*4882a593Smuzhiyun                 TRACE_AND_STEP();
10973*4882a593Smuzhiyun                 test_long(destval, srcval);
10974*4882a593Smuzhiyun             }
10975*4882a593Smuzhiyun             else {
10976*4882a593Smuzhiyun                 u16 destval, srcval;
10977*4882a593Smuzhiyun 
10978*4882a593Smuzhiyun                 DECODE_PRINTF("TEST\tWORD PTR ");
10979*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
10980*4882a593Smuzhiyun                 DECODE_PRINTF(",");
10981*4882a593Smuzhiyun                 srcval = fetch_word_imm();
10982*4882a593Smuzhiyun                 DECODE_PRINTF2("%x\n", srcval);
10983*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
10984*4882a593Smuzhiyun                 TRACE_AND_STEP();
10985*4882a593Smuzhiyun                 test_word(destval, srcval);
10986*4882a593Smuzhiyun             }
10987*4882a593Smuzhiyun             break;
10988*4882a593Smuzhiyun         case 1:
10989*4882a593Smuzhiyun             DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10990*4882a593Smuzhiyun             HALT_SYS();
10991*4882a593Smuzhiyun             break;
10992*4882a593Smuzhiyun         case 2:
10993*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10994*4882a593Smuzhiyun                 u32 destval;
10995*4882a593Smuzhiyun 
10996*4882a593Smuzhiyun                 DECODE_PRINTF("NOT\tDWORD PTR ");
10997*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
10998*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
10999*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11000*4882a593Smuzhiyun                 TRACE_AND_STEP();
11001*4882a593Smuzhiyun                 destval = not_long(destval);
11002*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
11003*4882a593Smuzhiyun             }
11004*4882a593Smuzhiyun             else {
11005*4882a593Smuzhiyun                 u16 destval;
11006*4882a593Smuzhiyun 
11007*4882a593Smuzhiyun                 DECODE_PRINTF("NOT\tWORD PTR ");
11008*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11009*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11010*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11011*4882a593Smuzhiyun                 TRACE_AND_STEP();
11012*4882a593Smuzhiyun                 destval = not_word(destval);
11013*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
11014*4882a593Smuzhiyun             }
11015*4882a593Smuzhiyun             break;
11016*4882a593Smuzhiyun         case 3:
11017*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11018*4882a593Smuzhiyun                 u32 destval;
11019*4882a593Smuzhiyun 
11020*4882a593Smuzhiyun                 DECODE_PRINTF("NEG\tDWORD PTR ");
11021*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11022*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11023*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11024*4882a593Smuzhiyun                 TRACE_AND_STEP();
11025*4882a593Smuzhiyun                 destval = neg_long(destval);
11026*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
11027*4882a593Smuzhiyun             }
11028*4882a593Smuzhiyun             else {
11029*4882a593Smuzhiyun                 u16 destval;
11030*4882a593Smuzhiyun 
11031*4882a593Smuzhiyun                 DECODE_PRINTF("NEG\tWORD PTR ");
11032*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11033*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11034*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11035*4882a593Smuzhiyun                 TRACE_AND_STEP();
11036*4882a593Smuzhiyun                 destval = neg_word(destval);
11037*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
11038*4882a593Smuzhiyun             }
11039*4882a593Smuzhiyun             break;
11040*4882a593Smuzhiyun         case 4:
11041*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11042*4882a593Smuzhiyun                 u32 destval;
11043*4882a593Smuzhiyun 
11044*4882a593Smuzhiyun                 DECODE_PRINTF("MUL\tDWORD PTR ");
11045*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11046*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11047*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11048*4882a593Smuzhiyun                 TRACE_AND_STEP();
11049*4882a593Smuzhiyun                 mul_long(destval);
11050*4882a593Smuzhiyun             }
11051*4882a593Smuzhiyun             else {
11052*4882a593Smuzhiyun                 u16 destval;
11053*4882a593Smuzhiyun 
11054*4882a593Smuzhiyun                 DECODE_PRINTF("MUL\tWORD PTR ");
11055*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11056*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11057*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11058*4882a593Smuzhiyun                 TRACE_AND_STEP();
11059*4882a593Smuzhiyun                 mul_word(destval);
11060*4882a593Smuzhiyun             }
11061*4882a593Smuzhiyun             break;
11062*4882a593Smuzhiyun         case 5:
11063*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11064*4882a593Smuzhiyun                 u32 destval;
11065*4882a593Smuzhiyun 
11066*4882a593Smuzhiyun                 DECODE_PRINTF("IMUL\tDWORD PTR ");
11067*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11068*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11069*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11070*4882a593Smuzhiyun                 TRACE_AND_STEP();
11071*4882a593Smuzhiyun                 imul_long(destval);
11072*4882a593Smuzhiyun             }
11073*4882a593Smuzhiyun             else {
11074*4882a593Smuzhiyun                 u16 destval;
11075*4882a593Smuzhiyun 
11076*4882a593Smuzhiyun                 DECODE_PRINTF("IMUL\tWORD PTR ");
11077*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11078*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11079*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11080*4882a593Smuzhiyun                 TRACE_AND_STEP();
11081*4882a593Smuzhiyun                 imul_word(destval);
11082*4882a593Smuzhiyun             }
11083*4882a593Smuzhiyun             break;
11084*4882a593Smuzhiyun         case 6:
11085*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11086*4882a593Smuzhiyun                 u32 destval;
11087*4882a593Smuzhiyun 
11088*4882a593Smuzhiyun                 DECODE_PRINTF("DIV\tDWORD PTR ");
11089*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11090*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11091*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11092*4882a593Smuzhiyun                 TRACE_AND_STEP();
11093*4882a593Smuzhiyun                 div_long(destval);
11094*4882a593Smuzhiyun             }
11095*4882a593Smuzhiyun             else {
11096*4882a593Smuzhiyun                 u16 destval;
11097*4882a593Smuzhiyun 
11098*4882a593Smuzhiyun                 DECODE_PRINTF("DIV\tWORD PTR ");
11099*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11100*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11101*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11102*4882a593Smuzhiyun                 TRACE_AND_STEP();
11103*4882a593Smuzhiyun                 div_word(destval);
11104*4882a593Smuzhiyun             }
11105*4882a593Smuzhiyun             break;
11106*4882a593Smuzhiyun         case 7:
11107*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11108*4882a593Smuzhiyun                 u32 destval;
11109*4882a593Smuzhiyun 
11110*4882a593Smuzhiyun                 DECODE_PRINTF("IDIV\tDWORD PTR ");
11111*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11112*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11113*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11114*4882a593Smuzhiyun                 TRACE_AND_STEP();
11115*4882a593Smuzhiyun                 idiv_long(destval);
11116*4882a593Smuzhiyun             }
11117*4882a593Smuzhiyun             else {
11118*4882a593Smuzhiyun                 u16 destval;
11119*4882a593Smuzhiyun 
11120*4882a593Smuzhiyun                 DECODE_PRINTF("IDIV\tWORD PTR ");
11121*4882a593Smuzhiyun                 destoffset = decode_rm01_address(rl);
11122*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11123*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11124*4882a593Smuzhiyun                 TRACE_AND_STEP();
11125*4882a593Smuzhiyun                 idiv_word(destval);
11126*4882a593Smuzhiyun             }
11127*4882a593Smuzhiyun             break;
11128*4882a593Smuzhiyun         }
11129*4882a593Smuzhiyun         break;                  /* end mod==01 */
11130*4882a593Smuzhiyun     case 2:                    /* mod=10 */
11131*4882a593Smuzhiyun         switch (rh) {
11132*4882a593Smuzhiyun         case 0:                /* test word imm */
11133*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11134*4882a593Smuzhiyun                 u32 destval, srcval;
11135*4882a593Smuzhiyun 
11136*4882a593Smuzhiyun                 DECODE_PRINTF("TEST\tDWORD PTR ");
11137*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11138*4882a593Smuzhiyun                 DECODE_PRINTF(",");
11139*4882a593Smuzhiyun                 srcval = fetch_long_imm();
11140*4882a593Smuzhiyun                 DECODE_PRINTF2("%x\n", srcval);
11141*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11142*4882a593Smuzhiyun                 TRACE_AND_STEP();
11143*4882a593Smuzhiyun                 test_long(destval, srcval);
11144*4882a593Smuzhiyun             }
11145*4882a593Smuzhiyun             else {
11146*4882a593Smuzhiyun                 u16 destval, srcval;
11147*4882a593Smuzhiyun 
11148*4882a593Smuzhiyun                 DECODE_PRINTF("TEST\tWORD PTR ");
11149*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11150*4882a593Smuzhiyun                 DECODE_PRINTF(",");
11151*4882a593Smuzhiyun                 srcval = fetch_word_imm();
11152*4882a593Smuzhiyun                 DECODE_PRINTF2("%x\n", srcval);
11153*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11154*4882a593Smuzhiyun                 TRACE_AND_STEP();
11155*4882a593Smuzhiyun                 test_word(destval, srcval);
11156*4882a593Smuzhiyun             }
11157*4882a593Smuzhiyun             break;
11158*4882a593Smuzhiyun         case 1:
11159*4882a593Smuzhiyun             DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
11160*4882a593Smuzhiyun             HALT_SYS();
11161*4882a593Smuzhiyun             break;
11162*4882a593Smuzhiyun         case 2:
11163*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11164*4882a593Smuzhiyun                 u32 destval;
11165*4882a593Smuzhiyun 
11166*4882a593Smuzhiyun                 DECODE_PRINTF("NOT\tDWORD PTR ");
11167*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11168*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11169*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11170*4882a593Smuzhiyun                 TRACE_AND_STEP();
11171*4882a593Smuzhiyun                 destval = not_long(destval);
11172*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
11173*4882a593Smuzhiyun             }
11174*4882a593Smuzhiyun             else {
11175*4882a593Smuzhiyun                 u16 destval;
11176*4882a593Smuzhiyun 
11177*4882a593Smuzhiyun                 DECODE_PRINTF("NOT\tWORD PTR ");
11178*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11179*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11180*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11181*4882a593Smuzhiyun                 TRACE_AND_STEP();
11182*4882a593Smuzhiyun                 destval = not_word(destval);
11183*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
11184*4882a593Smuzhiyun             }
11185*4882a593Smuzhiyun             break;
11186*4882a593Smuzhiyun         case 3:
11187*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11188*4882a593Smuzhiyun                 u32 destval;
11189*4882a593Smuzhiyun 
11190*4882a593Smuzhiyun                 DECODE_PRINTF("NEG\tDWORD PTR ");
11191*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11192*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11193*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11194*4882a593Smuzhiyun                 TRACE_AND_STEP();
11195*4882a593Smuzhiyun                 destval = neg_long(destval);
11196*4882a593Smuzhiyun                 store_data_long(destoffset, destval);
11197*4882a593Smuzhiyun             }
11198*4882a593Smuzhiyun             else {
11199*4882a593Smuzhiyun                 u16 destval;
11200*4882a593Smuzhiyun 
11201*4882a593Smuzhiyun                 DECODE_PRINTF("NEG\tWORD PTR ");
11202*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11203*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11204*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11205*4882a593Smuzhiyun                 TRACE_AND_STEP();
11206*4882a593Smuzhiyun                 destval = neg_word(destval);
11207*4882a593Smuzhiyun                 store_data_word(destoffset, destval);
11208*4882a593Smuzhiyun             }
11209*4882a593Smuzhiyun             break;
11210*4882a593Smuzhiyun         case 4:
11211*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11212*4882a593Smuzhiyun                 u32 destval;
11213*4882a593Smuzhiyun 
11214*4882a593Smuzhiyun                 DECODE_PRINTF("MUL\tDWORD PTR ");
11215*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11216*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11217*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11218*4882a593Smuzhiyun                 TRACE_AND_STEP();
11219*4882a593Smuzhiyun                 mul_long(destval);
11220*4882a593Smuzhiyun             }
11221*4882a593Smuzhiyun             else {
11222*4882a593Smuzhiyun                 u16 destval;
11223*4882a593Smuzhiyun 
11224*4882a593Smuzhiyun                 DECODE_PRINTF("MUL\tWORD PTR ");
11225*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11226*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11227*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11228*4882a593Smuzhiyun                 TRACE_AND_STEP();
11229*4882a593Smuzhiyun                 mul_word(destval);
11230*4882a593Smuzhiyun             }
11231*4882a593Smuzhiyun             break;
11232*4882a593Smuzhiyun         case 5:
11233*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11234*4882a593Smuzhiyun                 u32 destval;
11235*4882a593Smuzhiyun 
11236*4882a593Smuzhiyun                 DECODE_PRINTF("IMUL\tDWORD PTR ");
11237*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11238*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11239*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11240*4882a593Smuzhiyun                 TRACE_AND_STEP();
11241*4882a593Smuzhiyun                 imul_long(destval);
11242*4882a593Smuzhiyun             }
11243*4882a593Smuzhiyun             else {
11244*4882a593Smuzhiyun                 u16 destval;
11245*4882a593Smuzhiyun 
11246*4882a593Smuzhiyun                 DECODE_PRINTF("IMUL\tWORD PTR ");
11247*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11248*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11249*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11250*4882a593Smuzhiyun                 TRACE_AND_STEP();
11251*4882a593Smuzhiyun                 imul_word(destval);
11252*4882a593Smuzhiyun             }
11253*4882a593Smuzhiyun             break;
11254*4882a593Smuzhiyun         case 6:
11255*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11256*4882a593Smuzhiyun                 u32 destval;
11257*4882a593Smuzhiyun 
11258*4882a593Smuzhiyun                 DECODE_PRINTF("DIV\tDWORD PTR ");
11259*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11260*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11261*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11262*4882a593Smuzhiyun                 TRACE_AND_STEP();
11263*4882a593Smuzhiyun                 div_long(destval);
11264*4882a593Smuzhiyun             }
11265*4882a593Smuzhiyun             else {
11266*4882a593Smuzhiyun                 u16 destval;
11267*4882a593Smuzhiyun 
11268*4882a593Smuzhiyun                 DECODE_PRINTF("DIV\tWORD PTR ");
11269*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11270*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11271*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11272*4882a593Smuzhiyun                 TRACE_AND_STEP();
11273*4882a593Smuzhiyun                 div_word(destval);
11274*4882a593Smuzhiyun             }
11275*4882a593Smuzhiyun             break;
11276*4882a593Smuzhiyun         case 7:
11277*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11278*4882a593Smuzhiyun                 u32 destval;
11279*4882a593Smuzhiyun 
11280*4882a593Smuzhiyun                 DECODE_PRINTF("IDIV\tDWORD PTR ");
11281*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11282*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11283*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11284*4882a593Smuzhiyun                 TRACE_AND_STEP();
11285*4882a593Smuzhiyun                 idiv_long(destval);
11286*4882a593Smuzhiyun             }
11287*4882a593Smuzhiyun             else {
11288*4882a593Smuzhiyun                 u16 destval;
11289*4882a593Smuzhiyun 
11290*4882a593Smuzhiyun                 DECODE_PRINTF("IDIV\tWORD PTR ");
11291*4882a593Smuzhiyun                 destoffset = decode_rm10_address(rl);
11292*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11293*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11294*4882a593Smuzhiyun                 TRACE_AND_STEP();
11295*4882a593Smuzhiyun                 idiv_word(destval);
11296*4882a593Smuzhiyun             }
11297*4882a593Smuzhiyun             break;
11298*4882a593Smuzhiyun         }
11299*4882a593Smuzhiyun         break;                  /* end mod==10 */
11300*4882a593Smuzhiyun     case 3:                    /* mod=11 */
11301*4882a593Smuzhiyun         switch (rh) {
11302*4882a593Smuzhiyun         case 0:                /* test word imm */
11303*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11304*4882a593Smuzhiyun                 u32 *destreg;
11305*4882a593Smuzhiyun                 u32 srcval;
11306*4882a593Smuzhiyun 
11307*4882a593Smuzhiyun                 DECODE_PRINTF("TEST\t");
11308*4882a593Smuzhiyun                 destreg = DECODE_RM_LONG_REGISTER(rl);
11309*4882a593Smuzhiyun                 DECODE_PRINTF(",");
11310*4882a593Smuzhiyun                 srcval = fetch_long_imm();
11311*4882a593Smuzhiyun                 DECODE_PRINTF2("%x\n", srcval);
11312*4882a593Smuzhiyun                 TRACE_AND_STEP();
11313*4882a593Smuzhiyun                 test_long(*destreg, srcval);
11314*4882a593Smuzhiyun             }
11315*4882a593Smuzhiyun             else {
11316*4882a593Smuzhiyun                 u16 *destreg;
11317*4882a593Smuzhiyun                 u16 srcval;
11318*4882a593Smuzhiyun 
11319*4882a593Smuzhiyun                 DECODE_PRINTF("TEST\t");
11320*4882a593Smuzhiyun                 destreg = DECODE_RM_WORD_REGISTER(rl);
11321*4882a593Smuzhiyun                 DECODE_PRINTF(",");
11322*4882a593Smuzhiyun                 srcval = fetch_word_imm();
11323*4882a593Smuzhiyun                 DECODE_PRINTF2("%x\n", srcval);
11324*4882a593Smuzhiyun                 TRACE_AND_STEP();
11325*4882a593Smuzhiyun                 test_word(*destreg, srcval);
11326*4882a593Smuzhiyun             }
11327*4882a593Smuzhiyun             break;
11328*4882a593Smuzhiyun         case 1:
11329*4882a593Smuzhiyun             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
11330*4882a593Smuzhiyun             HALT_SYS();
11331*4882a593Smuzhiyun             break;
11332*4882a593Smuzhiyun         case 2:
11333*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11334*4882a593Smuzhiyun                 u32 *destreg;
11335*4882a593Smuzhiyun 
11336*4882a593Smuzhiyun                 DECODE_PRINTF("NOT\t");
11337*4882a593Smuzhiyun                 destreg = DECODE_RM_LONG_REGISTER(rl);
11338*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11339*4882a593Smuzhiyun                 TRACE_AND_STEP();
11340*4882a593Smuzhiyun                 *destreg = not_long(*destreg);
11341*4882a593Smuzhiyun             }
11342*4882a593Smuzhiyun             else {
11343*4882a593Smuzhiyun                 u16 *destreg;
11344*4882a593Smuzhiyun 
11345*4882a593Smuzhiyun                 DECODE_PRINTF("NOT\t");
11346*4882a593Smuzhiyun                 destreg = DECODE_RM_WORD_REGISTER(rl);
11347*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11348*4882a593Smuzhiyun                 TRACE_AND_STEP();
11349*4882a593Smuzhiyun                 *destreg = not_word(*destreg);
11350*4882a593Smuzhiyun             }
11351*4882a593Smuzhiyun             break;
11352*4882a593Smuzhiyun         case 3:
11353*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11354*4882a593Smuzhiyun                 u32 *destreg;
11355*4882a593Smuzhiyun 
11356*4882a593Smuzhiyun                 DECODE_PRINTF("NEG\t");
11357*4882a593Smuzhiyun                 destreg = DECODE_RM_LONG_REGISTER(rl);
11358*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11359*4882a593Smuzhiyun                 TRACE_AND_STEP();
11360*4882a593Smuzhiyun                 *destreg = neg_long(*destreg);
11361*4882a593Smuzhiyun             }
11362*4882a593Smuzhiyun             else {
11363*4882a593Smuzhiyun                 u16 *destreg;
11364*4882a593Smuzhiyun 
11365*4882a593Smuzhiyun                 DECODE_PRINTF("NEG\t");
11366*4882a593Smuzhiyun                 destreg = DECODE_RM_WORD_REGISTER(rl);
11367*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11368*4882a593Smuzhiyun                 TRACE_AND_STEP();
11369*4882a593Smuzhiyun                 *destreg = neg_word(*destreg);
11370*4882a593Smuzhiyun             }
11371*4882a593Smuzhiyun             break;
11372*4882a593Smuzhiyun         case 4:
11373*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11374*4882a593Smuzhiyun                 u32 *destreg;
11375*4882a593Smuzhiyun 
11376*4882a593Smuzhiyun                 DECODE_PRINTF("MUL\t");
11377*4882a593Smuzhiyun                 destreg = DECODE_RM_LONG_REGISTER(rl);
11378*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11379*4882a593Smuzhiyun                 TRACE_AND_STEP();
11380*4882a593Smuzhiyun                 mul_long(*destreg);     /*!!!  */
11381*4882a593Smuzhiyun             }
11382*4882a593Smuzhiyun             else {
11383*4882a593Smuzhiyun                 u16 *destreg;
11384*4882a593Smuzhiyun 
11385*4882a593Smuzhiyun                 DECODE_PRINTF("MUL\t");
11386*4882a593Smuzhiyun                 destreg = DECODE_RM_WORD_REGISTER(rl);
11387*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11388*4882a593Smuzhiyun                 TRACE_AND_STEP();
11389*4882a593Smuzhiyun                 mul_word(*destreg);     /*!!!  */
11390*4882a593Smuzhiyun             }
11391*4882a593Smuzhiyun             break;
11392*4882a593Smuzhiyun         case 5:
11393*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11394*4882a593Smuzhiyun                 u32 *destreg;
11395*4882a593Smuzhiyun 
11396*4882a593Smuzhiyun                 DECODE_PRINTF("IMUL\t");
11397*4882a593Smuzhiyun                 destreg = DECODE_RM_LONG_REGISTER(rl);
11398*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11399*4882a593Smuzhiyun                 TRACE_AND_STEP();
11400*4882a593Smuzhiyun                 imul_long(*destreg);
11401*4882a593Smuzhiyun             }
11402*4882a593Smuzhiyun             else {
11403*4882a593Smuzhiyun                 u16 *destreg;
11404*4882a593Smuzhiyun 
11405*4882a593Smuzhiyun                 DECODE_PRINTF("IMUL\t");
11406*4882a593Smuzhiyun                 destreg = DECODE_RM_WORD_REGISTER(rl);
11407*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11408*4882a593Smuzhiyun                 TRACE_AND_STEP();
11409*4882a593Smuzhiyun                 imul_word(*destreg);
11410*4882a593Smuzhiyun             }
11411*4882a593Smuzhiyun             break;
11412*4882a593Smuzhiyun         case 6:
11413*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11414*4882a593Smuzhiyun                 u32 *destreg;
11415*4882a593Smuzhiyun 
11416*4882a593Smuzhiyun                 DECODE_PRINTF("DIV\t");
11417*4882a593Smuzhiyun                 destreg = DECODE_RM_LONG_REGISTER(rl);
11418*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11419*4882a593Smuzhiyun                 TRACE_AND_STEP();
11420*4882a593Smuzhiyun                 div_long(*destreg);
11421*4882a593Smuzhiyun             }
11422*4882a593Smuzhiyun             else {
11423*4882a593Smuzhiyun                 u16 *destreg;
11424*4882a593Smuzhiyun 
11425*4882a593Smuzhiyun                 DECODE_PRINTF("DIV\t");
11426*4882a593Smuzhiyun                 destreg = DECODE_RM_WORD_REGISTER(rl);
11427*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11428*4882a593Smuzhiyun                 TRACE_AND_STEP();
11429*4882a593Smuzhiyun                 div_word(*destreg);
11430*4882a593Smuzhiyun             }
11431*4882a593Smuzhiyun             break;
11432*4882a593Smuzhiyun         case 7:
11433*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11434*4882a593Smuzhiyun                 u32 *destreg;
11435*4882a593Smuzhiyun 
11436*4882a593Smuzhiyun                 DECODE_PRINTF("IDIV\t");
11437*4882a593Smuzhiyun                 destreg = DECODE_RM_LONG_REGISTER(rl);
11438*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11439*4882a593Smuzhiyun                 TRACE_AND_STEP();
11440*4882a593Smuzhiyun                 idiv_long(*destreg);
11441*4882a593Smuzhiyun             }
11442*4882a593Smuzhiyun             else {
11443*4882a593Smuzhiyun                 u16 *destreg;
11444*4882a593Smuzhiyun 
11445*4882a593Smuzhiyun                 DECODE_PRINTF("IDIV\t");
11446*4882a593Smuzhiyun                 destreg = DECODE_RM_WORD_REGISTER(rl);
11447*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
11448*4882a593Smuzhiyun                 TRACE_AND_STEP();
11449*4882a593Smuzhiyun                 idiv_word(*destreg);
11450*4882a593Smuzhiyun             }
11451*4882a593Smuzhiyun             break;
11452*4882a593Smuzhiyun         }
11453*4882a593Smuzhiyun         break;                  /* end mod==11 */
11454*4882a593Smuzhiyun     }
11455*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
11456*4882a593Smuzhiyun     END_OF_INSTR();
11457*4882a593Smuzhiyun }
11458*4882a593Smuzhiyun 
11459*4882a593Smuzhiyun /****************************************************************************
11460*4882a593Smuzhiyun REMARKS:
11461*4882a593Smuzhiyun Handles opcode 0xf8
11462*4882a593Smuzhiyun ****************************************************************************/
11463*4882a593Smuzhiyun static void
x86emuOp_clc(u8 X86EMU_UNUSED (op1))11464*4882a593Smuzhiyun x86emuOp_clc(u8 X86EMU_UNUSED(op1))
11465*4882a593Smuzhiyun {
11466*4882a593Smuzhiyun     /* clear the carry flag. */
11467*4882a593Smuzhiyun     START_OF_INSTR();
11468*4882a593Smuzhiyun     DECODE_PRINTF("CLC\n");
11469*4882a593Smuzhiyun     TRACE_AND_STEP();
11470*4882a593Smuzhiyun     CLEAR_FLAG(F_CF);
11471*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
11472*4882a593Smuzhiyun     END_OF_INSTR();
11473*4882a593Smuzhiyun }
11474*4882a593Smuzhiyun 
11475*4882a593Smuzhiyun /****************************************************************************
11476*4882a593Smuzhiyun REMARKS:
11477*4882a593Smuzhiyun Handles opcode 0xf9
11478*4882a593Smuzhiyun ****************************************************************************/
11479*4882a593Smuzhiyun static void
x86emuOp_stc(u8 X86EMU_UNUSED (op1))11480*4882a593Smuzhiyun x86emuOp_stc(u8 X86EMU_UNUSED(op1))
11481*4882a593Smuzhiyun {
11482*4882a593Smuzhiyun     /* set the carry flag. */
11483*4882a593Smuzhiyun     START_OF_INSTR();
11484*4882a593Smuzhiyun     DECODE_PRINTF("STC\n");
11485*4882a593Smuzhiyun     TRACE_AND_STEP();
11486*4882a593Smuzhiyun     SET_FLAG(F_CF);
11487*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
11488*4882a593Smuzhiyun     END_OF_INSTR();
11489*4882a593Smuzhiyun }
11490*4882a593Smuzhiyun 
11491*4882a593Smuzhiyun /****************************************************************************
11492*4882a593Smuzhiyun REMARKS:
11493*4882a593Smuzhiyun Handles opcode 0xfa
11494*4882a593Smuzhiyun ****************************************************************************/
11495*4882a593Smuzhiyun static void
x86emuOp_cli(u8 X86EMU_UNUSED (op1))11496*4882a593Smuzhiyun x86emuOp_cli(u8 X86EMU_UNUSED(op1))
11497*4882a593Smuzhiyun {
11498*4882a593Smuzhiyun     /* clear interrupts. */
11499*4882a593Smuzhiyun     START_OF_INSTR();
11500*4882a593Smuzhiyun     DECODE_PRINTF("CLI\n");
11501*4882a593Smuzhiyun     TRACE_AND_STEP();
11502*4882a593Smuzhiyun     CLEAR_FLAG(F_IF);
11503*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
11504*4882a593Smuzhiyun     END_OF_INSTR();
11505*4882a593Smuzhiyun }
11506*4882a593Smuzhiyun 
11507*4882a593Smuzhiyun /****************************************************************************
11508*4882a593Smuzhiyun REMARKS:
11509*4882a593Smuzhiyun Handles opcode 0xfb
11510*4882a593Smuzhiyun ****************************************************************************/
11511*4882a593Smuzhiyun static void
x86emuOp_sti(u8 X86EMU_UNUSED (op1))11512*4882a593Smuzhiyun x86emuOp_sti(u8 X86EMU_UNUSED(op1))
11513*4882a593Smuzhiyun {
11514*4882a593Smuzhiyun     /* enable  interrupts. */
11515*4882a593Smuzhiyun     START_OF_INSTR();
11516*4882a593Smuzhiyun     DECODE_PRINTF("STI\n");
11517*4882a593Smuzhiyun     TRACE_AND_STEP();
11518*4882a593Smuzhiyun     SET_FLAG(F_IF);
11519*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
11520*4882a593Smuzhiyun     END_OF_INSTR();
11521*4882a593Smuzhiyun }
11522*4882a593Smuzhiyun 
11523*4882a593Smuzhiyun /****************************************************************************
11524*4882a593Smuzhiyun REMARKS:
11525*4882a593Smuzhiyun Handles opcode 0xfc
11526*4882a593Smuzhiyun ****************************************************************************/
11527*4882a593Smuzhiyun static void
x86emuOp_cld(u8 X86EMU_UNUSED (op1))11528*4882a593Smuzhiyun x86emuOp_cld(u8 X86EMU_UNUSED(op1))
11529*4882a593Smuzhiyun {
11530*4882a593Smuzhiyun     /* clear interrupts. */
11531*4882a593Smuzhiyun     START_OF_INSTR();
11532*4882a593Smuzhiyun     DECODE_PRINTF("CLD\n");
11533*4882a593Smuzhiyun     TRACE_AND_STEP();
11534*4882a593Smuzhiyun     CLEAR_FLAG(F_DF);
11535*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
11536*4882a593Smuzhiyun     END_OF_INSTR();
11537*4882a593Smuzhiyun }
11538*4882a593Smuzhiyun 
11539*4882a593Smuzhiyun /****************************************************************************
11540*4882a593Smuzhiyun REMARKS:
11541*4882a593Smuzhiyun Handles opcode 0xfd
11542*4882a593Smuzhiyun ****************************************************************************/
11543*4882a593Smuzhiyun static void
x86emuOp_std(u8 X86EMU_UNUSED (op1))11544*4882a593Smuzhiyun x86emuOp_std(u8 X86EMU_UNUSED(op1))
11545*4882a593Smuzhiyun {
11546*4882a593Smuzhiyun     /* clear interrupts. */
11547*4882a593Smuzhiyun     START_OF_INSTR();
11548*4882a593Smuzhiyun     DECODE_PRINTF("STD\n");
11549*4882a593Smuzhiyun     TRACE_AND_STEP();
11550*4882a593Smuzhiyun     SET_FLAG(F_DF);
11551*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
11552*4882a593Smuzhiyun     END_OF_INSTR();
11553*4882a593Smuzhiyun }
11554*4882a593Smuzhiyun 
11555*4882a593Smuzhiyun /****************************************************************************
11556*4882a593Smuzhiyun REMARKS:
11557*4882a593Smuzhiyun Handles opcode 0xfe
11558*4882a593Smuzhiyun ****************************************************************************/
11559*4882a593Smuzhiyun static void
x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED (op1))11560*4882a593Smuzhiyun x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
11561*4882a593Smuzhiyun {
11562*4882a593Smuzhiyun     int mod, rh, rl;
11563*4882a593Smuzhiyun     u8 destval;
11564*4882a593Smuzhiyun     uint destoffset;
11565*4882a593Smuzhiyun     u8 *destreg;
11566*4882a593Smuzhiyun 
11567*4882a593Smuzhiyun     /* Yet another special case instruction. */
11568*4882a593Smuzhiyun     START_OF_INSTR();
11569*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
11570*4882a593Smuzhiyun #ifdef DEBUG
11571*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
11572*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
11573*4882a593Smuzhiyun            general, so that it is important to leave the strings
11574*4882a593Smuzhiyun            in the same format, even though the result is that the
11575*4882a593Smuzhiyun            above test is done twice. */
11576*4882a593Smuzhiyun 
11577*4882a593Smuzhiyun         switch (rh) {
11578*4882a593Smuzhiyun         case 0:
11579*4882a593Smuzhiyun             DECODE_PRINTF("INC\t");
11580*4882a593Smuzhiyun             break;
11581*4882a593Smuzhiyun         case 1:
11582*4882a593Smuzhiyun             DECODE_PRINTF("DEC\t");
11583*4882a593Smuzhiyun             break;
11584*4882a593Smuzhiyun         case 2:
11585*4882a593Smuzhiyun         case 3:
11586*4882a593Smuzhiyun         case 4:
11587*4882a593Smuzhiyun         case 5:
11588*4882a593Smuzhiyun         case 6:
11589*4882a593Smuzhiyun         case 7:
11590*4882a593Smuzhiyun             DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
11591*4882a593Smuzhiyun             HALT_SYS();
11592*4882a593Smuzhiyun             break;
11593*4882a593Smuzhiyun         }
11594*4882a593Smuzhiyun     }
11595*4882a593Smuzhiyun #endif
11596*4882a593Smuzhiyun     switch (mod) {
11597*4882a593Smuzhiyun     case 0:
11598*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
11599*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
11600*4882a593Smuzhiyun         DECODE_PRINTF("\n");
11601*4882a593Smuzhiyun         switch (rh) {
11602*4882a593Smuzhiyun         case 0:                /* inc word ptr ... */
11603*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
11604*4882a593Smuzhiyun             TRACE_AND_STEP();
11605*4882a593Smuzhiyun             destval = inc_byte(destval);
11606*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
11607*4882a593Smuzhiyun             break;
11608*4882a593Smuzhiyun         case 1:                /* dec word ptr ... */
11609*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
11610*4882a593Smuzhiyun             TRACE_AND_STEP();
11611*4882a593Smuzhiyun             destval = dec_byte(destval);
11612*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
11613*4882a593Smuzhiyun             break;
11614*4882a593Smuzhiyun         }
11615*4882a593Smuzhiyun         break;
11616*4882a593Smuzhiyun     case 1:
11617*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
11618*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
11619*4882a593Smuzhiyun         DECODE_PRINTF("\n");
11620*4882a593Smuzhiyun         switch (rh) {
11621*4882a593Smuzhiyun         case 0:
11622*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
11623*4882a593Smuzhiyun             TRACE_AND_STEP();
11624*4882a593Smuzhiyun             destval = inc_byte(destval);
11625*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
11626*4882a593Smuzhiyun             break;
11627*4882a593Smuzhiyun         case 1:
11628*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
11629*4882a593Smuzhiyun             TRACE_AND_STEP();
11630*4882a593Smuzhiyun             destval = dec_byte(destval);
11631*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
11632*4882a593Smuzhiyun             break;
11633*4882a593Smuzhiyun         }
11634*4882a593Smuzhiyun         break;
11635*4882a593Smuzhiyun     case 2:
11636*4882a593Smuzhiyun         DECODE_PRINTF("BYTE PTR ");
11637*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
11638*4882a593Smuzhiyun         DECODE_PRINTF("\n");
11639*4882a593Smuzhiyun         switch (rh) {
11640*4882a593Smuzhiyun         case 0:
11641*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
11642*4882a593Smuzhiyun             TRACE_AND_STEP();
11643*4882a593Smuzhiyun             destval = inc_byte(destval);
11644*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
11645*4882a593Smuzhiyun             break;
11646*4882a593Smuzhiyun         case 1:
11647*4882a593Smuzhiyun             destval = fetch_data_byte(destoffset);
11648*4882a593Smuzhiyun             TRACE_AND_STEP();
11649*4882a593Smuzhiyun             destval = dec_byte(destval);
11650*4882a593Smuzhiyun             store_data_byte(destoffset, destval);
11651*4882a593Smuzhiyun             break;
11652*4882a593Smuzhiyun         }
11653*4882a593Smuzhiyun         break;
11654*4882a593Smuzhiyun     case 3:
11655*4882a593Smuzhiyun         destreg = DECODE_RM_BYTE_REGISTER(rl);
11656*4882a593Smuzhiyun         DECODE_PRINTF("\n");
11657*4882a593Smuzhiyun         switch (rh) {
11658*4882a593Smuzhiyun         case 0:
11659*4882a593Smuzhiyun             TRACE_AND_STEP();
11660*4882a593Smuzhiyun             *destreg = inc_byte(*destreg);
11661*4882a593Smuzhiyun             break;
11662*4882a593Smuzhiyun         case 1:
11663*4882a593Smuzhiyun             TRACE_AND_STEP();
11664*4882a593Smuzhiyun             *destreg = dec_byte(*destreg);
11665*4882a593Smuzhiyun             break;
11666*4882a593Smuzhiyun         }
11667*4882a593Smuzhiyun         break;
11668*4882a593Smuzhiyun     }
11669*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
11670*4882a593Smuzhiyun     END_OF_INSTR();
11671*4882a593Smuzhiyun }
11672*4882a593Smuzhiyun 
11673*4882a593Smuzhiyun /****************************************************************************
11674*4882a593Smuzhiyun REMARKS:
11675*4882a593Smuzhiyun Handles opcode 0xff
11676*4882a593Smuzhiyun ****************************************************************************/
11677*4882a593Smuzhiyun static void
x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED (op1))11678*4882a593Smuzhiyun x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11679*4882a593Smuzhiyun {
11680*4882a593Smuzhiyun     int mod, rh, rl;
11681*4882a593Smuzhiyun     uint destoffset = 0;
11682*4882a593Smuzhiyun     u16 *destreg;
11683*4882a593Smuzhiyun     u16 destval, destval2;
11684*4882a593Smuzhiyun 
11685*4882a593Smuzhiyun     /* Yet another special case instruction. */
11686*4882a593Smuzhiyun     START_OF_INSTR();
11687*4882a593Smuzhiyun     FETCH_DECODE_MODRM(mod, rh, rl);
11688*4882a593Smuzhiyun #ifdef DEBUG
11689*4882a593Smuzhiyun     if (DEBUG_DECODE()) {
11690*4882a593Smuzhiyun         /* XXX DECODE_PRINTF may be changed to something more
11691*4882a593Smuzhiyun            general, so that it is important to leave the strings
11692*4882a593Smuzhiyun            in the same format, even though the result is that the
11693*4882a593Smuzhiyun            above test is done twice. */
11694*4882a593Smuzhiyun 
11695*4882a593Smuzhiyun         switch (rh) {
11696*4882a593Smuzhiyun         case 0:
11697*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11698*4882a593Smuzhiyun                 DECODE_PRINTF("INC\tDWORD PTR ");
11699*4882a593Smuzhiyun             }
11700*4882a593Smuzhiyun             else {
11701*4882a593Smuzhiyun                 DECODE_PRINTF("INC\tWORD PTR ");
11702*4882a593Smuzhiyun             }
11703*4882a593Smuzhiyun             break;
11704*4882a593Smuzhiyun         case 1:
11705*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11706*4882a593Smuzhiyun                 DECODE_PRINTF("DEC\tDWORD PTR ");
11707*4882a593Smuzhiyun             }
11708*4882a593Smuzhiyun             else {
11709*4882a593Smuzhiyun                 DECODE_PRINTF("DEC\tWORD PTR ");
11710*4882a593Smuzhiyun             }
11711*4882a593Smuzhiyun             break;
11712*4882a593Smuzhiyun         case 2:
11713*4882a593Smuzhiyun             DECODE_PRINTF("CALL\t");
11714*4882a593Smuzhiyun             break;
11715*4882a593Smuzhiyun         case 3:
11716*4882a593Smuzhiyun             DECODE_PRINTF("CALL\tFAR ");
11717*4882a593Smuzhiyun             break;
11718*4882a593Smuzhiyun         case 4:
11719*4882a593Smuzhiyun             DECODE_PRINTF("JMP\t");
11720*4882a593Smuzhiyun             break;
11721*4882a593Smuzhiyun         case 5:
11722*4882a593Smuzhiyun             DECODE_PRINTF("JMP\tFAR ");
11723*4882a593Smuzhiyun             break;
11724*4882a593Smuzhiyun         case 6:
11725*4882a593Smuzhiyun             DECODE_PRINTF("PUSH\t");
11726*4882a593Smuzhiyun             break;
11727*4882a593Smuzhiyun         case 7:
11728*4882a593Smuzhiyun             DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11729*4882a593Smuzhiyun             HALT_SYS();
11730*4882a593Smuzhiyun             break;
11731*4882a593Smuzhiyun         }
11732*4882a593Smuzhiyun     }
11733*4882a593Smuzhiyun #endif
11734*4882a593Smuzhiyun     switch (mod) {
11735*4882a593Smuzhiyun     case 0:
11736*4882a593Smuzhiyun         destoffset = decode_rm00_address(rl);
11737*4882a593Smuzhiyun         DECODE_PRINTF("\n");
11738*4882a593Smuzhiyun         switch (rh) {
11739*4882a593Smuzhiyun         case 0:                /* inc word ptr ... */
11740*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11741*4882a593Smuzhiyun                 u32 destval32;
11742*4882a593Smuzhiyun 
11743*4882a593Smuzhiyun                 destval32 = fetch_data_long(destoffset);
11744*4882a593Smuzhiyun                 TRACE_AND_STEP();
11745*4882a593Smuzhiyun                 destval32 = inc_long(destval32);
11746*4882a593Smuzhiyun                 store_data_long(destoffset, destval32);
11747*4882a593Smuzhiyun             }
11748*4882a593Smuzhiyun             else {
11749*4882a593Smuzhiyun                 u16 destval16;
11750*4882a593Smuzhiyun 
11751*4882a593Smuzhiyun                 destval16 = fetch_data_word(destoffset);
11752*4882a593Smuzhiyun                 TRACE_AND_STEP();
11753*4882a593Smuzhiyun                 destval16 = inc_word(destval16);
11754*4882a593Smuzhiyun                 store_data_word(destoffset, destval16);
11755*4882a593Smuzhiyun             }
11756*4882a593Smuzhiyun             break;
11757*4882a593Smuzhiyun         case 1:                /* dec word ptr ... */
11758*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11759*4882a593Smuzhiyun                 u32 destval32;
11760*4882a593Smuzhiyun 
11761*4882a593Smuzhiyun                 destval32 = fetch_data_long(destoffset);
11762*4882a593Smuzhiyun                 TRACE_AND_STEP();
11763*4882a593Smuzhiyun                 destval32 = dec_long(destval32);
11764*4882a593Smuzhiyun                 store_data_long(destoffset, destval32);
11765*4882a593Smuzhiyun             }
11766*4882a593Smuzhiyun             else {
11767*4882a593Smuzhiyun                 u16 destval16;
11768*4882a593Smuzhiyun 
11769*4882a593Smuzhiyun                 destval16 = fetch_data_word(destoffset);
11770*4882a593Smuzhiyun                 TRACE_AND_STEP();
11771*4882a593Smuzhiyun                 destval16 = dec_word(destval16);
11772*4882a593Smuzhiyun                 store_data_word(destoffset, destval16);
11773*4882a593Smuzhiyun             }
11774*4882a593Smuzhiyun             break;
11775*4882a593Smuzhiyun         case 2:                /* call word ptr ... */
11776*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11777*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11778*4882a593Smuzhiyun                 TRACE_AND_STEP();
11779*4882a593Smuzhiyun                 push_long(M.x86.R_EIP);
11780*4882a593Smuzhiyun                 M.x86.R_EIP = destval;
11781*4882a593Smuzhiyun             } else {
11782*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11783*4882a593Smuzhiyun                 TRACE_AND_STEP();
11784*4882a593Smuzhiyun                 push_word(M.x86.R_IP);
11785*4882a593Smuzhiyun                 M.x86.R_IP = destval;
11786*4882a593Smuzhiyun             }
11787*4882a593Smuzhiyun             break;
11788*4882a593Smuzhiyun         case 3:                /* call far ptr ... */
11789*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11790*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11791*4882a593Smuzhiyun                 destval2 = fetch_data_word(destoffset + 4);
11792*4882a593Smuzhiyun                 TRACE_AND_STEP();
11793*4882a593Smuzhiyun                 push_long(M.x86.R_CS);
11794*4882a593Smuzhiyun                 M.x86.R_CS = destval2;
11795*4882a593Smuzhiyun                 push_long(M.x86.R_EIP);
11796*4882a593Smuzhiyun                 M.x86.R_EIP = destval;
11797*4882a593Smuzhiyun             } else {
11798*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11799*4882a593Smuzhiyun                 destval2 = fetch_data_word(destoffset + 2);
11800*4882a593Smuzhiyun                 TRACE_AND_STEP();
11801*4882a593Smuzhiyun                 push_word(M.x86.R_CS);
11802*4882a593Smuzhiyun                 M.x86.R_CS = destval2;
11803*4882a593Smuzhiyun                 push_word(M.x86.R_IP);
11804*4882a593Smuzhiyun                 M.x86.R_IP = destval;
11805*4882a593Smuzhiyun             }
11806*4882a593Smuzhiyun             break;
11807*4882a593Smuzhiyun         case 4:                /* jmp word ptr ... */
11808*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
11809*4882a593Smuzhiyun             TRACE_AND_STEP();
11810*4882a593Smuzhiyun             M.x86.R_IP = destval;
11811*4882a593Smuzhiyun             break;
11812*4882a593Smuzhiyun         case 5:                /* jmp far ptr ... */
11813*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
11814*4882a593Smuzhiyun             destval2 = fetch_data_word(destoffset + 2);
11815*4882a593Smuzhiyun             TRACE_AND_STEP();
11816*4882a593Smuzhiyun             M.x86.R_IP = destval;
11817*4882a593Smuzhiyun             M.x86.R_CS = destval2;
11818*4882a593Smuzhiyun             break;
11819*4882a593Smuzhiyun         case 6:                /*  push word ptr ... */
11820*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11821*4882a593Smuzhiyun                 u32 destval32;
11822*4882a593Smuzhiyun 
11823*4882a593Smuzhiyun                 destval32 = fetch_data_long(destoffset);
11824*4882a593Smuzhiyun                 TRACE_AND_STEP();
11825*4882a593Smuzhiyun                 push_long(destval32);
11826*4882a593Smuzhiyun             }
11827*4882a593Smuzhiyun             else {
11828*4882a593Smuzhiyun                 u16 destval16;
11829*4882a593Smuzhiyun 
11830*4882a593Smuzhiyun                 destval16 = fetch_data_word(destoffset);
11831*4882a593Smuzhiyun                 TRACE_AND_STEP();
11832*4882a593Smuzhiyun                 push_word(destval16);
11833*4882a593Smuzhiyun             }
11834*4882a593Smuzhiyun             break;
11835*4882a593Smuzhiyun         }
11836*4882a593Smuzhiyun         break;
11837*4882a593Smuzhiyun     case 1:
11838*4882a593Smuzhiyun         destoffset = decode_rm01_address(rl);
11839*4882a593Smuzhiyun         DECODE_PRINTF("\n");
11840*4882a593Smuzhiyun         switch (rh) {
11841*4882a593Smuzhiyun         case 0:
11842*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11843*4882a593Smuzhiyun                 u32 destval32;
11844*4882a593Smuzhiyun 
11845*4882a593Smuzhiyun                 destval32 = fetch_data_long(destoffset);
11846*4882a593Smuzhiyun                 TRACE_AND_STEP();
11847*4882a593Smuzhiyun                 destval32 = inc_long(destval32);
11848*4882a593Smuzhiyun                 store_data_long(destoffset, destval32);
11849*4882a593Smuzhiyun             }
11850*4882a593Smuzhiyun             else {
11851*4882a593Smuzhiyun                 u16 destval16;
11852*4882a593Smuzhiyun 
11853*4882a593Smuzhiyun                 destval16 = fetch_data_word(destoffset);
11854*4882a593Smuzhiyun                 TRACE_AND_STEP();
11855*4882a593Smuzhiyun                 destval16 = inc_word(destval16);
11856*4882a593Smuzhiyun                 store_data_word(destoffset, destval16);
11857*4882a593Smuzhiyun             }
11858*4882a593Smuzhiyun             break;
11859*4882a593Smuzhiyun         case 1:
11860*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11861*4882a593Smuzhiyun                 u32 destval32;
11862*4882a593Smuzhiyun 
11863*4882a593Smuzhiyun                 destval32 = fetch_data_long(destoffset);
11864*4882a593Smuzhiyun                 TRACE_AND_STEP();
11865*4882a593Smuzhiyun                 destval32 = dec_long(destval32);
11866*4882a593Smuzhiyun                 store_data_long(destoffset, destval32);
11867*4882a593Smuzhiyun             }
11868*4882a593Smuzhiyun             else {
11869*4882a593Smuzhiyun                 u16 destval16;
11870*4882a593Smuzhiyun 
11871*4882a593Smuzhiyun                 destval16 = fetch_data_word(destoffset);
11872*4882a593Smuzhiyun                 TRACE_AND_STEP();
11873*4882a593Smuzhiyun                 destval16 = dec_word(destval16);
11874*4882a593Smuzhiyun                 store_data_word(destoffset, destval16);
11875*4882a593Smuzhiyun             }
11876*4882a593Smuzhiyun             break;
11877*4882a593Smuzhiyun         case 2:                /* call word ptr ... */
11878*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11879*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11880*4882a593Smuzhiyun                 TRACE_AND_STEP();
11881*4882a593Smuzhiyun                 push_long(M.x86.R_EIP);
11882*4882a593Smuzhiyun                 M.x86.R_EIP = destval;
11883*4882a593Smuzhiyun             } else {
11884*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11885*4882a593Smuzhiyun                 TRACE_AND_STEP();
11886*4882a593Smuzhiyun                 push_word(M.x86.R_IP);
11887*4882a593Smuzhiyun                 M.x86.R_IP = destval;
11888*4882a593Smuzhiyun             }
11889*4882a593Smuzhiyun             break;
11890*4882a593Smuzhiyun         case 3:                /* call far ptr ... */
11891*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11892*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11893*4882a593Smuzhiyun                 destval2 = fetch_data_word(destoffset + 4);
11894*4882a593Smuzhiyun                 TRACE_AND_STEP();
11895*4882a593Smuzhiyun                 push_long(M.x86.R_CS);
11896*4882a593Smuzhiyun                 M.x86.R_CS = destval2;
11897*4882a593Smuzhiyun                 push_long(M.x86.R_EIP);
11898*4882a593Smuzhiyun                 M.x86.R_EIP = destval;
11899*4882a593Smuzhiyun             } else {
11900*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11901*4882a593Smuzhiyun                 destval2 = fetch_data_word(destoffset + 2);
11902*4882a593Smuzhiyun                 TRACE_AND_STEP();
11903*4882a593Smuzhiyun                 push_word(M.x86.R_CS);
11904*4882a593Smuzhiyun                 M.x86.R_CS = destval2;
11905*4882a593Smuzhiyun                 push_word(M.x86.R_IP);
11906*4882a593Smuzhiyun                 M.x86.R_IP = destval;
11907*4882a593Smuzhiyun             }
11908*4882a593Smuzhiyun             break;
11909*4882a593Smuzhiyun         case 4:                /* jmp word ptr ... */
11910*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
11911*4882a593Smuzhiyun             TRACE_AND_STEP();
11912*4882a593Smuzhiyun             M.x86.R_IP = destval;
11913*4882a593Smuzhiyun             break;
11914*4882a593Smuzhiyun         case 5:                /* jmp far ptr ... */
11915*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
11916*4882a593Smuzhiyun             destval2 = fetch_data_word(destoffset + 2);
11917*4882a593Smuzhiyun             TRACE_AND_STEP();
11918*4882a593Smuzhiyun             M.x86.R_IP = destval;
11919*4882a593Smuzhiyun             M.x86.R_CS = destval2;
11920*4882a593Smuzhiyun             break;
11921*4882a593Smuzhiyun         case 6:                /*  push word ptr ... */
11922*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11923*4882a593Smuzhiyun                 u32 destval32;
11924*4882a593Smuzhiyun 
11925*4882a593Smuzhiyun                 destval32 = fetch_data_long(destoffset);
11926*4882a593Smuzhiyun                 TRACE_AND_STEP();
11927*4882a593Smuzhiyun                 push_long(destval32);
11928*4882a593Smuzhiyun             }
11929*4882a593Smuzhiyun             else {
11930*4882a593Smuzhiyun                 u16 destval16;
11931*4882a593Smuzhiyun 
11932*4882a593Smuzhiyun                 destval16 = fetch_data_word(destoffset);
11933*4882a593Smuzhiyun                 TRACE_AND_STEP();
11934*4882a593Smuzhiyun                 push_word(destval16);
11935*4882a593Smuzhiyun             }
11936*4882a593Smuzhiyun             break;
11937*4882a593Smuzhiyun         }
11938*4882a593Smuzhiyun         break;
11939*4882a593Smuzhiyun     case 2:
11940*4882a593Smuzhiyun         destoffset = decode_rm10_address(rl);
11941*4882a593Smuzhiyun         DECODE_PRINTF("\n");
11942*4882a593Smuzhiyun         switch (rh) {
11943*4882a593Smuzhiyun         case 0:
11944*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11945*4882a593Smuzhiyun                 u32 destval32;
11946*4882a593Smuzhiyun 
11947*4882a593Smuzhiyun                 destval32 = fetch_data_long(destoffset);
11948*4882a593Smuzhiyun                 TRACE_AND_STEP();
11949*4882a593Smuzhiyun                 destval32 = inc_long(destval32);
11950*4882a593Smuzhiyun                 store_data_long(destoffset, destval32);
11951*4882a593Smuzhiyun             }
11952*4882a593Smuzhiyun             else {
11953*4882a593Smuzhiyun                 u16 destval16;
11954*4882a593Smuzhiyun 
11955*4882a593Smuzhiyun                 destval16 = fetch_data_word(destoffset);
11956*4882a593Smuzhiyun                 TRACE_AND_STEP();
11957*4882a593Smuzhiyun                 destval16 = inc_word(destval16);
11958*4882a593Smuzhiyun                 store_data_word(destoffset, destval16);
11959*4882a593Smuzhiyun             }
11960*4882a593Smuzhiyun             break;
11961*4882a593Smuzhiyun         case 1:
11962*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11963*4882a593Smuzhiyun                 u32 destval32;
11964*4882a593Smuzhiyun 
11965*4882a593Smuzhiyun                 destval32 = fetch_data_long(destoffset);
11966*4882a593Smuzhiyun                 TRACE_AND_STEP();
11967*4882a593Smuzhiyun                 destval32 = dec_long(destval32);
11968*4882a593Smuzhiyun                 store_data_long(destoffset, destval32);
11969*4882a593Smuzhiyun             }
11970*4882a593Smuzhiyun             else {
11971*4882a593Smuzhiyun                 u16 destval16;
11972*4882a593Smuzhiyun 
11973*4882a593Smuzhiyun                 destval16 = fetch_data_word(destoffset);
11974*4882a593Smuzhiyun                 TRACE_AND_STEP();
11975*4882a593Smuzhiyun                 destval16 = dec_word(destval16);
11976*4882a593Smuzhiyun                 store_data_word(destoffset, destval16);
11977*4882a593Smuzhiyun             }
11978*4882a593Smuzhiyun             break;
11979*4882a593Smuzhiyun         case 2:                /* call word ptr ... */
11980*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11981*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11982*4882a593Smuzhiyun                 TRACE_AND_STEP();
11983*4882a593Smuzhiyun                 push_long(M.x86.R_EIP);
11984*4882a593Smuzhiyun                 M.x86.R_EIP = destval;
11985*4882a593Smuzhiyun             } else {
11986*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
11987*4882a593Smuzhiyun                 TRACE_AND_STEP();
11988*4882a593Smuzhiyun                 push_word(M.x86.R_IP);
11989*4882a593Smuzhiyun                 M.x86.R_IP = destval;
11990*4882a593Smuzhiyun             }
11991*4882a593Smuzhiyun             break;
11992*4882a593Smuzhiyun         case 3:                /* call far ptr ... */
11993*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11994*4882a593Smuzhiyun                 destval = fetch_data_long(destoffset);
11995*4882a593Smuzhiyun                 destval2 = fetch_data_word(destoffset + 4);
11996*4882a593Smuzhiyun                 TRACE_AND_STEP();
11997*4882a593Smuzhiyun                 push_long(M.x86.R_CS);
11998*4882a593Smuzhiyun                 M.x86.R_CS = destval2;
11999*4882a593Smuzhiyun                 push_long(M.x86.R_EIP);
12000*4882a593Smuzhiyun                 M.x86.R_EIP = destval;
12001*4882a593Smuzhiyun             } else {
12002*4882a593Smuzhiyun                 destval = fetch_data_word(destoffset);
12003*4882a593Smuzhiyun                 destval2 = fetch_data_word(destoffset + 2);
12004*4882a593Smuzhiyun                 TRACE_AND_STEP();
12005*4882a593Smuzhiyun                 push_word(M.x86.R_CS);
12006*4882a593Smuzhiyun                 M.x86.R_CS = destval2;
12007*4882a593Smuzhiyun                 push_word(M.x86.R_IP);
12008*4882a593Smuzhiyun                 M.x86.R_IP = destval;
12009*4882a593Smuzhiyun             }
12010*4882a593Smuzhiyun             break;
12011*4882a593Smuzhiyun         case 4:                /* jmp word ptr ... */
12012*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
12013*4882a593Smuzhiyun             TRACE_AND_STEP();
12014*4882a593Smuzhiyun             M.x86.R_IP = destval;
12015*4882a593Smuzhiyun             break;
12016*4882a593Smuzhiyun         case 5:                /* jmp far ptr ... */
12017*4882a593Smuzhiyun             destval = fetch_data_word(destoffset);
12018*4882a593Smuzhiyun             destval2 = fetch_data_word(destoffset + 2);
12019*4882a593Smuzhiyun             TRACE_AND_STEP();
12020*4882a593Smuzhiyun             M.x86.R_IP = destval;
12021*4882a593Smuzhiyun             M.x86.R_CS = destval2;
12022*4882a593Smuzhiyun             break;
12023*4882a593Smuzhiyun         case 6:                /*  push word ptr ... */
12024*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12025*4882a593Smuzhiyun                 u32 destval32;
12026*4882a593Smuzhiyun 
12027*4882a593Smuzhiyun                 destval32 = fetch_data_long(destoffset);
12028*4882a593Smuzhiyun                 TRACE_AND_STEP();
12029*4882a593Smuzhiyun                 push_long(destval32);
12030*4882a593Smuzhiyun             }
12031*4882a593Smuzhiyun             else {
12032*4882a593Smuzhiyun                 u16 destval16;
12033*4882a593Smuzhiyun 
12034*4882a593Smuzhiyun                 destval16 = fetch_data_word(destoffset);
12035*4882a593Smuzhiyun                 TRACE_AND_STEP();
12036*4882a593Smuzhiyun                 push_word(destval16);
12037*4882a593Smuzhiyun             }
12038*4882a593Smuzhiyun             break;
12039*4882a593Smuzhiyun         }
12040*4882a593Smuzhiyun         break;
12041*4882a593Smuzhiyun     case 3:
12042*4882a593Smuzhiyun         switch (rh) {
12043*4882a593Smuzhiyun         case 0:
12044*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12045*4882a593Smuzhiyun                 u32 *destreg32;
12046*4882a593Smuzhiyun 
12047*4882a593Smuzhiyun                 destreg32 = DECODE_RM_LONG_REGISTER(rl);
12048*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
12049*4882a593Smuzhiyun                 TRACE_AND_STEP();
12050*4882a593Smuzhiyun                 *destreg32 = inc_long(*destreg32);
12051*4882a593Smuzhiyun             }
12052*4882a593Smuzhiyun             else {
12053*4882a593Smuzhiyun                 u16 *destreg16;
12054*4882a593Smuzhiyun 
12055*4882a593Smuzhiyun                 destreg16 = DECODE_RM_WORD_REGISTER(rl);
12056*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
12057*4882a593Smuzhiyun                 TRACE_AND_STEP();
12058*4882a593Smuzhiyun                 *destreg16 = inc_word(*destreg16);
12059*4882a593Smuzhiyun             }
12060*4882a593Smuzhiyun             break;
12061*4882a593Smuzhiyun         case 1:
12062*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12063*4882a593Smuzhiyun                 u32 *destreg32;
12064*4882a593Smuzhiyun 
12065*4882a593Smuzhiyun                 destreg32 = DECODE_RM_LONG_REGISTER(rl);
12066*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
12067*4882a593Smuzhiyun                 TRACE_AND_STEP();
12068*4882a593Smuzhiyun                 *destreg32 = dec_long(*destreg32);
12069*4882a593Smuzhiyun             }
12070*4882a593Smuzhiyun             else {
12071*4882a593Smuzhiyun                 u16 *destreg16;
12072*4882a593Smuzhiyun 
12073*4882a593Smuzhiyun                 destreg16 = DECODE_RM_WORD_REGISTER(rl);
12074*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
12075*4882a593Smuzhiyun                 TRACE_AND_STEP();
12076*4882a593Smuzhiyun                 *destreg16 = dec_word(*destreg16);
12077*4882a593Smuzhiyun             }
12078*4882a593Smuzhiyun             break;
12079*4882a593Smuzhiyun         case 2:                /* call word ptr ... */
12080*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12081*4882a593Smuzhiyun                 destreg = (u16 *)DECODE_RM_LONG_REGISTER(rl);
12082*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
12083*4882a593Smuzhiyun                 TRACE_AND_STEP();
12084*4882a593Smuzhiyun                 push_long(M.x86.R_EIP);
12085*4882a593Smuzhiyun                 M.x86.R_EIP = *destreg;
12086*4882a593Smuzhiyun             } else {
12087*4882a593Smuzhiyun                 destreg = DECODE_RM_WORD_REGISTER(rl);
12088*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
12089*4882a593Smuzhiyun                 TRACE_AND_STEP();
12090*4882a593Smuzhiyun                 push_word(M.x86.R_IP);
12091*4882a593Smuzhiyun                 M.x86.R_IP = *destreg;
12092*4882a593Smuzhiyun             }
12093*4882a593Smuzhiyun             break;
12094*4882a593Smuzhiyun         case 3:                /* jmp far ptr ... */
12095*4882a593Smuzhiyun             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12096*4882a593Smuzhiyun             TRACE_AND_STEP();
12097*4882a593Smuzhiyun             HALT_SYS();
12098*4882a593Smuzhiyun             break;
12099*4882a593Smuzhiyun 
12100*4882a593Smuzhiyun         case 4:                /* jmp  ... */
12101*4882a593Smuzhiyun             destreg = DECODE_RM_WORD_REGISTER(rl);
12102*4882a593Smuzhiyun             DECODE_PRINTF("\n");
12103*4882a593Smuzhiyun             TRACE_AND_STEP();
12104*4882a593Smuzhiyun             M.x86.R_IP = (u16) (*destreg);
12105*4882a593Smuzhiyun             break;
12106*4882a593Smuzhiyun         case 5:                /* jmp far ptr ... */
12107*4882a593Smuzhiyun             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12108*4882a593Smuzhiyun             TRACE_AND_STEP();
12109*4882a593Smuzhiyun             HALT_SYS();
12110*4882a593Smuzhiyun             break;
12111*4882a593Smuzhiyun         case 6:
12112*4882a593Smuzhiyun             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12113*4882a593Smuzhiyun                 u32 *destreg32;
12114*4882a593Smuzhiyun 
12115*4882a593Smuzhiyun                 destreg32 = DECODE_RM_LONG_REGISTER(rl);
12116*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
12117*4882a593Smuzhiyun                 TRACE_AND_STEP();
12118*4882a593Smuzhiyun                 push_long(*destreg32);
12119*4882a593Smuzhiyun             }
12120*4882a593Smuzhiyun             else {
12121*4882a593Smuzhiyun                 u16 *destreg16;
12122*4882a593Smuzhiyun 
12123*4882a593Smuzhiyun                 destreg16 = DECODE_RM_WORD_REGISTER(rl);
12124*4882a593Smuzhiyun                 DECODE_PRINTF("\n");
12125*4882a593Smuzhiyun                 TRACE_AND_STEP();
12126*4882a593Smuzhiyun                 push_word(*destreg16);
12127*4882a593Smuzhiyun             }
12128*4882a593Smuzhiyun             break;
12129*4882a593Smuzhiyun         }
12130*4882a593Smuzhiyun         break;
12131*4882a593Smuzhiyun     }
12132*4882a593Smuzhiyun     DECODE_CLEAR_SEGOVR();
12133*4882a593Smuzhiyun     END_OF_INSTR();
12134*4882a593Smuzhiyun }
12135*4882a593Smuzhiyun 
12136*4882a593Smuzhiyun /***************************************************************************
12137*4882a593Smuzhiyun  * Single byte operation code table:
12138*4882a593Smuzhiyun  **************************************************************************/
12139*4882a593Smuzhiyun void (*x86emu_optab[256]) (u8) = {
12140*4882a593Smuzhiyun /*  0x00 */ x86emuOp_add_byte_RM_R,
12141*4882a593Smuzhiyun /*  0x01 */ x86emuOp_add_word_RM_R,
12142*4882a593Smuzhiyun /*  0x02 */ x86emuOp_add_byte_R_RM,
12143*4882a593Smuzhiyun /*  0x03 */ x86emuOp_add_word_R_RM,
12144*4882a593Smuzhiyun /*  0x04 */ x86emuOp_add_byte_AL_IMM,
12145*4882a593Smuzhiyun /*  0x05 */ x86emuOp_add_word_AX_IMM,
12146*4882a593Smuzhiyun /*  0x06 */ x86emuOp_push_ES,
12147*4882a593Smuzhiyun /*  0x07 */ x86emuOp_pop_ES,
12148*4882a593Smuzhiyun /*  0x08 */ x86emuOp_or_byte_RM_R,
12149*4882a593Smuzhiyun /*  0x09 */ x86emuOp_or_word_RM_R,
12150*4882a593Smuzhiyun /*  0x0a */ x86emuOp_or_byte_R_RM,
12151*4882a593Smuzhiyun /*  0x0b */ x86emuOp_or_word_R_RM,
12152*4882a593Smuzhiyun /*  0x0c */ x86emuOp_or_byte_AL_IMM,
12153*4882a593Smuzhiyun /*  0x0d */ x86emuOp_or_word_AX_IMM,
12154*4882a593Smuzhiyun /*  0x0e */ x86emuOp_push_CS,
12155*4882a593Smuzhiyun /*  0x0f */ x86emuOp_two_byte,
12156*4882a593Smuzhiyun /*  0x10 */ x86emuOp_adc_byte_RM_R,
12157*4882a593Smuzhiyun /*  0x11 */ x86emuOp_adc_word_RM_R,
12158*4882a593Smuzhiyun /*  0x12 */ x86emuOp_adc_byte_R_RM,
12159*4882a593Smuzhiyun /*  0x13 */ x86emuOp_adc_word_R_RM,
12160*4882a593Smuzhiyun /*  0x14 */ x86emuOp_adc_byte_AL_IMM,
12161*4882a593Smuzhiyun /*  0x15 */ x86emuOp_adc_word_AX_IMM,
12162*4882a593Smuzhiyun /*  0x16 */ x86emuOp_push_SS,
12163*4882a593Smuzhiyun /*  0x17 */ x86emuOp_pop_SS,
12164*4882a593Smuzhiyun /*  0x18 */ x86emuOp_sbb_byte_RM_R,
12165*4882a593Smuzhiyun /*  0x19 */ x86emuOp_sbb_word_RM_R,
12166*4882a593Smuzhiyun /*  0x1a */ x86emuOp_sbb_byte_R_RM,
12167*4882a593Smuzhiyun /*  0x1b */ x86emuOp_sbb_word_R_RM,
12168*4882a593Smuzhiyun /*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
12169*4882a593Smuzhiyun /*  0x1d */ x86emuOp_sbb_word_AX_IMM,
12170*4882a593Smuzhiyun /*  0x1e */ x86emuOp_push_DS,
12171*4882a593Smuzhiyun /*  0x1f */ x86emuOp_pop_DS,
12172*4882a593Smuzhiyun /*  0x20 */ x86emuOp_and_byte_RM_R,
12173*4882a593Smuzhiyun /*  0x21 */ x86emuOp_and_word_RM_R,
12174*4882a593Smuzhiyun /*  0x22 */ x86emuOp_and_byte_R_RM,
12175*4882a593Smuzhiyun /*  0x23 */ x86emuOp_and_word_R_RM,
12176*4882a593Smuzhiyun /*  0x24 */ x86emuOp_and_byte_AL_IMM,
12177*4882a593Smuzhiyun /*  0x25 */ x86emuOp_and_word_AX_IMM,
12178*4882a593Smuzhiyun /*  0x26 */ x86emuOp_segovr_ES,
12179*4882a593Smuzhiyun /*  0x27 */ x86emuOp_daa,
12180*4882a593Smuzhiyun /*  0x28 */ x86emuOp_sub_byte_RM_R,
12181*4882a593Smuzhiyun /*  0x29 */ x86emuOp_sub_word_RM_R,
12182*4882a593Smuzhiyun /*  0x2a */ x86emuOp_sub_byte_R_RM,
12183*4882a593Smuzhiyun /*  0x2b */ x86emuOp_sub_word_R_RM,
12184*4882a593Smuzhiyun /*  0x2c */ x86emuOp_sub_byte_AL_IMM,
12185*4882a593Smuzhiyun /*  0x2d */ x86emuOp_sub_word_AX_IMM,
12186*4882a593Smuzhiyun /*  0x2e */ x86emuOp_segovr_CS,
12187*4882a593Smuzhiyun /*  0x2f */ x86emuOp_das,
12188*4882a593Smuzhiyun /*  0x30 */ x86emuOp_xor_byte_RM_R,
12189*4882a593Smuzhiyun /*  0x31 */ x86emuOp_xor_word_RM_R,
12190*4882a593Smuzhiyun /*  0x32 */ x86emuOp_xor_byte_R_RM,
12191*4882a593Smuzhiyun /*  0x33 */ x86emuOp_xor_word_R_RM,
12192*4882a593Smuzhiyun /*  0x34 */ x86emuOp_xor_byte_AL_IMM,
12193*4882a593Smuzhiyun /*  0x35 */ x86emuOp_xor_word_AX_IMM,
12194*4882a593Smuzhiyun /*  0x36 */ x86emuOp_segovr_SS,
12195*4882a593Smuzhiyun /*  0x37 */ x86emuOp_aaa,
12196*4882a593Smuzhiyun /*  0x38 */ x86emuOp_cmp_byte_RM_R,
12197*4882a593Smuzhiyun /*  0x39 */ x86emuOp_cmp_word_RM_R,
12198*4882a593Smuzhiyun /*  0x3a */ x86emuOp_cmp_byte_R_RM,
12199*4882a593Smuzhiyun /*  0x3b */ x86emuOp_cmp_word_R_RM,
12200*4882a593Smuzhiyun /*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
12201*4882a593Smuzhiyun /*  0x3d */ x86emuOp_cmp_word_AX_IMM,
12202*4882a593Smuzhiyun /*  0x3e */ x86emuOp_segovr_DS,
12203*4882a593Smuzhiyun /*  0x3f */ x86emuOp_aas,
12204*4882a593Smuzhiyun /*  0x40 */ x86emuOp_inc_AX,
12205*4882a593Smuzhiyun /*  0x41 */ x86emuOp_inc_CX,
12206*4882a593Smuzhiyun /*  0x42 */ x86emuOp_inc_DX,
12207*4882a593Smuzhiyun /*  0x43 */ x86emuOp_inc_BX,
12208*4882a593Smuzhiyun /*  0x44 */ x86emuOp_inc_SP,
12209*4882a593Smuzhiyun /*  0x45 */ x86emuOp_inc_BP,
12210*4882a593Smuzhiyun /*  0x46 */ x86emuOp_inc_SI,
12211*4882a593Smuzhiyun /*  0x47 */ x86emuOp_inc_DI,
12212*4882a593Smuzhiyun /*  0x48 */ x86emuOp_dec_AX,
12213*4882a593Smuzhiyun /*  0x49 */ x86emuOp_dec_CX,
12214*4882a593Smuzhiyun /*  0x4a */ x86emuOp_dec_DX,
12215*4882a593Smuzhiyun /*  0x4b */ x86emuOp_dec_BX,
12216*4882a593Smuzhiyun /*  0x4c */ x86emuOp_dec_SP,
12217*4882a593Smuzhiyun /*  0x4d */ x86emuOp_dec_BP,
12218*4882a593Smuzhiyun /*  0x4e */ x86emuOp_dec_SI,
12219*4882a593Smuzhiyun /*  0x4f */ x86emuOp_dec_DI,
12220*4882a593Smuzhiyun /*  0x50 */ x86emuOp_push_AX,
12221*4882a593Smuzhiyun /*  0x51 */ x86emuOp_push_CX,
12222*4882a593Smuzhiyun /*  0x52 */ x86emuOp_push_DX,
12223*4882a593Smuzhiyun /*  0x53 */ x86emuOp_push_BX,
12224*4882a593Smuzhiyun /*  0x54 */ x86emuOp_push_SP,
12225*4882a593Smuzhiyun /*  0x55 */ x86emuOp_push_BP,
12226*4882a593Smuzhiyun /*  0x56 */ x86emuOp_push_SI,
12227*4882a593Smuzhiyun /*  0x57 */ x86emuOp_push_DI,
12228*4882a593Smuzhiyun /*  0x58 */ x86emuOp_pop_AX,
12229*4882a593Smuzhiyun /*  0x59 */ x86emuOp_pop_CX,
12230*4882a593Smuzhiyun /*  0x5a */ x86emuOp_pop_DX,
12231*4882a593Smuzhiyun /*  0x5b */ x86emuOp_pop_BX,
12232*4882a593Smuzhiyun /*  0x5c */ x86emuOp_pop_SP,
12233*4882a593Smuzhiyun /*  0x5d */ x86emuOp_pop_BP,
12234*4882a593Smuzhiyun /*  0x5e */ x86emuOp_pop_SI,
12235*4882a593Smuzhiyun /*  0x5f */ x86emuOp_pop_DI,
12236*4882a593Smuzhiyun /*  0x60 */ x86emuOp_push_all,
12237*4882a593Smuzhiyun /*  0x61 */ x86emuOp_pop_all,
12238*4882a593Smuzhiyun                                                 /*  0x62 */ x86emuOp_illegal_op,
12239*4882a593Smuzhiyun                                                 /* bound */
12240*4882a593Smuzhiyun                                                 /*  0x63 */ x86emuOp_illegal_op,
12241*4882a593Smuzhiyun                                                 /* arpl */
12242*4882a593Smuzhiyun /*  0x64 */ x86emuOp_segovr_FS,
12243*4882a593Smuzhiyun /*  0x65 */ x86emuOp_segovr_GS,
12244*4882a593Smuzhiyun /*  0x66 */ x86emuOp_prefix_data,
12245*4882a593Smuzhiyun /*  0x67 */ x86emuOp_prefix_addr,
12246*4882a593Smuzhiyun /*  0x68 */ x86emuOp_push_word_IMM,
12247*4882a593Smuzhiyun /*  0x69 */ x86emuOp_imul_word_IMM,
12248*4882a593Smuzhiyun /*  0x6a */ x86emuOp_push_byte_IMM,
12249*4882a593Smuzhiyun /*  0x6b */ x86emuOp_imul_byte_IMM,
12250*4882a593Smuzhiyun /*  0x6c */ x86emuOp_ins_byte,
12251*4882a593Smuzhiyun /*  0x6d */ x86emuOp_ins_word,
12252*4882a593Smuzhiyun /*  0x6e */ x86emuOp_outs_byte,
12253*4882a593Smuzhiyun /*  0x6f */ x86emuOp_outs_word,
12254*4882a593Smuzhiyun /*  0x70 */ x86emuOp_jump_near_O,
12255*4882a593Smuzhiyun /*  0x71 */ x86emuOp_jump_near_NO,
12256*4882a593Smuzhiyun /*  0x72 */ x86emuOp_jump_near_B,
12257*4882a593Smuzhiyun /*  0x73 */ x86emuOp_jump_near_NB,
12258*4882a593Smuzhiyun /*  0x74 */ x86emuOp_jump_near_Z,
12259*4882a593Smuzhiyun /*  0x75 */ x86emuOp_jump_near_NZ,
12260*4882a593Smuzhiyun /*  0x76 */ x86emuOp_jump_near_BE,
12261*4882a593Smuzhiyun /*  0x77 */ x86emuOp_jump_near_NBE,
12262*4882a593Smuzhiyun /*  0x78 */ x86emuOp_jump_near_S,
12263*4882a593Smuzhiyun /*  0x79 */ x86emuOp_jump_near_NS,
12264*4882a593Smuzhiyun /*  0x7a */ x86emuOp_jump_near_P,
12265*4882a593Smuzhiyun /*  0x7b */ x86emuOp_jump_near_NP,
12266*4882a593Smuzhiyun /*  0x7c */ x86emuOp_jump_near_L,
12267*4882a593Smuzhiyun /*  0x7d */ x86emuOp_jump_near_NL,
12268*4882a593Smuzhiyun /*  0x7e */ x86emuOp_jump_near_LE,
12269*4882a593Smuzhiyun /*  0x7f */ x86emuOp_jump_near_NLE,
12270*4882a593Smuzhiyun /*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
12271*4882a593Smuzhiyun /*  0x81 */ x86emuOp_opc81_word_RM_IMM,
12272*4882a593Smuzhiyun /*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
12273*4882a593Smuzhiyun /*  0x83 */ x86emuOp_opc83_word_RM_IMM,
12274*4882a593Smuzhiyun /*  0x84 */ x86emuOp_test_byte_RM_R,
12275*4882a593Smuzhiyun /*  0x85 */ x86emuOp_test_word_RM_R,
12276*4882a593Smuzhiyun /*  0x86 */ x86emuOp_xchg_byte_RM_R,
12277*4882a593Smuzhiyun /*  0x87 */ x86emuOp_xchg_word_RM_R,
12278*4882a593Smuzhiyun /*  0x88 */ x86emuOp_mov_byte_RM_R,
12279*4882a593Smuzhiyun /*  0x89 */ x86emuOp_mov_word_RM_R,
12280*4882a593Smuzhiyun /*  0x8a */ x86emuOp_mov_byte_R_RM,
12281*4882a593Smuzhiyun /*  0x8b */ x86emuOp_mov_word_R_RM,
12282*4882a593Smuzhiyun /*  0x8c */ x86emuOp_mov_word_RM_SR,
12283*4882a593Smuzhiyun /*  0x8d */ x86emuOp_lea_word_R_M,
12284*4882a593Smuzhiyun /*  0x8e */ x86emuOp_mov_word_SR_RM,
12285*4882a593Smuzhiyun /*  0x8f */ x86emuOp_pop_RM,
12286*4882a593Smuzhiyun /*  0x90 */ x86emuOp_nop,
12287*4882a593Smuzhiyun /*  0x91 */ x86emuOp_xchg_word_AX_CX,
12288*4882a593Smuzhiyun /*  0x92 */ x86emuOp_xchg_word_AX_DX,
12289*4882a593Smuzhiyun /*  0x93 */ x86emuOp_xchg_word_AX_BX,
12290*4882a593Smuzhiyun /*  0x94 */ x86emuOp_xchg_word_AX_SP,
12291*4882a593Smuzhiyun /*  0x95 */ x86emuOp_xchg_word_AX_BP,
12292*4882a593Smuzhiyun /*  0x96 */ x86emuOp_xchg_word_AX_SI,
12293*4882a593Smuzhiyun /*  0x97 */ x86emuOp_xchg_word_AX_DI,
12294*4882a593Smuzhiyun /*  0x98 */ x86emuOp_cbw,
12295*4882a593Smuzhiyun /*  0x99 */ x86emuOp_cwd,
12296*4882a593Smuzhiyun /*  0x9a */ x86emuOp_call_far_IMM,
12297*4882a593Smuzhiyun /*  0x9b */ x86emuOp_wait,
12298*4882a593Smuzhiyun /*  0x9c */ x86emuOp_pushf_word,
12299*4882a593Smuzhiyun /*  0x9d */ x86emuOp_popf_word,
12300*4882a593Smuzhiyun /*  0x9e */ x86emuOp_sahf,
12301*4882a593Smuzhiyun /*  0x9f */ x86emuOp_lahf,
12302*4882a593Smuzhiyun /*  0xa0 */ x86emuOp_mov_AL_M_IMM,
12303*4882a593Smuzhiyun /*  0xa1 */ x86emuOp_mov_AX_M_IMM,
12304*4882a593Smuzhiyun /*  0xa2 */ x86emuOp_mov_M_AL_IMM,
12305*4882a593Smuzhiyun /*  0xa3 */ x86emuOp_mov_M_AX_IMM,
12306*4882a593Smuzhiyun /*  0xa4 */ x86emuOp_movs_byte,
12307*4882a593Smuzhiyun /*  0xa5 */ x86emuOp_movs_word,
12308*4882a593Smuzhiyun /*  0xa6 */ x86emuOp_cmps_byte,
12309*4882a593Smuzhiyun /*  0xa7 */ x86emuOp_cmps_word,
12310*4882a593Smuzhiyun /*  0xa8 */ x86emuOp_test_AL_IMM,
12311*4882a593Smuzhiyun /*  0xa9 */ x86emuOp_test_AX_IMM,
12312*4882a593Smuzhiyun /*  0xaa */ x86emuOp_stos_byte,
12313*4882a593Smuzhiyun /*  0xab */ x86emuOp_stos_word,
12314*4882a593Smuzhiyun /*  0xac */ x86emuOp_lods_byte,
12315*4882a593Smuzhiyun /*  0xad */ x86emuOp_lods_word,
12316*4882a593Smuzhiyun /*  0xac */ x86emuOp_scas_byte,
12317*4882a593Smuzhiyun /*  0xad */ x86emuOp_scas_word,
12318*4882a593Smuzhiyun /*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
12319*4882a593Smuzhiyun /*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
12320*4882a593Smuzhiyun /*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
12321*4882a593Smuzhiyun /*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
12322*4882a593Smuzhiyun /*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
12323*4882a593Smuzhiyun /*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
12324*4882a593Smuzhiyun /*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
12325*4882a593Smuzhiyun /*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
12326*4882a593Smuzhiyun /*  0xb8 */ x86emuOp_mov_word_AX_IMM,
12327*4882a593Smuzhiyun /*  0xb9 */ x86emuOp_mov_word_CX_IMM,
12328*4882a593Smuzhiyun /*  0xba */ x86emuOp_mov_word_DX_IMM,
12329*4882a593Smuzhiyun /*  0xbb */ x86emuOp_mov_word_BX_IMM,
12330*4882a593Smuzhiyun /*  0xbc */ x86emuOp_mov_word_SP_IMM,
12331*4882a593Smuzhiyun /*  0xbd */ x86emuOp_mov_word_BP_IMM,
12332*4882a593Smuzhiyun /*  0xbe */ x86emuOp_mov_word_SI_IMM,
12333*4882a593Smuzhiyun /*  0xbf */ x86emuOp_mov_word_DI_IMM,
12334*4882a593Smuzhiyun /*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
12335*4882a593Smuzhiyun /*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
12336*4882a593Smuzhiyun /*  0xc2 */ x86emuOp_ret_near_IMM,
12337*4882a593Smuzhiyun /*  0xc3 */ x86emuOp_ret_near,
12338*4882a593Smuzhiyun /*  0xc4 */ x86emuOp_les_R_IMM,
12339*4882a593Smuzhiyun /*  0xc5 */ x86emuOp_lds_R_IMM,
12340*4882a593Smuzhiyun /*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
12341*4882a593Smuzhiyun /*  0xc7 */ x86emuOp_mov_word_RM_IMM,
12342*4882a593Smuzhiyun /*  0xc8 */ x86emuOp_enter,
12343*4882a593Smuzhiyun /*  0xc9 */ x86emuOp_leave,
12344*4882a593Smuzhiyun /*  0xca */ x86emuOp_ret_far_IMM,
12345*4882a593Smuzhiyun /*  0xcb */ x86emuOp_ret_far,
12346*4882a593Smuzhiyun /*  0xcc */ x86emuOp_int3,
12347*4882a593Smuzhiyun /*  0xcd */ x86emuOp_int_IMM,
12348*4882a593Smuzhiyun /*  0xce */ x86emuOp_into,
12349*4882a593Smuzhiyun /*  0xcf */ x86emuOp_iret,
12350*4882a593Smuzhiyun /*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
12351*4882a593Smuzhiyun /*  0xd1 */ x86emuOp_opcD1_word_RM_1,
12352*4882a593Smuzhiyun /*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
12353*4882a593Smuzhiyun /*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
12354*4882a593Smuzhiyun /*  0xd4 */ x86emuOp_aam,
12355*4882a593Smuzhiyun /*  0xd5 */ x86emuOp_aad,
12356*4882a593Smuzhiyun                                                 /*  0xd6 */ x86emuOp_illegal_op,
12357*4882a593Smuzhiyun                                                 /* Undocumented SETALC instruction */
12358*4882a593Smuzhiyun /*  0xd7 */ x86emuOp_xlat,
12359*4882a593Smuzhiyun /*  0xd8 */ x86emuOp_esc_coprocess_d8,
12360*4882a593Smuzhiyun /*  0xd9 */ x86emuOp_esc_coprocess_d9,
12361*4882a593Smuzhiyun /*  0xda */ x86emuOp_esc_coprocess_da,
12362*4882a593Smuzhiyun /*  0xdb */ x86emuOp_esc_coprocess_db,
12363*4882a593Smuzhiyun /*  0xdc */ x86emuOp_esc_coprocess_dc,
12364*4882a593Smuzhiyun /*  0xdd */ x86emuOp_esc_coprocess_dd,
12365*4882a593Smuzhiyun /*  0xde */ x86emuOp_esc_coprocess_de,
12366*4882a593Smuzhiyun /*  0xdf */ x86emuOp_esc_coprocess_df,
12367*4882a593Smuzhiyun /*  0xe0 */ x86emuOp_loopne,
12368*4882a593Smuzhiyun /*  0xe1 */ x86emuOp_loope,
12369*4882a593Smuzhiyun /*  0xe2 */ x86emuOp_loop,
12370*4882a593Smuzhiyun /*  0xe3 */ x86emuOp_jcxz,
12371*4882a593Smuzhiyun /*  0xe4 */ x86emuOp_in_byte_AL_IMM,
12372*4882a593Smuzhiyun /*  0xe5 */ x86emuOp_in_word_AX_IMM,
12373*4882a593Smuzhiyun /*  0xe6 */ x86emuOp_out_byte_IMM_AL,
12374*4882a593Smuzhiyun /*  0xe7 */ x86emuOp_out_word_IMM_AX,
12375*4882a593Smuzhiyun /*  0xe8 */ x86emuOp_call_near_IMM,
12376*4882a593Smuzhiyun /*  0xe9 */ x86emuOp_jump_near_IMM,
12377*4882a593Smuzhiyun /*  0xea */ x86emuOp_jump_far_IMM,
12378*4882a593Smuzhiyun /*  0xeb */ x86emuOp_jump_byte_IMM,
12379*4882a593Smuzhiyun /*  0xec */ x86emuOp_in_byte_AL_DX,
12380*4882a593Smuzhiyun /*  0xed */ x86emuOp_in_word_AX_DX,
12381*4882a593Smuzhiyun /*  0xee */ x86emuOp_out_byte_DX_AL,
12382*4882a593Smuzhiyun /*  0xef */ x86emuOp_out_word_DX_AX,
12383*4882a593Smuzhiyun /*  0xf0 */ x86emuOp_lock,
12384*4882a593Smuzhiyun /*  0xf1 */ x86emuOp_illegal_op,
12385*4882a593Smuzhiyun /*  0xf2 */ x86emuOp_repne,
12386*4882a593Smuzhiyun /*  0xf3 */ x86emuOp_repe,
12387*4882a593Smuzhiyun /*  0xf4 */ x86emuOp_halt,
12388*4882a593Smuzhiyun /*  0xf5 */ x86emuOp_cmc,
12389*4882a593Smuzhiyun /*  0xf6 */ x86emuOp_opcF6_byte_RM,
12390*4882a593Smuzhiyun /*  0xf7 */ x86emuOp_opcF7_word_RM,
12391*4882a593Smuzhiyun /*  0xf8 */ x86emuOp_clc,
12392*4882a593Smuzhiyun /*  0xf9 */ x86emuOp_stc,
12393*4882a593Smuzhiyun /*  0xfa */ x86emuOp_cli,
12394*4882a593Smuzhiyun /*  0xfb */ x86emuOp_sti,
12395*4882a593Smuzhiyun /*  0xfc */ x86emuOp_cld,
12396*4882a593Smuzhiyun /*  0xfd */ x86emuOp_std,
12397*4882a593Smuzhiyun /*  0xfe */ x86emuOp_opcFE_byte_RM,
12398*4882a593Smuzhiyun /*  0xff */ x86emuOp_opcFF_word_RM,
12399*4882a593Smuzhiyun };
12400