1ece92f85SJason Jin /****************************************************************************
2ece92f85SJason Jin * Realmode X86 Emulator Library
3ece92f85SJason Jin *
44c2e3da8SKumar Gala * Copyright (C) 2007 Freescale Semiconductor, Inc.
5ece92f85SJason Jin * Jason Jin <Jason.jin@freescale.com>
6ece92f85SJason Jin *
7ece92f85SJason Jin * Copyright (C) 1991-2004 SciTech Software, Inc.
8ece92f85SJason Jin * Copyright (C) David Mosberger-Tang
9ece92f85SJason Jin * Copyright (C) 1999 Egbert Eich
10ece92f85SJason Jin *
11ece92f85SJason Jin * ========================================================================
12ece92f85SJason Jin *
13ece92f85SJason Jin * Permission to use, copy, modify, distribute, and sell this software and
14ece92f85SJason Jin * its documentation for any purpose is hereby granted without fee,
15ece92f85SJason Jin * provided that the above copyright notice appear in all copies and that
16ece92f85SJason Jin * both that copyright notice and this permission notice appear in
17ece92f85SJason Jin * supporting documentation, and that the name of the authors not be used
18ece92f85SJason Jin * in advertising or publicity pertaining to distribution of the software
19ece92f85SJason Jin * without specific, written prior permission. The authors makes no
20ece92f85SJason Jin * representations about the suitability of this software for any purpose.
21ece92f85SJason Jin * It is provided "as is" without express or implied warranty.
22ece92f85SJason Jin *
23ece92f85SJason Jin * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
24ece92f85SJason Jin * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
25ece92f85SJason Jin * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
26ece92f85SJason Jin * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
27ece92f85SJason Jin * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
28ece92f85SJason Jin * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29ece92f85SJason Jin * PERFORMANCE OF THIS SOFTWARE.
30ece92f85SJason Jin *
31ece92f85SJason Jin * ========================================================================
32ece92f85SJason Jin *
33ece92f85SJason Jin * Language: ANSI C
34ece92f85SJason Jin * Environment: Any
35ece92f85SJason Jin * Developer: Kendall Bennett
36ece92f85SJason Jin *
37ece92f85SJason Jin * Description: This file includes subroutines to implement the decoding
38ece92f85SJason Jin * and emulation of all the x86 processor instructions.
39ece92f85SJason Jin *
40ece92f85SJason Jin * There are approximately 250 subroutines in here, which correspond
41ece92f85SJason Jin * to the 256 byte-"opcodes" found on the 8086. The table which
42ece92f85SJason Jin * dispatches this is found in the files optab.[ch].
43ece92f85SJason Jin *
44*fc0b5948SRobert P. J. Day * Each opcode proc has a comment preceding it which gives it's table
45ece92f85SJason Jin * address. Several opcodes are missing (undefined) in the table.
46ece92f85SJason Jin *
47ece92f85SJason Jin * Each proc includes information for decoding (DECODE_PRINTF and
48ece92f85SJason Jin * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
49ece92f85SJason Jin * functions (START_OF_INSTR, END_OF_INSTR).
50ece92f85SJason Jin *
51ece92f85SJason Jin * Many of the procedures are *VERY* similar in coding. This has
52ece92f85SJason Jin * allowed for a very large amount of code to be generated in a fairly
53ece92f85SJason Jin * short amount of time (i.e. cut, paste, and modify). The result is
54ece92f85SJason Jin * that much of the code below could have been folded into subroutines
55ece92f85SJason Jin * for a large reduction in size of this file. The downside would be
56ece92f85SJason Jin * that there would be a penalty in execution speed. The file could
57ece92f85SJason Jin * also have been *MUCH* larger by inlining certain functions which
58ece92f85SJason Jin * were called. This could have resulted even faster execution. The
59ece92f85SJason Jin * prime directive I used to decide whether to inline the code or to
60ece92f85SJason Jin * modularize it, was basically: 1) no unnecessary subroutine calls,
61ece92f85SJason Jin * 2) no routines more than about 200 lines in size, and 3) modularize
62ece92f85SJason Jin * any code that I might not get right the first time. The fetch_*
63ece92f85SJason Jin * subroutines fall into the latter category. The The decode_* fall
64ece92f85SJason Jin * into the second category. The coding of the "switch(mod){ .... }"
65ece92f85SJason Jin * in many of the subroutines below falls into the first category.
66ece92f85SJason Jin * Especially, the coding of {add,and,or,sub,...}_{byte,word}
67ece92f85SJason Jin * subroutines are an especially glaring case of the third guideline.
68ece92f85SJason Jin * Since so much of the code is cloned from other modules (compare
69ece92f85SJason Jin * opcode #00 to opcode #01), making the basic operations subroutine
70ece92f85SJason Jin * calls is especially important; otherwise mistakes in coding an
71ece92f85SJason Jin * "add" would represent a nightmare in maintenance.
72ece92f85SJason Jin *
73ece92f85SJason Jin ****************************************************************************/
74ece92f85SJason Jin
7578cff50eSMichal Simek #include <common.h>
765b4de930SMichal Simek #include "x86emu/x86emui.h"
775b4de930SMichal Simek
78ece92f85SJason Jin /*----------------------------- Implementation ----------------------------*/
79ece92f85SJason Jin
80ece92f85SJason Jin /* constant arrays to do several instructions in just one function */
81ece92f85SJason Jin
82b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
83ece92f85SJason Jin static char *x86emu_GenOpName[8] = {
84ece92f85SJason Jin "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"};
85ece92f85SJason Jin #endif
86ece92f85SJason Jin
87ece92f85SJason Jin /* used by several opcodes */
88285870f7SEd Swarthout static u8 (*genop_byte_operation[])(u8 d, u8 s) =
89ece92f85SJason Jin {
90ece92f85SJason Jin add_byte, /* 00 */
91ece92f85SJason Jin or_byte, /* 01 */
92ece92f85SJason Jin adc_byte, /* 02 */
93ece92f85SJason Jin sbb_byte, /* 03 */
94ece92f85SJason Jin and_byte, /* 04 */
95ece92f85SJason Jin sub_byte, /* 05 */
96ece92f85SJason Jin xor_byte, /* 06 */
97ece92f85SJason Jin cmp_byte, /* 07 */
98ece92f85SJason Jin };
99ece92f85SJason Jin
100285870f7SEd Swarthout static u16 (*genop_word_operation[])(u16 d, u16 s) =
101ece92f85SJason Jin {
102ece92f85SJason Jin add_word, /*00 */
103ece92f85SJason Jin or_word, /*01 */
104ece92f85SJason Jin adc_word, /*02 */
105ece92f85SJason Jin sbb_word, /*03 */
106ece92f85SJason Jin and_word, /*04 */
107ece92f85SJason Jin sub_word, /*05 */
108ece92f85SJason Jin xor_word, /*06 */
109ece92f85SJason Jin cmp_word, /*07 */
110ece92f85SJason Jin };
111ece92f85SJason Jin
112285870f7SEd Swarthout static u32 (*genop_long_operation[])(u32 d, u32 s) =
113ece92f85SJason Jin {
114ece92f85SJason Jin add_long, /*00 */
115ece92f85SJason Jin or_long, /*01 */
116ece92f85SJason Jin adc_long, /*02 */
117ece92f85SJason Jin sbb_long, /*03 */
118ece92f85SJason Jin and_long, /*04 */
119ece92f85SJason Jin sub_long, /*05 */
120ece92f85SJason Jin xor_long, /*06 */
121ece92f85SJason Jin cmp_long, /*07 */
122ece92f85SJason Jin };
123ece92f85SJason Jin
124ece92f85SJason Jin /* used by opcodes 80, c0, d0, and d2. */
125285870f7SEd Swarthout static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
126ece92f85SJason Jin {
127ece92f85SJason Jin rol_byte,
128ece92f85SJason Jin ror_byte,
129ece92f85SJason Jin rcl_byte,
130ece92f85SJason Jin rcr_byte,
131ece92f85SJason Jin shl_byte,
132ece92f85SJason Jin shr_byte,
133ece92f85SJason Jin shl_byte, /* sal_byte === shl_byte by definition */
134ece92f85SJason Jin sar_byte,
135ece92f85SJason Jin };
136ece92f85SJason Jin
137ece92f85SJason Jin /* used by opcodes c1, d1, and d3. */
138285870f7SEd Swarthout static u16(*opcD1_word_operation[])(u16 s, u8 d) =
139ece92f85SJason Jin {
140ece92f85SJason Jin rol_word,
141ece92f85SJason Jin ror_word,
142ece92f85SJason Jin rcl_word,
143ece92f85SJason Jin rcr_word,
144ece92f85SJason Jin shl_word,
145ece92f85SJason Jin shr_word,
146ece92f85SJason Jin shl_word, /* sal_byte === shl_byte by definition */
147ece92f85SJason Jin sar_word,
148ece92f85SJason Jin };
149ece92f85SJason Jin
150ece92f85SJason Jin /* used by opcodes c1, d1, and d3. */
151285870f7SEd Swarthout static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
152ece92f85SJason Jin {
153ece92f85SJason Jin rol_long,
154ece92f85SJason Jin ror_long,
155ece92f85SJason Jin rcl_long,
156ece92f85SJason Jin rcr_long,
157ece92f85SJason Jin shl_long,
158ece92f85SJason Jin shr_long,
159ece92f85SJason Jin shl_long, /* sal_byte === shl_byte by definition */
160ece92f85SJason Jin sar_long,
161ece92f85SJason Jin };
162ece92f85SJason Jin
163b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
164ece92f85SJason Jin
165ece92f85SJason Jin static char *opF6_names[8] =
166ece92f85SJason Jin { "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" };
167ece92f85SJason Jin
168ece92f85SJason Jin #endif
169ece92f85SJason Jin
170ece92f85SJason Jin /****************************************************************************
171ece92f85SJason Jin PARAMETERS:
172ece92f85SJason Jin op1 - Instruction op code
173ece92f85SJason Jin
174ece92f85SJason Jin REMARKS:
175ece92f85SJason Jin Handles illegal opcodes.
176ece92f85SJason Jin ****************************************************************************/
x86emuOp_illegal_op(u8 op1)177ece92f85SJason Jin void x86emuOp_illegal_op(
178ece92f85SJason Jin u8 op1)
179ece92f85SJason Jin {
180ece92f85SJason Jin START_OF_INSTR();
181ece92f85SJason Jin if (M.x86.R_SP != 0) {
182e78dd869SSimon Glass DB(printf("ILLEGAL X86 OPCODE\n"));
183ece92f85SJason Jin TRACE_REGS();
184ece92f85SJason Jin DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
185ece92f85SJason Jin M.x86.R_CS, M.x86.R_IP-1,op1));
186ece92f85SJason Jin HALT_SYS();
187ece92f85SJason Jin }
188ece92f85SJason Jin else {
189ece92f85SJason Jin /* If we get here, it means the stack pointer is back to zero
190ece92f85SJason Jin * so we are just returning from an emulator service call
191ece92f85SJason Jin * so therte is no need to display an error message. We trap
192ece92f85SJason Jin * the emulator with an 0xF1 opcode to finish the service
193ece92f85SJason Jin * call.
194ece92f85SJason Jin */
195ece92f85SJason Jin X86EMU_halt_sys();
196ece92f85SJason Jin }
197ece92f85SJason Jin END_OF_INSTR();
198ece92f85SJason Jin }
199ece92f85SJason Jin
200ece92f85SJason Jin /****************************************************************************
201ece92f85SJason Jin REMARKS:
202ece92f85SJason Jin Handles opcodes 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
203ece92f85SJason Jin ****************************************************************************/
x86emuOp_genop_byte_RM_R(u8 op1)204ece92f85SJason Jin void x86emuOp_genop_byte_RM_R(u8 op1)
205ece92f85SJason Jin {
206ece92f85SJason Jin int mod, rl, rh;
207ece92f85SJason Jin uint destoffset;
208ece92f85SJason Jin u8 *destreg, *srcreg;
209ece92f85SJason Jin u8 destval;
210ece92f85SJason Jin
211ece92f85SJason Jin op1 = (op1 >> 3) & 0x7;
212ece92f85SJason Jin
213ece92f85SJason Jin START_OF_INSTR();
214ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]);
215ece92f85SJason Jin DECODE_PRINTF("\t");
216ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
217ece92f85SJason Jin if(mod<3)
218ece92f85SJason Jin { destoffset = decode_rmXX_address(mod,rl);
219ece92f85SJason Jin DECODE_PRINTF(",");
220ece92f85SJason Jin destval = fetch_data_byte(destoffset);
221ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh);
222ece92f85SJason Jin DECODE_PRINTF("\n");
223ece92f85SJason Jin TRACE_AND_STEP();
224ece92f85SJason Jin destval = genop_byte_operation[op1](destval, *srcreg);
225ece92f85SJason Jin store_data_byte(destoffset, destval);
226ece92f85SJason Jin }
227ece92f85SJason Jin else
228ece92f85SJason Jin { /* register to register */
229ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
230ece92f85SJason Jin DECODE_PRINTF(",");
231ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh);
232ece92f85SJason Jin DECODE_PRINTF("\n");
233ece92f85SJason Jin TRACE_AND_STEP();
234ece92f85SJason Jin *destreg = genop_byte_operation[op1](*destreg, *srcreg);
235ece92f85SJason Jin }
236ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
237ece92f85SJason Jin END_OF_INSTR();
238ece92f85SJason Jin }
239ece92f85SJason Jin
240ece92f85SJason Jin /****************************************************************************
241ece92f85SJason Jin REMARKS:
242ece92f85SJason Jin Handles opcodes 0x01, 0x09, 0x11, 0x19, 0x21, 0x29, 0x31, 0x39
243ece92f85SJason Jin ****************************************************************************/
x86emuOp_genop_word_RM_R(u8 op1)244ece92f85SJason Jin void x86emuOp_genop_word_RM_R(u8 op1)
245ece92f85SJason Jin {
246ece92f85SJason Jin int mod, rl, rh;
247ece92f85SJason Jin uint destoffset;
248ece92f85SJason Jin
249ece92f85SJason Jin op1 = (op1 >> 3) & 0x7;
250ece92f85SJason Jin
251ece92f85SJason Jin START_OF_INSTR();
252ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]);
253ece92f85SJason Jin DECODE_PRINTF("\t");
254ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
255ece92f85SJason Jin
256ece92f85SJason Jin if(mod<3) {
257ece92f85SJason Jin destoffset = decode_rmXX_address(mod,rl);
258ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
259ece92f85SJason Jin u32 destval;
260ece92f85SJason Jin u32 *srcreg;
261ece92f85SJason Jin
262ece92f85SJason Jin DECODE_PRINTF(",");
263ece92f85SJason Jin destval = fetch_data_long(destoffset);
264ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh);
265ece92f85SJason Jin DECODE_PRINTF("\n");
266ece92f85SJason Jin TRACE_AND_STEP();
267ece92f85SJason Jin destval = genop_long_operation[op1](destval, *srcreg);
268ece92f85SJason Jin store_data_long(destoffset, destval);
269ece92f85SJason Jin } else {
270ece92f85SJason Jin u16 destval;
271ece92f85SJason Jin u16 *srcreg;
272ece92f85SJason Jin
273ece92f85SJason Jin DECODE_PRINTF(",");
274ece92f85SJason Jin destval = fetch_data_word(destoffset);
275ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh);
276ece92f85SJason Jin DECODE_PRINTF("\n");
277ece92f85SJason Jin TRACE_AND_STEP();
278ece92f85SJason Jin destval = genop_word_operation[op1](destval, *srcreg);
279ece92f85SJason Jin store_data_word(destoffset, destval);
280ece92f85SJason Jin }
281ece92f85SJason Jin } else { /* register to register */
282ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
283ece92f85SJason Jin u32 *destreg,*srcreg;
284ece92f85SJason Jin
285ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
286ece92f85SJason Jin DECODE_PRINTF(",");
287ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh);
288ece92f85SJason Jin DECODE_PRINTF("\n");
289ece92f85SJason Jin TRACE_AND_STEP();
290ece92f85SJason Jin *destreg = genop_long_operation[op1](*destreg, *srcreg);
291ece92f85SJason Jin } else {
292ece92f85SJason Jin u16 *destreg,*srcreg;
293ece92f85SJason Jin
294ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
295ece92f85SJason Jin DECODE_PRINTF(",");
296ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh);
297ece92f85SJason Jin DECODE_PRINTF("\n");
298ece92f85SJason Jin TRACE_AND_STEP();
299ece92f85SJason Jin *destreg = genop_word_operation[op1](*destreg, *srcreg);
300ece92f85SJason Jin }
301ece92f85SJason Jin }
302ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
303ece92f85SJason Jin END_OF_INSTR();
304ece92f85SJason Jin }
305ece92f85SJason Jin
306ece92f85SJason Jin /****************************************************************************
307ece92f85SJason Jin REMARKS:
308ece92f85SJason Jin Handles opcodes 0x02, 0x0a, 0x12, 0x1a, 0x22, 0x2a, 0x32, 0x3a
309ece92f85SJason Jin ****************************************************************************/
x86emuOp_genop_byte_R_RM(u8 op1)310ece92f85SJason Jin void x86emuOp_genop_byte_R_RM(u8 op1)
311ece92f85SJason Jin {
312ece92f85SJason Jin int mod, rl, rh;
313ece92f85SJason Jin u8 *destreg, *srcreg;
314ece92f85SJason Jin uint srcoffset;
315ece92f85SJason Jin u8 srcval;
316ece92f85SJason Jin
317ece92f85SJason Jin op1 = (op1 >> 3) & 0x7;
318ece92f85SJason Jin
319ece92f85SJason Jin START_OF_INSTR();
320ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]);
321ece92f85SJason Jin DECODE_PRINTF("\t");
322ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
323ece92f85SJason Jin if (mod < 3) {
324ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rh);
325ece92f85SJason Jin DECODE_PRINTF(",");
326ece92f85SJason Jin srcoffset = decode_rmXX_address(mod,rl);
327ece92f85SJason Jin srcval = fetch_data_byte(srcoffset);
328ece92f85SJason Jin } else { /* register to register */
329ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rh);
330ece92f85SJason Jin DECODE_PRINTF(",");
331ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl);
332ece92f85SJason Jin srcval = *srcreg;
333ece92f85SJason Jin }
334ece92f85SJason Jin DECODE_PRINTF("\n");
335ece92f85SJason Jin TRACE_AND_STEP();
336ece92f85SJason Jin *destreg = genop_byte_operation[op1](*destreg, srcval);
337ece92f85SJason Jin
338ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
339ece92f85SJason Jin END_OF_INSTR();
340ece92f85SJason Jin }
341ece92f85SJason Jin
342ece92f85SJason Jin /****************************************************************************
343ece92f85SJason Jin REMARKS:
344ece92f85SJason Jin Handles opcodes 0x03, 0x0b, 0x13, 0x1b, 0x23, 0x2b, 0x33, 0x3b
345ece92f85SJason Jin ****************************************************************************/
x86emuOp_genop_word_R_RM(u8 op1)346ece92f85SJason Jin void x86emuOp_genop_word_R_RM(u8 op1)
347ece92f85SJason Jin {
348ece92f85SJason Jin int mod, rl, rh;
349ece92f85SJason Jin uint srcoffset;
350ece92f85SJason Jin u32 *destreg32, srcval;
351ece92f85SJason Jin u16 *destreg;
352ece92f85SJason Jin
353ece92f85SJason Jin op1 = (op1 >> 3) & 0x7;
354ece92f85SJason Jin
355ece92f85SJason Jin START_OF_INSTR();
356ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]);
357ece92f85SJason Jin DECODE_PRINTF("\t");
358ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
359ece92f85SJason Jin if (mod < 3) {
360ece92f85SJason Jin srcoffset = decode_rmXX_address(mod,rl);
361ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
362ece92f85SJason Jin destreg32 = DECODE_RM_LONG_REGISTER(rh);
363ece92f85SJason Jin DECODE_PRINTF(",");
364ece92f85SJason Jin srcval = fetch_data_long(srcoffset);
365ece92f85SJason Jin DECODE_PRINTF("\n");
366ece92f85SJason Jin TRACE_AND_STEP();
367ece92f85SJason Jin *destreg32 = genop_long_operation[op1](*destreg32, srcval);
368ece92f85SJason Jin } else {
369ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
370ece92f85SJason Jin DECODE_PRINTF(",");
371ece92f85SJason Jin srcval = fetch_data_word(srcoffset);
372ece92f85SJason Jin DECODE_PRINTF("\n");
373ece92f85SJason Jin TRACE_AND_STEP();
374ece92f85SJason Jin *destreg = genop_word_operation[op1](*destreg, srcval);
375ece92f85SJason Jin }
376ece92f85SJason Jin } else { /* register to register */
377ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
378ece92f85SJason Jin u32 *srcreg;
379ece92f85SJason Jin destreg32 = DECODE_RM_LONG_REGISTER(rh);
380ece92f85SJason Jin DECODE_PRINTF(",");
381ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
382ece92f85SJason Jin DECODE_PRINTF("\n");
383ece92f85SJason Jin TRACE_AND_STEP();
384ece92f85SJason Jin *destreg32 = genop_long_operation[op1](*destreg32, *srcreg);
385ece92f85SJason Jin } else {
386ece92f85SJason Jin u16 *srcreg;
387ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
388ece92f85SJason Jin DECODE_PRINTF(",");
389ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
390ece92f85SJason Jin DECODE_PRINTF("\n");
391ece92f85SJason Jin TRACE_AND_STEP();
392ece92f85SJason Jin *destreg = genop_word_operation[op1](*destreg, *srcreg);
393ece92f85SJason Jin }
394ece92f85SJason Jin }
395ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
396ece92f85SJason Jin END_OF_INSTR();
397ece92f85SJason Jin }
398ece92f85SJason Jin
399ece92f85SJason Jin /****************************************************************************
400ece92f85SJason Jin REMARKS:
401ece92f85SJason Jin Handles opcodes 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c
402ece92f85SJason Jin ****************************************************************************/
x86emuOp_genop_byte_AL_IMM(u8 op1)403ece92f85SJason Jin void x86emuOp_genop_byte_AL_IMM(u8 op1)
404ece92f85SJason Jin {
405ece92f85SJason Jin u8 srcval;
406ece92f85SJason Jin
407ece92f85SJason Jin op1 = (op1 >> 3) & 0x7;
408ece92f85SJason Jin
409ece92f85SJason Jin START_OF_INSTR();
410ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]);
411ece92f85SJason Jin DECODE_PRINTF("\tAL,");
412ece92f85SJason Jin srcval = fetch_byte_imm();
413ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval);
414ece92f85SJason Jin TRACE_AND_STEP();
415ece92f85SJason Jin M.x86.R_AL = genop_byte_operation[op1](M.x86.R_AL, srcval);
416ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
417ece92f85SJason Jin END_OF_INSTR();
418ece92f85SJason Jin }
419ece92f85SJason Jin
420ece92f85SJason Jin /****************************************************************************
421ece92f85SJason Jin REMARKS:
422ece92f85SJason Jin Handles opcodes 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d
423ece92f85SJason Jin ****************************************************************************/
x86emuOp_genop_word_AX_IMM(u8 op1)424ece92f85SJason Jin void x86emuOp_genop_word_AX_IMM(u8 op1)
425ece92f85SJason Jin {
426ece92f85SJason Jin u32 srcval;
427ece92f85SJason Jin
428ece92f85SJason Jin op1 = (op1 >> 3) & 0x7;
429ece92f85SJason Jin
430ece92f85SJason Jin START_OF_INSTR();
431ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
432ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]);
433ece92f85SJason Jin DECODE_PRINTF("\tEAX,");
434ece92f85SJason Jin srcval = fetch_long_imm();
435ece92f85SJason Jin } else {
436ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]);
437ece92f85SJason Jin DECODE_PRINTF("\tAX,");
438ece92f85SJason Jin srcval = fetch_word_imm();
439ece92f85SJason Jin }
440ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval);
441ece92f85SJason Jin TRACE_AND_STEP();
442ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
443ece92f85SJason Jin M.x86.R_EAX = genop_long_operation[op1](M.x86.R_EAX, srcval);
444ece92f85SJason Jin } else {
445ece92f85SJason Jin M.x86.R_AX = genop_word_operation[op1](M.x86.R_AX, (u16)srcval);
446ece92f85SJason Jin }
447ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
448ece92f85SJason Jin END_OF_INSTR();
449ece92f85SJason Jin }
450ece92f85SJason Jin
451ece92f85SJason Jin /****************************************************************************
452ece92f85SJason Jin REMARKS:
453ece92f85SJason Jin Handles opcode 0x06
454ece92f85SJason Jin ****************************************************************************/
x86emuOp_push_ES(u8 X86EMU_UNUSED (op1))455ece92f85SJason Jin void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
456ece92f85SJason Jin {
457ece92f85SJason Jin START_OF_INSTR();
458ece92f85SJason Jin DECODE_PRINTF("PUSH\tES\n");
459ece92f85SJason Jin TRACE_AND_STEP();
460ece92f85SJason Jin push_word(M.x86.R_ES);
461ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
462ece92f85SJason Jin END_OF_INSTR();
463ece92f85SJason Jin }
464ece92f85SJason Jin
465ece92f85SJason Jin /****************************************************************************
466ece92f85SJason Jin REMARKS:
467ece92f85SJason Jin Handles opcode 0x07
468ece92f85SJason Jin ****************************************************************************/
x86emuOp_pop_ES(u8 X86EMU_UNUSED (op1))469ece92f85SJason Jin void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
470ece92f85SJason Jin {
471ece92f85SJason Jin START_OF_INSTR();
472ece92f85SJason Jin DECODE_PRINTF("POP\tES\n");
473ece92f85SJason Jin TRACE_AND_STEP();
474ece92f85SJason Jin M.x86.R_ES = pop_word();
475ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
476ece92f85SJason Jin END_OF_INSTR();
477ece92f85SJason Jin }
478ece92f85SJason Jin
479ece92f85SJason Jin /****************************************************************************
480ece92f85SJason Jin REMARKS:
481ece92f85SJason Jin Handles opcode 0x0e
482ece92f85SJason Jin ****************************************************************************/
x86emuOp_push_CS(u8 X86EMU_UNUSED (op1))483ece92f85SJason Jin void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
484ece92f85SJason Jin {
485ece92f85SJason Jin START_OF_INSTR();
486ece92f85SJason Jin DECODE_PRINTF("PUSH\tCS\n");
487ece92f85SJason Jin TRACE_AND_STEP();
488ece92f85SJason Jin push_word(M.x86.R_CS);
489ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
490ece92f85SJason Jin END_OF_INSTR();
491ece92f85SJason Jin }
492ece92f85SJason Jin
493ece92f85SJason Jin /****************************************************************************
494ece92f85SJason Jin REMARKS:
495ece92f85SJason Jin Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
496ece92f85SJason Jin ****************************************************************************/
x86emuOp_two_byte(u8 X86EMU_UNUSED (op1))497ece92f85SJason Jin void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
498ece92f85SJason Jin {
499ece92f85SJason Jin u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
500ece92f85SJason Jin INC_DECODED_INST_LEN(1);
501ece92f85SJason Jin (*x86emu_optab2[op2])(op2);
502ece92f85SJason Jin }
503ece92f85SJason Jin
504ece92f85SJason Jin /****************************************************************************
505ece92f85SJason Jin REMARKS:
506ece92f85SJason Jin Handles opcode 0x16
507ece92f85SJason Jin ****************************************************************************/
x86emuOp_push_SS(u8 X86EMU_UNUSED (op1))508ece92f85SJason Jin void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
509ece92f85SJason Jin {
510ece92f85SJason Jin START_OF_INSTR();
511ece92f85SJason Jin DECODE_PRINTF("PUSH\tSS\n");
512ece92f85SJason Jin TRACE_AND_STEP();
513ece92f85SJason Jin push_word(M.x86.R_SS);
514ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
515ece92f85SJason Jin END_OF_INSTR();
516ece92f85SJason Jin }
517ece92f85SJason Jin
518ece92f85SJason Jin /****************************************************************************
519ece92f85SJason Jin REMARKS:
520ece92f85SJason Jin Handles opcode 0x17
521ece92f85SJason Jin ****************************************************************************/
x86emuOp_pop_SS(u8 X86EMU_UNUSED (op1))522ece92f85SJason Jin void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
523ece92f85SJason Jin {
524ece92f85SJason Jin START_OF_INSTR();
525ece92f85SJason Jin DECODE_PRINTF("POP\tSS\n");
526ece92f85SJason Jin TRACE_AND_STEP();
527ece92f85SJason Jin M.x86.R_SS = pop_word();
528ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
529ece92f85SJason Jin END_OF_INSTR();
530ece92f85SJason Jin }
531ece92f85SJason Jin
532ece92f85SJason Jin /****************************************************************************
533ece92f85SJason Jin REMARKS:
534ece92f85SJason Jin Handles opcode 0x1e
535ece92f85SJason Jin ****************************************************************************/
x86emuOp_push_DS(u8 X86EMU_UNUSED (op1))536ece92f85SJason Jin void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
537ece92f85SJason Jin {
538ece92f85SJason Jin START_OF_INSTR();
539ece92f85SJason Jin DECODE_PRINTF("PUSH\tDS\n");
540ece92f85SJason Jin TRACE_AND_STEP();
541ece92f85SJason Jin push_word(M.x86.R_DS);
542ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
543ece92f85SJason Jin END_OF_INSTR();
544ece92f85SJason Jin }
545ece92f85SJason Jin
546ece92f85SJason Jin /****************************************************************************
547ece92f85SJason Jin REMARKS:
548ece92f85SJason Jin Handles opcode 0x1f
549ece92f85SJason Jin ****************************************************************************/
x86emuOp_pop_DS(u8 X86EMU_UNUSED (op1))550ece92f85SJason Jin void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
551ece92f85SJason Jin {
552ece92f85SJason Jin START_OF_INSTR();
553ece92f85SJason Jin DECODE_PRINTF("POP\tDS\n");
554ece92f85SJason Jin TRACE_AND_STEP();
555ece92f85SJason Jin M.x86.R_DS = pop_word();
556ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
557ece92f85SJason Jin END_OF_INSTR();
558ece92f85SJason Jin }
559ece92f85SJason Jin
560ece92f85SJason Jin /****************************************************************************
561ece92f85SJason Jin REMARKS:
562ece92f85SJason Jin Handles opcode 0x26
563ece92f85SJason Jin ****************************************************************************/
x86emuOp_segovr_ES(u8 X86EMU_UNUSED (op1))564ece92f85SJason Jin void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
565ece92f85SJason Jin {
566ece92f85SJason Jin START_OF_INSTR();
567ece92f85SJason Jin DECODE_PRINTF("ES:\n");
568ece92f85SJason Jin TRACE_AND_STEP();
569ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_ES;
570ece92f85SJason Jin /*
571ece92f85SJason Jin * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
572ece92f85SJason Jin * opcode subroutines we do not want to do this.
573ece92f85SJason Jin */
574ece92f85SJason Jin END_OF_INSTR();
575ece92f85SJason Jin }
576ece92f85SJason Jin
577ece92f85SJason Jin /****************************************************************************
578ece92f85SJason Jin REMARKS:
579ece92f85SJason Jin Handles opcode 0x27
580ece92f85SJason Jin ****************************************************************************/
x86emuOp_daa(u8 X86EMU_UNUSED (op1))581ece92f85SJason Jin void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
582ece92f85SJason Jin {
583ece92f85SJason Jin START_OF_INSTR();
584ece92f85SJason Jin DECODE_PRINTF("DAA\n");
585ece92f85SJason Jin TRACE_AND_STEP();
586ece92f85SJason Jin M.x86.R_AL = daa_byte(M.x86.R_AL);
587ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
588ece92f85SJason Jin END_OF_INSTR();
589ece92f85SJason Jin }
590ece92f85SJason Jin
591ece92f85SJason Jin /****************************************************************************
592ece92f85SJason Jin REMARKS:
593ece92f85SJason Jin Handles opcode 0x2e
594ece92f85SJason Jin ****************************************************************************/
x86emuOp_segovr_CS(u8 X86EMU_UNUSED (op1))595ece92f85SJason Jin void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
596ece92f85SJason Jin {
597ece92f85SJason Jin START_OF_INSTR();
598ece92f85SJason Jin DECODE_PRINTF("CS:\n");
599ece92f85SJason Jin TRACE_AND_STEP();
600ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_CS;
601ece92f85SJason Jin /* note no DECODE_CLEAR_SEGOVR here. */
602ece92f85SJason Jin END_OF_INSTR();
603ece92f85SJason Jin }
604ece92f85SJason Jin
605ece92f85SJason Jin /****************************************************************************
606ece92f85SJason Jin REMARKS:
607ece92f85SJason Jin Handles opcode 0x2f
608ece92f85SJason Jin ****************************************************************************/
x86emuOp_das(u8 X86EMU_UNUSED (op1))609ece92f85SJason Jin void x86emuOp_das(u8 X86EMU_UNUSED(op1))
610ece92f85SJason Jin {
611ece92f85SJason Jin START_OF_INSTR();
612ece92f85SJason Jin DECODE_PRINTF("DAS\n");
613ece92f85SJason Jin TRACE_AND_STEP();
614ece92f85SJason Jin M.x86.R_AL = das_byte(M.x86.R_AL);
615ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
616ece92f85SJason Jin END_OF_INSTR();
617ece92f85SJason Jin }
618ece92f85SJason Jin
619ece92f85SJason Jin /****************************************************************************
620ece92f85SJason Jin REMARKS:
621ece92f85SJason Jin Handles opcode 0x36
622ece92f85SJason Jin ****************************************************************************/
x86emuOp_segovr_SS(u8 X86EMU_UNUSED (op1))623ece92f85SJason Jin void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
624ece92f85SJason Jin {
625ece92f85SJason Jin START_OF_INSTR();
626ece92f85SJason Jin DECODE_PRINTF("SS:\n");
627ece92f85SJason Jin TRACE_AND_STEP();
628ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_SS;
629ece92f85SJason Jin /* no DECODE_CLEAR_SEGOVR ! */
630ece92f85SJason Jin END_OF_INSTR();
631ece92f85SJason Jin }
632ece92f85SJason Jin
633ece92f85SJason Jin /****************************************************************************
634ece92f85SJason Jin REMARKS:
635ece92f85SJason Jin Handles opcode 0x37
636ece92f85SJason Jin ****************************************************************************/
x86emuOp_aaa(u8 X86EMU_UNUSED (op1))637ece92f85SJason Jin void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
638ece92f85SJason Jin {
639ece92f85SJason Jin START_OF_INSTR();
640ece92f85SJason Jin DECODE_PRINTF("AAA\n");
641ece92f85SJason Jin TRACE_AND_STEP();
642ece92f85SJason Jin M.x86.R_AX = aaa_word(M.x86.R_AX);
643ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
644ece92f85SJason Jin END_OF_INSTR();
645ece92f85SJason Jin }
646ece92f85SJason Jin
647ece92f85SJason Jin /****************************************************************************
648ece92f85SJason Jin REMARKS:
649ece92f85SJason Jin Handles opcode 0x3e
650ece92f85SJason Jin ****************************************************************************/
x86emuOp_segovr_DS(u8 X86EMU_UNUSED (op1))651ece92f85SJason Jin void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
652ece92f85SJason Jin {
653ece92f85SJason Jin START_OF_INSTR();
654ece92f85SJason Jin DECODE_PRINTF("DS:\n");
655ece92f85SJason Jin TRACE_AND_STEP();
656ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_DS;
657ece92f85SJason Jin /* NO DECODE_CLEAR_SEGOVR! */
658ece92f85SJason Jin END_OF_INSTR();
659ece92f85SJason Jin }
660ece92f85SJason Jin
661ece92f85SJason Jin /****************************************************************************
662ece92f85SJason Jin REMARKS:
663ece92f85SJason Jin Handles opcode 0x3f
664ece92f85SJason Jin ****************************************************************************/
x86emuOp_aas(u8 X86EMU_UNUSED (op1))665ece92f85SJason Jin void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
666ece92f85SJason Jin {
667ece92f85SJason Jin START_OF_INSTR();
668ece92f85SJason Jin DECODE_PRINTF("AAS\n");
669ece92f85SJason Jin TRACE_AND_STEP();
670ece92f85SJason Jin M.x86.R_AX = aas_word(M.x86.R_AX);
671ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
672ece92f85SJason Jin END_OF_INSTR();
673ece92f85SJason Jin }
674ece92f85SJason Jin
675ece92f85SJason Jin /****************************************************************************
676ece92f85SJason Jin REMARKS:
677ece92f85SJason Jin Handles opcode 0x40 - 0x47
678ece92f85SJason Jin ****************************************************************************/
x86emuOp_inc_register(u8 op1)679ece92f85SJason Jin void x86emuOp_inc_register(u8 op1)
680ece92f85SJason Jin {
681ece92f85SJason Jin START_OF_INSTR();
682ece92f85SJason Jin op1 &= 0x7;
683ece92f85SJason Jin DECODE_PRINTF("INC\t");
684ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
685ece92f85SJason Jin u32 *reg;
686ece92f85SJason Jin reg = DECODE_RM_LONG_REGISTER(op1);
687ece92f85SJason Jin DECODE_PRINTF("\n");
688ece92f85SJason Jin TRACE_AND_STEP();
689ece92f85SJason Jin *reg = inc_long(*reg);
690ece92f85SJason Jin } else {
691ece92f85SJason Jin u16 *reg;
692ece92f85SJason Jin reg = DECODE_RM_WORD_REGISTER(op1);
693ece92f85SJason Jin DECODE_PRINTF("\n");
694ece92f85SJason Jin TRACE_AND_STEP();
695ece92f85SJason Jin *reg = inc_word(*reg);
696ece92f85SJason Jin }
697ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
698ece92f85SJason Jin END_OF_INSTR();
699ece92f85SJason Jin }
700ece92f85SJason Jin
701ece92f85SJason Jin /****************************************************************************
702ece92f85SJason Jin REMARKS:
703ece92f85SJason Jin Handles opcode 0x48 - 0x4F
704ece92f85SJason Jin ****************************************************************************/
x86emuOp_dec_register(u8 op1)705ece92f85SJason Jin void x86emuOp_dec_register(u8 op1)
706ece92f85SJason Jin {
707ece92f85SJason Jin START_OF_INSTR();
708ece92f85SJason Jin op1 &= 0x7;
709ece92f85SJason Jin DECODE_PRINTF("DEC\t");
710ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
711ece92f85SJason Jin u32 *reg;
712ece92f85SJason Jin reg = DECODE_RM_LONG_REGISTER(op1);
713ece92f85SJason Jin DECODE_PRINTF("\n");
714ece92f85SJason Jin TRACE_AND_STEP();
715ece92f85SJason Jin *reg = dec_long(*reg);
716ece92f85SJason Jin } else {
717ece92f85SJason Jin u16 *reg;
718ece92f85SJason Jin reg = DECODE_RM_WORD_REGISTER(op1);
719ece92f85SJason Jin DECODE_PRINTF("\n");
720ece92f85SJason Jin TRACE_AND_STEP();
721ece92f85SJason Jin *reg = dec_word(*reg);
722ece92f85SJason Jin }
723ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
724ece92f85SJason Jin END_OF_INSTR();
725ece92f85SJason Jin }
726ece92f85SJason Jin
727ece92f85SJason Jin /****************************************************************************
728ece92f85SJason Jin REMARKS:
729ece92f85SJason Jin Handles opcode 0x50 - 0x57
730ece92f85SJason Jin ****************************************************************************/
x86emuOp_push_register(u8 op1)731ece92f85SJason Jin void x86emuOp_push_register(u8 op1)
732ece92f85SJason Jin {
733ece92f85SJason Jin START_OF_INSTR();
734ece92f85SJason Jin op1 &= 0x7;
735ece92f85SJason Jin DECODE_PRINTF("PUSH\t");
736ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
737ece92f85SJason Jin u32 *reg;
738ece92f85SJason Jin reg = DECODE_RM_LONG_REGISTER(op1);
739ece92f85SJason Jin DECODE_PRINTF("\n");
740ece92f85SJason Jin TRACE_AND_STEP();
741ece92f85SJason Jin push_long(*reg);
742ece92f85SJason Jin } else {
743ece92f85SJason Jin u16 *reg;
744ece92f85SJason Jin reg = DECODE_RM_WORD_REGISTER(op1);
745ece92f85SJason Jin DECODE_PRINTF("\n");
746ece92f85SJason Jin TRACE_AND_STEP();
747ece92f85SJason Jin push_word(*reg);
748ece92f85SJason Jin }
749ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
750ece92f85SJason Jin END_OF_INSTR();
751ece92f85SJason Jin }
752ece92f85SJason Jin
753ece92f85SJason Jin /****************************************************************************
754ece92f85SJason Jin REMARKS:
755ece92f85SJason Jin Handles opcode 0x58 - 0x5F
756ece92f85SJason Jin ****************************************************************************/
x86emuOp_pop_register(u8 op1)757ece92f85SJason Jin void x86emuOp_pop_register(u8 op1)
758ece92f85SJason Jin {
759ece92f85SJason Jin START_OF_INSTR();
760ece92f85SJason Jin op1 &= 0x7;
761ece92f85SJason Jin DECODE_PRINTF("POP\t");
762ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
763ece92f85SJason Jin u32 *reg;
764ece92f85SJason Jin reg = DECODE_RM_LONG_REGISTER(op1);
765ece92f85SJason Jin DECODE_PRINTF("\n");
766ece92f85SJason Jin TRACE_AND_STEP();
767ece92f85SJason Jin *reg = pop_long();
768ece92f85SJason Jin } else {
769ece92f85SJason Jin u16 *reg;
770ece92f85SJason Jin reg = DECODE_RM_WORD_REGISTER(op1);
771ece92f85SJason Jin DECODE_PRINTF("\n");
772ece92f85SJason Jin TRACE_AND_STEP();
773ece92f85SJason Jin *reg = pop_word();
774ece92f85SJason Jin }
775ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
776ece92f85SJason Jin END_OF_INSTR();
777ece92f85SJason Jin }
778ece92f85SJason Jin
779ece92f85SJason Jin /****************************************************************************
780ece92f85SJason Jin REMARKS:
781ece92f85SJason Jin Handles opcode 0x60
782ece92f85SJason Jin ****************************************************************************/
x86emuOp_push_all(u8 X86EMU_UNUSED (op1))783ece92f85SJason Jin void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
784ece92f85SJason Jin {
785ece92f85SJason Jin START_OF_INSTR();
786ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
787ece92f85SJason Jin DECODE_PRINTF("PUSHAD\n");
788ece92f85SJason Jin } else {
789ece92f85SJason Jin DECODE_PRINTF("PUSHA\n");
790ece92f85SJason Jin }
791ece92f85SJason Jin TRACE_AND_STEP();
792ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
793ece92f85SJason Jin u32 old_sp = M.x86.R_ESP;
794ece92f85SJason Jin
795ece92f85SJason Jin push_long(M.x86.R_EAX);
796ece92f85SJason Jin push_long(M.x86.R_ECX);
797ece92f85SJason Jin push_long(M.x86.R_EDX);
798ece92f85SJason Jin push_long(M.x86.R_EBX);
799ece92f85SJason Jin push_long(old_sp);
800ece92f85SJason Jin push_long(M.x86.R_EBP);
801ece92f85SJason Jin push_long(M.x86.R_ESI);
802ece92f85SJason Jin push_long(M.x86.R_EDI);
803ece92f85SJason Jin } else {
804ece92f85SJason Jin u16 old_sp = M.x86.R_SP;
805ece92f85SJason Jin
806ece92f85SJason Jin push_word(M.x86.R_AX);
807ece92f85SJason Jin push_word(M.x86.R_CX);
808ece92f85SJason Jin push_word(M.x86.R_DX);
809ece92f85SJason Jin push_word(M.x86.R_BX);
810ece92f85SJason Jin push_word(old_sp);
811ece92f85SJason Jin push_word(M.x86.R_BP);
812ece92f85SJason Jin push_word(M.x86.R_SI);
813ece92f85SJason Jin push_word(M.x86.R_DI);
814ece92f85SJason Jin }
815ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
816ece92f85SJason Jin END_OF_INSTR();
817ece92f85SJason Jin }
818ece92f85SJason Jin
819ece92f85SJason Jin /****************************************************************************
820ece92f85SJason Jin REMARKS:
821ece92f85SJason Jin Handles opcode 0x61
822ece92f85SJason Jin ****************************************************************************/
x86emuOp_pop_all(u8 X86EMU_UNUSED (op1))823ece92f85SJason Jin void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
824ece92f85SJason Jin {
825ece92f85SJason Jin START_OF_INSTR();
826ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
827ece92f85SJason Jin DECODE_PRINTF("POPAD\n");
828ece92f85SJason Jin } else {
829ece92f85SJason Jin DECODE_PRINTF("POPA\n");
830ece92f85SJason Jin }
831ece92f85SJason Jin TRACE_AND_STEP();
832ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
833ece92f85SJason Jin M.x86.R_EDI = pop_long();
834ece92f85SJason Jin M.x86.R_ESI = pop_long();
835ece92f85SJason Jin M.x86.R_EBP = pop_long();
836ece92f85SJason Jin M.x86.R_ESP += 4; /* skip ESP */
837ece92f85SJason Jin M.x86.R_EBX = pop_long();
838ece92f85SJason Jin M.x86.R_EDX = pop_long();
839ece92f85SJason Jin M.x86.R_ECX = pop_long();
840ece92f85SJason Jin M.x86.R_EAX = pop_long();
841ece92f85SJason Jin } else {
842ece92f85SJason Jin M.x86.R_DI = pop_word();
843ece92f85SJason Jin M.x86.R_SI = pop_word();
844ece92f85SJason Jin M.x86.R_BP = pop_word();
845ece92f85SJason Jin M.x86.R_SP += 2; /* skip SP */
846ece92f85SJason Jin M.x86.R_BX = pop_word();
847ece92f85SJason Jin M.x86.R_DX = pop_word();
848ece92f85SJason Jin M.x86.R_CX = pop_word();
849ece92f85SJason Jin M.x86.R_AX = pop_word();
850ece92f85SJason Jin }
851ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
852ece92f85SJason Jin END_OF_INSTR();
853ece92f85SJason Jin }
854ece92f85SJason Jin
855ece92f85SJason Jin /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
856ece92f85SJason Jin /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
857ece92f85SJason Jin
858ece92f85SJason Jin /****************************************************************************
859ece92f85SJason Jin REMARKS:
860ece92f85SJason Jin Handles opcode 0x64
861ece92f85SJason Jin ****************************************************************************/
x86emuOp_segovr_FS(u8 X86EMU_UNUSED (op1))862ece92f85SJason Jin void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
863ece92f85SJason Jin {
864ece92f85SJason Jin START_OF_INSTR();
865ece92f85SJason Jin DECODE_PRINTF("FS:\n");
866ece92f85SJason Jin TRACE_AND_STEP();
867ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_FS;
868ece92f85SJason Jin /*
869ece92f85SJason Jin * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
870ece92f85SJason Jin * opcode subroutines we do not want to do this.
871ece92f85SJason Jin */
872ece92f85SJason Jin END_OF_INSTR();
873ece92f85SJason Jin }
874ece92f85SJason Jin
875ece92f85SJason Jin /****************************************************************************
876ece92f85SJason Jin REMARKS:
877ece92f85SJason Jin Handles opcode 0x65
878ece92f85SJason Jin ****************************************************************************/
x86emuOp_segovr_GS(u8 X86EMU_UNUSED (op1))879ece92f85SJason Jin void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
880ece92f85SJason Jin {
881ece92f85SJason Jin START_OF_INSTR();
882ece92f85SJason Jin DECODE_PRINTF("GS:\n");
883ece92f85SJason Jin TRACE_AND_STEP();
884ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_GS;
885ece92f85SJason Jin /*
886ece92f85SJason Jin * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
887ece92f85SJason Jin * opcode subroutines we do not want to do this.
888ece92f85SJason Jin */
889ece92f85SJason Jin END_OF_INSTR();
890ece92f85SJason Jin }
891ece92f85SJason Jin
892ece92f85SJason Jin /****************************************************************************
893ece92f85SJason Jin REMARKS:
894ece92f85SJason Jin Handles opcode 0x66 - prefix for 32-bit register
895ece92f85SJason Jin ****************************************************************************/
x86emuOp_prefix_data(u8 X86EMU_UNUSED (op1))896ece92f85SJason Jin void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
897ece92f85SJason Jin {
898ece92f85SJason Jin START_OF_INSTR();
899ece92f85SJason Jin DECODE_PRINTF("DATA:\n");
900ece92f85SJason Jin TRACE_AND_STEP();
901ece92f85SJason Jin M.x86.mode |= SYSMODE_PREFIX_DATA;
902ece92f85SJason Jin /* note no DECODE_CLEAR_SEGOVR here. */
903ece92f85SJason Jin END_OF_INSTR();
904ece92f85SJason Jin }
905ece92f85SJason Jin
906ece92f85SJason Jin /****************************************************************************
907ece92f85SJason Jin REMARKS:
908ece92f85SJason Jin Handles opcode 0x67 - prefix for 32-bit address
909ece92f85SJason Jin ****************************************************************************/
x86emuOp_prefix_addr(u8 X86EMU_UNUSED (op1))910ece92f85SJason Jin void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
911ece92f85SJason Jin {
912ece92f85SJason Jin START_OF_INSTR();
913ece92f85SJason Jin DECODE_PRINTF("ADDR:\n");
914ece92f85SJason Jin TRACE_AND_STEP();
915ece92f85SJason Jin M.x86.mode |= SYSMODE_PREFIX_ADDR;
916ece92f85SJason Jin /* note no DECODE_CLEAR_SEGOVR here. */
917ece92f85SJason Jin END_OF_INSTR();
918ece92f85SJason Jin }
919ece92f85SJason Jin
920ece92f85SJason Jin /****************************************************************************
921ece92f85SJason Jin REMARKS:
922ece92f85SJason Jin Handles opcode 0x68
923ece92f85SJason Jin ****************************************************************************/
x86emuOp_push_word_IMM(u8 X86EMU_UNUSED (op1))924ece92f85SJason Jin void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
925ece92f85SJason Jin {
926ece92f85SJason Jin u32 imm;
927ece92f85SJason Jin
928ece92f85SJason Jin START_OF_INSTR();
929ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
930ece92f85SJason Jin imm = fetch_long_imm();
931ece92f85SJason Jin } else {
932ece92f85SJason Jin imm = fetch_word_imm();
933ece92f85SJason Jin }
934ece92f85SJason Jin DECODE_PRINTF2("PUSH\t%x\n", imm);
935ece92f85SJason Jin TRACE_AND_STEP();
936ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
937ece92f85SJason Jin push_long(imm);
938ece92f85SJason Jin } else {
939ece92f85SJason Jin push_word((u16)imm);
940ece92f85SJason Jin }
941ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
942ece92f85SJason Jin END_OF_INSTR();
943ece92f85SJason Jin }
944ece92f85SJason Jin
945ece92f85SJason Jin /****************************************************************************
946ece92f85SJason Jin REMARKS:
947ece92f85SJason Jin Handles opcode 0x69
948ece92f85SJason Jin ****************************************************************************/
x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED (op1))949ece92f85SJason Jin void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
950ece92f85SJason Jin {
951ece92f85SJason Jin int mod, rl, rh;
952ece92f85SJason Jin uint srcoffset;
953ece92f85SJason Jin
954ece92f85SJason Jin START_OF_INSTR();
955ece92f85SJason Jin DECODE_PRINTF("IMUL\t");
956ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
957ece92f85SJason Jin if (mod < 3) {
958ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
959ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
960ece92f85SJason Jin u32 *destreg;
961ece92f85SJason Jin u32 srcval;
962ece92f85SJason Jin u32 res_lo,res_hi;
963ece92f85SJason Jin s32 imm;
964ece92f85SJason Jin
965ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
966ece92f85SJason Jin DECODE_PRINTF(",");
967ece92f85SJason Jin srcval = fetch_data_long(srcoffset);
968ece92f85SJason Jin imm = fetch_long_imm();
969ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm);
970ece92f85SJason Jin TRACE_AND_STEP();
971ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
972ece92f85SJason Jin if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
973ece92f85SJason Jin (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
974ece92f85SJason Jin CLEAR_FLAG(F_CF);
975ece92f85SJason Jin CLEAR_FLAG(F_OF);
976ece92f85SJason Jin } else {
977ece92f85SJason Jin SET_FLAG(F_CF);
978ece92f85SJason Jin SET_FLAG(F_OF);
979ece92f85SJason Jin }
980ece92f85SJason Jin *destreg = (u32)res_lo;
981ece92f85SJason Jin } else {
982ece92f85SJason Jin u16 *destreg;
983ece92f85SJason Jin u16 srcval;
984ece92f85SJason Jin u32 res;
985ece92f85SJason Jin s16 imm;
986ece92f85SJason Jin
987ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
988ece92f85SJason Jin DECODE_PRINTF(",");
989ece92f85SJason Jin srcval = fetch_data_word(srcoffset);
990ece92f85SJason Jin imm = fetch_word_imm();
991ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm);
992ece92f85SJason Jin TRACE_AND_STEP();
993ece92f85SJason Jin res = (s16)srcval * (s16)imm;
994ece92f85SJason Jin if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
995ece92f85SJason Jin (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
996ece92f85SJason Jin CLEAR_FLAG(F_CF);
997ece92f85SJason Jin CLEAR_FLAG(F_OF);
998ece92f85SJason Jin } else {
999ece92f85SJason Jin SET_FLAG(F_CF);
1000ece92f85SJason Jin SET_FLAG(F_OF);
1001ece92f85SJason Jin }
1002ece92f85SJason Jin *destreg = (u16)res;
1003ece92f85SJason Jin }
1004ece92f85SJason Jin } else { /* register to register */
1005ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1006ece92f85SJason Jin u32 *destreg,*srcreg;
1007ece92f85SJason Jin u32 res_lo,res_hi;
1008ece92f85SJason Jin s32 imm;
1009ece92f85SJason Jin
1010ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1011ece92f85SJason Jin DECODE_PRINTF(",");
1012ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
1013ece92f85SJason Jin imm = fetch_long_imm();
1014ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm);
1015ece92f85SJason Jin TRACE_AND_STEP();
1016ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
1017ece92f85SJason Jin if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
1018ece92f85SJason Jin (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
1019ece92f85SJason Jin CLEAR_FLAG(F_CF);
1020ece92f85SJason Jin CLEAR_FLAG(F_OF);
1021ece92f85SJason Jin } else {
1022ece92f85SJason Jin SET_FLAG(F_CF);
1023ece92f85SJason Jin SET_FLAG(F_OF);
1024ece92f85SJason Jin }
1025ece92f85SJason Jin *destreg = (u32)res_lo;
1026ece92f85SJason Jin } else {
1027ece92f85SJason Jin u16 *destreg,*srcreg;
1028ece92f85SJason Jin u32 res;
1029ece92f85SJason Jin s16 imm;
1030ece92f85SJason Jin
1031ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
1032ece92f85SJason Jin DECODE_PRINTF(",");
1033ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
1034ece92f85SJason Jin imm = fetch_word_imm();
1035ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm);
1036ece92f85SJason Jin res = (s16)*srcreg * (s16)imm;
1037ece92f85SJason Jin if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
1038ece92f85SJason Jin (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
1039ece92f85SJason Jin CLEAR_FLAG(F_CF);
1040ece92f85SJason Jin CLEAR_FLAG(F_OF);
1041ece92f85SJason Jin } else {
1042ece92f85SJason Jin SET_FLAG(F_CF);
1043ece92f85SJason Jin SET_FLAG(F_OF);
1044ece92f85SJason Jin }
1045ece92f85SJason Jin *destreg = (u16)res;
1046ece92f85SJason Jin }
1047ece92f85SJason Jin }
1048ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1049ece92f85SJason Jin END_OF_INSTR();
1050ece92f85SJason Jin }
1051ece92f85SJason Jin
1052ece92f85SJason Jin /****************************************************************************
1053ece92f85SJason Jin REMARKS:
1054ece92f85SJason Jin Handles opcode 0x6a
1055ece92f85SJason Jin ****************************************************************************/
x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED (op1))1056ece92f85SJason Jin void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
1057ece92f85SJason Jin {
1058ece92f85SJason Jin s16 imm;
1059ece92f85SJason Jin
1060ece92f85SJason Jin START_OF_INSTR();
1061ece92f85SJason Jin imm = (s8)fetch_byte_imm();
1062ece92f85SJason Jin DECODE_PRINTF2("PUSH\t%d\n", imm);
1063ece92f85SJason Jin TRACE_AND_STEP();
1064ece92f85SJason Jin push_word(imm);
1065ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1066ece92f85SJason Jin END_OF_INSTR();
1067ece92f85SJason Jin }
1068ece92f85SJason Jin
1069ece92f85SJason Jin /****************************************************************************
1070ece92f85SJason Jin REMARKS:
1071ece92f85SJason Jin Handles opcode 0x6b
1072ece92f85SJason Jin ****************************************************************************/
x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED (op1))1073ece92f85SJason Jin void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
1074ece92f85SJason Jin {
1075ece92f85SJason Jin int mod, rl, rh;
1076ece92f85SJason Jin uint srcoffset;
1077ece92f85SJason Jin s8 imm;
1078ece92f85SJason Jin
1079ece92f85SJason Jin START_OF_INSTR();
1080ece92f85SJason Jin DECODE_PRINTF("IMUL\t");
1081ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1082ece92f85SJason Jin if (mod < 3) {
1083ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1084ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1085ece92f85SJason Jin u32 *destreg;
1086ece92f85SJason Jin u32 srcval;
1087ece92f85SJason Jin u32 res_lo,res_hi;
1088ece92f85SJason Jin
1089ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1090ece92f85SJason Jin DECODE_PRINTF(",");
1091ece92f85SJason Jin srcval = fetch_data_long(srcoffset);
1092ece92f85SJason Jin imm = fetch_byte_imm();
1093ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm);
1094ece92f85SJason Jin TRACE_AND_STEP();
1095ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
1096ece92f85SJason Jin if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
1097ece92f85SJason Jin (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
1098ece92f85SJason Jin CLEAR_FLAG(F_CF);
1099ece92f85SJason Jin CLEAR_FLAG(F_OF);
1100ece92f85SJason Jin } else {
1101ece92f85SJason Jin SET_FLAG(F_CF);
1102ece92f85SJason Jin SET_FLAG(F_OF);
1103ece92f85SJason Jin }
1104ece92f85SJason Jin *destreg = (u32)res_lo;
1105ece92f85SJason Jin } else {
1106ece92f85SJason Jin u16 *destreg;
1107ece92f85SJason Jin u16 srcval;
1108ece92f85SJason Jin u32 res;
1109ece92f85SJason Jin
1110ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
1111ece92f85SJason Jin DECODE_PRINTF(",");
1112ece92f85SJason Jin srcval = fetch_data_word(srcoffset);
1113ece92f85SJason Jin imm = fetch_byte_imm();
1114ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm);
1115ece92f85SJason Jin TRACE_AND_STEP();
1116ece92f85SJason Jin res = (s16)srcval * (s16)imm;
1117ece92f85SJason Jin if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
1118ece92f85SJason Jin (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
1119ece92f85SJason Jin CLEAR_FLAG(F_CF);
1120ece92f85SJason Jin CLEAR_FLAG(F_OF);
1121ece92f85SJason Jin } else {
1122ece92f85SJason Jin SET_FLAG(F_CF);
1123ece92f85SJason Jin SET_FLAG(F_OF);
1124ece92f85SJason Jin }
1125ece92f85SJason Jin *destreg = (u16)res;
1126ece92f85SJason Jin }
1127ece92f85SJason Jin } else { /* register to register */
1128ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1129ece92f85SJason Jin u32 *destreg,*srcreg;
1130ece92f85SJason Jin u32 res_lo,res_hi;
1131ece92f85SJason Jin
1132ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1133ece92f85SJason Jin DECODE_PRINTF(",");
1134ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
1135ece92f85SJason Jin imm = fetch_byte_imm();
1136ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm);
1137ece92f85SJason Jin TRACE_AND_STEP();
1138ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
1139ece92f85SJason Jin if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
1140ece92f85SJason Jin (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
1141ece92f85SJason Jin CLEAR_FLAG(F_CF);
1142ece92f85SJason Jin CLEAR_FLAG(F_OF);
1143ece92f85SJason Jin } else {
1144ece92f85SJason Jin SET_FLAG(F_CF);
1145ece92f85SJason Jin SET_FLAG(F_OF);
1146ece92f85SJason Jin }
1147ece92f85SJason Jin *destreg = (u32)res_lo;
1148ece92f85SJason Jin } else {
1149ece92f85SJason Jin u16 *destreg,*srcreg;
1150ece92f85SJason Jin u32 res;
1151ece92f85SJason Jin
1152ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
1153ece92f85SJason Jin DECODE_PRINTF(",");
1154ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
1155ece92f85SJason Jin imm = fetch_byte_imm();
1156ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm);
1157ece92f85SJason Jin TRACE_AND_STEP();
1158ece92f85SJason Jin res = (s16)*srcreg * (s16)imm;
1159ece92f85SJason Jin if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
1160ece92f85SJason Jin (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
1161ece92f85SJason Jin CLEAR_FLAG(F_CF);
1162ece92f85SJason Jin CLEAR_FLAG(F_OF);
1163ece92f85SJason Jin } else {
1164ece92f85SJason Jin SET_FLAG(F_CF);
1165ece92f85SJason Jin SET_FLAG(F_OF);
1166ece92f85SJason Jin }
1167ece92f85SJason Jin *destreg = (u16)res;
1168ece92f85SJason Jin }
1169ece92f85SJason Jin }
1170ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1171ece92f85SJason Jin END_OF_INSTR();
1172ece92f85SJason Jin }
1173ece92f85SJason Jin
1174ece92f85SJason Jin /****************************************************************************
1175ece92f85SJason Jin REMARKS:
1176ece92f85SJason Jin Handles opcode 0x6c
1177ece92f85SJason Jin ****************************************************************************/
x86emuOp_ins_byte(u8 X86EMU_UNUSED (op1))1178ece92f85SJason Jin void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
1179ece92f85SJason Jin {
1180ece92f85SJason Jin START_OF_INSTR();
1181ece92f85SJason Jin DECODE_PRINTF("INSB\n");
1182ece92f85SJason Jin ins(1);
1183ece92f85SJason Jin TRACE_AND_STEP();
1184ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1185ece92f85SJason Jin END_OF_INSTR();
1186ece92f85SJason Jin }
1187ece92f85SJason Jin
1188ece92f85SJason Jin /****************************************************************************
1189ece92f85SJason Jin REMARKS:
1190ece92f85SJason Jin Handles opcode 0x6d
1191ece92f85SJason Jin ****************************************************************************/
x86emuOp_ins_word(u8 X86EMU_UNUSED (op1))1192ece92f85SJason Jin void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
1193ece92f85SJason Jin {
1194ece92f85SJason Jin START_OF_INSTR();
1195ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1196ece92f85SJason Jin DECODE_PRINTF("INSD\n");
1197ece92f85SJason Jin ins(4);
1198ece92f85SJason Jin } else {
1199ece92f85SJason Jin DECODE_PRINTF("INSW\n");
1200ece92f85SJason Jin ins(2);
1201ece92f85SJason Jin }
1202ece92f85SJason Jin TRACE_AND_STEP();
1203ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1204ece92f85SJason Jin END_OF_INSTR();
1205ece92f85SJason Jin }
1206ece92f85SJason Jin
1207ece92f85SJason Jin /****************************************************************************
1208ece92f85SJason Jin REMARKS:
1209ece92f85SJason Jin Handles opcode 0x6e
1210ece92f85SJason Jin ****************************************************************************/
x86emuOp_outs_byte(u8 X86EMU_UNUSED (op1))1211ece92f85SJason Jin void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
1212ece92f85SJason Jin {
1213ece92f85SJason Jin START_OF_INSTR();
1214ece92f85SJason Jin DECODE_PRINTF("OUTSB\n");
1215ece92f85SJason Jin outs(1);
1216ece92f85SJason Jin TRACE_AND_STEP();
1217ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1218ece92f85SJason Jin END_OF_INSTR();
1219ece92f85SJason Jin }
1220ece92f85SJason Jin
1221ece92f85SJason Jin /****************************************************************************
1222ece92f85SJason Jin REMARKS:
1223ece92f85SJason Jin Handles opcode 0x6f
1224ece92f85SJason Jin ****************************************************************************/
x86emuOp_outs_word(u8 X86EMU_UNUSED (op1))1225ece92f85SJason Jin void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
1226ece92f85SJason Jin {
1227ece92f85SJason Jin START_OF_INSTR();
1228ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1229ece92f85SJason Jin DECODE_PRINTF("OUTSD\n");
1230ece92f85SJason Jin outs(4);
1231ece92f85SJason Jin } else {
1232ece92f85SJason Jin DECODE_PRINTF("OUTSW\n");
1233ece92f85SJason Jin outs(2);
1234ece92f85SJason Jin }
1235ece92f85SJason Jin TRACE_AND_STEP();
1236ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1237ece92f85SJason Jin END_OF_INSTR();
1238ece92f85SJason Jin }
1239ece92f85SJason Jin
1240ece92f85SJason Jin /****************************************************************************
1241ece92f85SJason Jin REMARKS:
1242ece92f85SJason Jin Handles opcode 0x70 - 0x7F
1243ece92f85SJason Jin ****************************************************************************/
1244ece92f85SJason Jin int x86emu_check_jump_condition(u8 op);
1245ece92f85SJason Jin
x86emuOp_jump_near_cond(u8 op1)1246ece92f85SJason Jin void x86emuOp_jump_near_cond(u8 op1)
1247ece92f85SJason Jin {
1248ece92f85SJason Jin s8 offset;
1249ece92f85SJason Jin u16 target;
1250ece92f85SJason Jin int cond;
1251ece92f85SJason Jin
1252ece92f85SJason Jin /* jump to byte offset if overflow flag is set */
1253ece92f85SJason Jin START_OF_INSTR();
1254ece92f85SJason Jin cond = x86emu_check_jump_condition(op1 & 0xF);
1255ece92f85SJason Jin offset = (s8)fetch_byte_imm();
1256ece92f85SJason Jin target = (u16)(M.x86.R_IP + (s16)offset);
1257ece92f85SJason Jin DECODE_PRINTF2("%x\n", target);
1258ece92f85SJason Jin TRACE_AND_STEP();
1259ece92f85SJason Jin if (cond)
1260ece92f85SJason Jin M.x86.R_IP = target;
1261ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1262ece92f85SJason Jin END_OF_INSTR();
1263ece92f85SJason Jin }
1264ece92f85SJason Jin
1265ece92f85SJason Jin /****************************************************************************
1266ece92f85SJason Jin REMARKS:
1267ece92f85SJason Jin Handles opcode 0x80
1268ece92f85SJason Jin ****************************************************************************/
x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED (op1))1269ece92f85SJason Jin void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
1270ece92f85SJason Jin {
1271ece92f85SJason Jin int mod, rl, rh;
1272ece92f85SJason Jin u8 *destreg;
1273ece92f85SJason Jin uint destoffset;
1274ece92f85SJason Jin u8 imm;
1275ece92f85SJason Jin u8 destval;
1276ece92f85SJason Jin
1277ece92f85SJason Jin /*
1278ece92f85SJason Jin * Weirdo special case instruction format. Part of the opcode
1279ece92f85SJason Jin * held below in "RH". Doubly nested case would result, except
1280ece92f85SJason Jin * that the decoded instruction
1281ece92f85SJason Jin */
1282ece92f85SJason Jin START_OF_INSTR();
1283ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1284b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
1285ece92f85SJason Jin if (DEBUG_DECODE()) {
1286ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
1287ece92f85SJason Jin general, so that it is important to leave the strings
1288ece92f85SJason Jin in the same format, even though the result is that the
1289ece92f85SJason Jin above test is done twice. */
1290ece92f85SJason Jin
1291ece92f85SJason Jin switch (rh) {
1292ece92f85SJason Jin case 0:
1293ece92f85SJason Jin DECODE_PRINTF("ADD\t");
1294ece92f85SJason Jin break;
1295ece92f85SJason Jin case 1:
1296ece92f85SJason Jin DECODE_PRINTF("OR\t");
1297ece92f85SJason Jin break;
1298ece92f85SJason Jin case 2:
1299ece92f85SJason Jin DECODE_PRINTF("ADC\t");
1300ece92f85SJason Jin break;
1301ece92f85SJason Jin case 3:
1302ece92f85SJason Jin DECODE_PRINTF("SBB\t");
1303ece92f85SJason Jin break;
1304ece92f85SJason Jin case 4:
1305ece92f85SJason Jin DECODE_PRINTF("AND\t");
1306ece92f85SJason Jin break;
1307ece92f85SJason Jin case 5:
1308ece92f85SJason Jin DECODE_PRINTF("SUB\t");
1309ece92f85SJason Jin break;
1310ece92f85SJason Jin case 6:
1311ece92f85SJason Jin DECODE_PRINTF("XOR\t");
1312ece92f85SJason Jin break;
1313ece92f85SJason Jin case 7:
1314ece92f85SJason Jin DECODE_PRINTF("CMP\t");
1315ece92f85SJason Jin break;
1316ece92f85SJason Jin }
1317ece92f85SJason Jin }
1318ece92f85SJason Jin #endif
1319ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing
1320ece92f85SJason Jin mode. */
1321ece92f85SJason Jin if (mod < 3) {
1322ece92f85SJason Jin DECODE_PRINTF("BYTE PTR ");
1323ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
1324ece92f85SJason Jin DECODE_PRINTF(",");
1325ece92f85SJason Jin destval = fetch_data_byte(destoffset);
1326ece92f85SJason Jin imm = fetch_byte_imm();
1327ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm);
1328ece92f85SJason Jin TRACE_AND_STEP();
1329ece92f85SJason Jin destval = (*genop_byte_operation[rh]) (destval, imm);
1330ece92f85SJason Jin if (rh != 7)
1331ece92f85SJason Jin store_data_byte(destoffset, destval);
1332ece92f85SJason Jin } else { /* register to register */
1333ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
1334ece92f85SJason Jin DECODE_PRINTF(",");
1335ece92f85SJason Jin imm = fetch_byte_imm();
1336ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm);
1337ece92f85SJason Jin TRACE_AND_STEP();
1338ece92f85SJason Jin destval = (*genop_byte_operation[rh]) (*destreg, imm);
1339ece92f85SJason Jin if (rh != 7)
1340ece92f85SJason Jin *destreg = destval;
1341ece92f85SJason Jin }
1342ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1343ece92f85SJason Jin END_OF_INSTR();
1344ece92f85SJason Jin }
1345ece92f85SJason Jin
1346ece92f85SJason Jin /****************************************************************************
1347ece92f85SJason Jin REMARKS:
1348ece92f85SJason Jin Handles opcode 0x81
1349ece92f85SJason Jin ****************************************************************************/
x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED (op1))1350ece92f85SJason Jin void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
1351ece92f85SJason Jin {
1352ece92f85SJason Jin int mod, rl, rh;
1353ece92f85SJason Jin uint destoffset;
1354ece92f85SJason Jin
1355ece92f85SJason Jin /*
1356ece92f85SJason Jin * Weirdo special case instruction format. Part of the opcode
1357ece92f85SJason Jin * held below in "RH". Doubly nested case would result, except
1358ece92f85SJason Jin * that the decoded instruction
1359ece92f85SJason Jin */
1360ece92f85SJason Jin START_OF_INSTR();
1361ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1362b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
1363ece92f85SJason Jin if (DEBUG_DECODE()) {
1364ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
1365ece92f85SJason Jin general, so that it is important to leave the strings
1366ece92f85SJason Jin in the same format, even though the result is that the
1367ece92f85SJason Jin above test is done twice. */
1368ece92f85SJason Jin
1369ece92f85SJason Jin switch (rh) {
1370ece92f85SJason Jin case 0:
1371ece92f85SJason Jin DECODE_PRINTF("ADD\t");
1372ece92f85SJason Jin break;
1373ece92f85SJason Jin case 1:
1374ece92f85SJason Jin DECODE_PRINTF("OR\t");
1375ece92f85SJason Jin break;
1376ece92f85SJason Jin case 2:
1377ece92f85SJason Jin DECODE_PRINTF("ADC\t");
1378ece92f85SJason Jin break;
1379ece92f85SJason Jin case 3:
1380ece92f85SJason Jin DECODE_PRINTF("SBB\t");
1381ece92f85SJason Jin break;
1382ece92f85SJason Jin case 4:
1383ece92f85SJason Jin DECODE_PRINTF("AND\t");
1384ece92f85SJason Jin break;
1385ece92f85SJason Jin case 5:
1386ece92f85SJason Jin DECODE_PRINTF("SUB\t");
1387ece92f85SJason Jin break;
1388ece92f85SJason Jin case 6:
1389ece92f85SJason Jin DECODE_PRINTF("XOR\t");
1390ece92f85SJason Jin break;
1391ece92f85SJason Jin case 7:
1392ece92f85SJason Jin DECODE_PRINTF("CMP\t");
1393ece92f85SJason Jin break;
1394ece92f85SJason Jin }
1395ece92f85SJason Jin }
1396ece92f85SJason Jin #endif
1397ece92f85SJason Jin /*
1398ece92f85SJason Jin * Know operation, decode the mod byte to find the addressing
1399ece92f85SJason Jin * mode.
1400ece92f85SJason Jin */
1401ece92f85SJason Jin if (mod < 3) {
1402ece92f85SJason Jin DECODE_PRINTF("DWORD PTR ");
1403ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
1404ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1405ece92f85SJason Jin u32 destval,imm;
1406ece92f85SJason Jin
1407ece92f85SJason Jin DECODE_PRINTF(",");
1408ece92f85SJason Jin destval = fetch_data_long(destoffset);
1409ece92f85SJason Jin imm = fetch_long_imm();
1410ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm);
1411ece92f85SJason Jin TRACE_AND_STEP();
1412ece92f85SJason Jin destval = (*genop_long_operation[rh]) (destval, imm);
1413ece92f85SJason Jin if (rh != 7)
1414ece92f85SJason Jin store_data_long(destoffset, destval);
1415ece92f85SJason Jin } else {
1416ece92f85SJason Jin u16 destval,imm;
1417ece92f85SJason Jin
1418ece92f85SJason Jin DECODE_PRINTF(",");
1419ece92f85SJason Jin destval = fetch_data_word(destoffset);
1420ece92f85SJason Jin imm = fetch_word_imm();
1421ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm);
1422ece92f85SJason Jin TRACE_AND_STEP();
1423ece92f85SJason Jin destval = (*genop_word_operation[rh]) (destval, imm);
1424ece92f85SJason Jin if (rh != 7)
1425ece92f85SJason Jin store_data_word(destoffset, destval);
1426ece92f85SJason Jin }
1427ece92f85SJason Jin } else { /* register to register */
1428ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1429ece92f85SJason Jin u32 *destreg;
1430ece92f85SJason Jin u32 destval,imm;
1431ece92f85SJason Jin
1432ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
1433ece92f85SJason Jin DECODE_PRINTF(",");
1434ece92f85SJason Jin imm = fetch_long_imm();
1435ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm);
1436ece92f85SJason Jin TRACE_AND_STEP();
1437ece92f85SJason Jin destval = (*genop_long_operation[rh]) (*destreg, imm);
1438ece92f85SJason Jin if (rh != 7)
1439ece92f85SJason Jin *destreg = destval;
1440ece92f85SJason Jin } else {
1441ece92f85SJason Jin u16 *destreg;
1442ece92f85SJason Jin u16 destval,imm;
1443ece92f85SJason Jin
1444ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
1445ece92f85SJason Jin DECODE_PRINTF(",");
1446ece92f85SJason Jin imm = fetch_word_imm();
1447ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm);
1448ece92f85SJason Jin TRACE_AND_STEP();
1449ece92f85SJason Jin destval = (*genop_word_operation[rh]) (*destreg, imm);
1450ece92f85SJason Jin if (rh != 7)
1451ece92f85SJason Jin *destreg = destval;
1452ece92f85SJason Jin }
1453ece92f85SJason Jin }
1454ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1455ece92f85SJason Jin END_OF_INSTR();
1456ece92f85SJason Jin }
1457ece92f85SJason Jin
1458ece92f85SJason Jin /****************************************************************************
1459ece92f85SJason Jin REMARKS:
1460ece92f85SJason Jin Handles opcode 0x82
1461ece92f85SJason Jin ****************************************************************************/
x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED (op1))1462ece92f85SJason Jin void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
1463ece92f85SJason Jin {
1464ece92f85SJason Jin int mod, rl, rh;
1465ece92f85SJason Jin u8 *destreg;
1466ece92f85SJason Jin uint destoffset;
1467ece92f85SJason Jin u8 imm;
1468ece92f85SJason Jin u8 destval;
1469ece92f85SJason Jin
1470ece92f85SJason Jin /*
1471ece92f85SJason Jin * Weirdo special case instruction format. Part of the opcode
1472ece92f85SJason Jin * held below in "RH". Doubly nested case would result, except
1473ece92f85SJason Jin * that the decoded instruction Similar to opcode 81, except that
1474ece92f85SJason Jin * the immediate byte is sign extended to a word length.
1475ece92f85SJason Jin */
1476ece92f85SJason Jin START_OF_INSTR();
1477ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1478b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
1479ece92f85SJason Jin if (DEBUG_DECODE()) {
1480ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
1481ece92f85SJason Jin general, so that it is important to leave the strings
1482ece92f85SJason Jin in the same format, even though the result is that the
1483ece92f85SJason Jin above test is done twice. */
1484ece92f85SJason Jin switch (rh) {
1485ece92f85SJason Jin case 0:
1486ece92f85SJason Jin DECODE_PRINTF("ADD\t");
1487ece92f85SJason Jin break;
1488ece92f85SJason Jin case 1:
1489ece92f85SJason Jin DECODE_PRINTF("OR\t");
1490ece92f85SJason Jin break;
1491ece92f85SJason Jin case 2:
1492ece92f85SJason Jin DECODE_PRINTF("ADC\t");
1493ece92f85SJason Jin break;
1494ece92f85SJason Jin case 3:
1495ece92f85SJason Jin DECODE_PRINTF("SBB\t");
1496ece92f85SJason Jin break;
1497ece92f85SJason Jin case 4:
1498ece92f85SJason Jin DECODE_PRINTF("AND\t");
1499ece92f85SJason Jin break;
1500ece92f85SJason Jin case 5:
1501ece92f85SJason Jin DECODE_PRINTF("SUB\t");
1502ece92f85SJason Jin break;
1503ece92f85SJason Jin case 6:
1504ece92f85SJason Jin DECODE_PRINTF("XOR\t");
1505ece92f85SJason Jin break;
1506ece92f85SJason Jin case 7:
1507ece92f85SJason Jin DECODE_PRINTF("CMP\t");
1508ece92f85SJason Jin break;
1509ece92f85SJason Jin }
1510ece92f85SJason Jin }
1511ece92f85SJason Jin #endif
1512ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing
1513ece92f85SJason Jin mode. */
1514ece92f85SJason Jin if (mod < 3) {
1515ece92f85SJason Jin DECODE_PRINTF("BYTE PTR ");
1516ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
1517ece92f85SJason Jin destval = fetch_data_byte(destoffset);
1518ece92f85SJason Jin imm = fetch_byte_imm();
1519ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm);
1520ece92f85SJason Jin TRACE_AND_STEP();
1521ece92f85SJason Jin destval = (*genop_byte_operation[rh]) (destval, imm);
1522ece92f85SJason Jin if (rh != 7)
1523ece92f85SJason Jin store_data_byte(destoffset, destval);
1524ece92f85SJason Jin } else { /* register to register */
1525ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
1526ece92f85SJason Jin imm = fetch_byte_imm();
1527ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm);
1528ece92f85SJason Jin TRACE_AND_STEP();
1529ece92f85SJason Jin destval = (*genop_byte_operation[rh]) (*destreg, imm);
1530ece92f85SJason Jin if (rh != 7)
1531ece92f85SJason Jin *destreg = destval;
1532ece92f85SJason Jin }
1533ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1534ece92f85SJason Jin END_OF_INSTR();
1535ece92f85SJason Jin }
1536ece92f85SJason Jin
1537ece92f85SJason Jin /****************************************************************************
1538ece92f85SJason Jin REMARKS:
1539ece92f85SJason Jin Handles opcode 0x83
1540ece92f85SJason Jin ****************************************************************************/
x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED (op1))1541ece92f85SJason Jin void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
1542ece92f85SJason Jin {
1543ece92f85SJason Jin int mod, rl, rh;
1544ece92f85SJason Jin uint destoffset;
1545ece92f85SJason Jin
1546ece92f85SJason Jin /*
1547ece92f85SJason Jin * Weirdo special case instruction format. Part of the opcode
1548ece92f85SJason Jin * held below in "RH". Doubly nested case would result, except
1549ece92f85SJason Jin * that the decoded instruction Similar to opcode 81, except that
1550ece92f85SJason Jin * the immediate byte is sign extended to a word length.
1551ece92f85SJason Jin */
1552ece92f85SJason Jin START_OF_INSTR();
1553ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1554b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
1555ece92f85SJason Jin if (DEBUG_DECODE()) {
1556ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
1557ece92f85SJason Jin general, so that it is important to leave the strings
1558ece92f85SJason Jin in the same format, even though the result is that the
1559ece92f85SJason Jin above test is done twice. */
1560ece92f85SJason Jin switch (rh) {
1561ece92f85SJason Jin case 0:
1562ece92f85SJason Jin DECODE_PRINTF("ADD\t");
1563ece92f85SJason Jin break;
1564ece92f85SJason Jin case 1:
1565ece92f85SJason Jin DECODE_PRINTF("OR\t");
1566ece92f85SJason Jin break;
1567ece92f85SJason Jin case 2:
1568ece92f85SJason Jin DECODE_PRINTF("ADC\t");
1569ece92f85SJason Jin break;
1570ece92f85SJason Jin case 3:
1571ece92f85SJason Jin DECODE_PRINTF("SBB\t");
1572ece92f85SJason Jin break;
1573ece92f85SJason Jin case 4:
1574ece92f85SJason Jin DECODE_PRINTF("AND\t");
1575ece92f85SJason Jin break;
1576ece92f85SJason Jin case 5:
1577ece92f85SJason Jin DECODE_PRINTF("SUB\t");
1578ece92f85SJason Jin break;
1579ece92f85SJason Jin case 6:
1580ece92f85SJason Jin DECODE_PRINTF("XOR\t");
1581ece92f85SJason Jin break;
1582ece92f85SJason Jin case 7:
1583ece92f85SJason Jin DECODE_PRINTF("CMP\t");
1584ece92f85SJason Jin break;
1585ece92f85SJason Jin }
1586ece92f85SJason Jin }
1587ece92f85SJason Jin #endif
1588ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing
1589ece92f85SJason Jin mode. */
1590ece92f85SJason Jin if (mod < 3) {
1591ece92f85SJason Jin DECODE_PRINTF("DWORD PTR ");
1592ece92f85SJason Jin destoffset = decode_rmXX_address(mod,rl);
1593ece92f85SJason Jin
1594ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1595ece92f85SJason Jin u32 destval,imm;
1596ece92f85SJason Jin
1597ece92f85SJason Jin destval = fetch_data_long(destoffset);
1598ece92f85SJason Jin imm = (s8) fetch_byte_imm();
1599ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm);
1600ece92f85SJason Jin TRACE_AND_STEP();
1601ece92f85SJason Jin destval = (*genop_long_operation[rh]) (destval, imm);
1602ece92f85SJason Jin if (rh != 7)
1603ece92f85SJason Jin store_data_long(destoffset, destval);
1604ece92f85SJason Jin } else {
1605ece92f85SJason Jin u16 destval,imm;
1606ece92f85SJason Jin
1607ece92f85SJason Jin destval = fetch_data_word(destoffset);
1608ece92f85SJason Jin imm = (s8) fetch_byte_imm();
1609ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm);
1610ece92f85SJason Jin TRACE_AND_STEP();
1611ece92f85SJason Jin destval = (*genop_word_operation[rh]) (destval, imm);
1612ece92f85SJason Jin if (rh != 7)
1613ece92f85SJason Jin store_data_word(destoffset, destval);
1614ece92f85SJason Jin }
1615ece92f85SJason Jin } else { /* register to register */
1616ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1617ece92f85SJason Jin u32 *destreg;
1618ece92f85SJason Jin u32 destval,imm;
1619ece92f85SJason Jin
1620ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
1621ece92f85SJason Jin imm = (s8) fetch_byte_imm();
1622ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm);
1623ece92f85SJason Jin TRACE_AND_STEP();
1624ece92f85SJason Jin destval = (*genop_long_operation[rh]) (*destreg, imm);
1625ece92f85SJason Jin if (rh != 7)
1626ece92f85SJason Jin *destreg = destval;
1627ece92f85SJason Jin } else {
1628ece92f85SJason Jin u16 *destreg;
1629ece92f85SJason Jin u16 destval,imm;
1630ece92f85SJason Jin
1631ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
1632ece92f85SJason Jin imm = (s8) fetch_byte_imm();
1633ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm);
1634ece92f85SJason Jin TRACE_AND_STEP();
1635ece92f85SJason Jin destval = (*genop_word_operation[rh]) (*destreg, imm);
1636ece92f85SJason Jin if (rh != 7)
1637ece92f85SJason Jin *destreg = destval;
1638ece92f85SJason Jin }
1639ece92f85SJason Jin }
1640ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1641ece92f85SJason Jin END_OF_INSTR();
1642ece92f85SJason Jin }
1643ece92f85SJason Jin
1644ece92f85SJason Jin /****************************************************************************
1645ece92f85SJason Jin REMARKS:
1646ece92f85SJason Jin Handles opcode 0x84
1647ece92f85SJason Jin ****************************************************************************/
x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED (op1))1648ece92f85SJason Jin void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
1649ece92f85SJason Jin {
1650ece92f85SJason Jin int mod, rl, rh;
1651ece92f85SJason Jin u8 *destreg, *srcreg;
1652ece92f85SJason Jin uint destoffset;
1653ece92f85SJason Jin u8 destval;
1654ece92f85SJason Jin
1655ece92f85SJason Jin START_OF_INSTR();
1656ece92f85SJason Jin DECODE_PRINTF("TEST\t");
1657ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1658ece92f85SJason Jin if (mod < 3) {
1659ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
1660ece92f85SJason Jin DECODE_PRINTF(",");
1661ece92f85SJason Jin destval = fetch_data_byte(destoffset);
1662ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh);
1663ece92f85SJason Jin DECODE_PRINTF("\n");
1664ece92f85SJason Jin TRACE_AND_STEP();
1665ece92f85SJason Jin test_byte(destval, *srcreg);
1666ece92f85SJason Jin } else { /* register to register */
1667ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
1668ece92f85SJason Jin DECODE_PRINTF(",");
1669ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh);
1670ece92f85SJason Jin DECODE_PRINTF("\n");
1671ece92f85SJason Jin TRACE_AND_STEP();
1672ece92f85SJason Jin test_byte(*destreg, *srcreg);
1673ece92f85SJason Jin }
1674ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1675ece92f85SJason Jin END_OF_INSTR();
1676ece92f85SJason Jin }
1677ece92f85SJason Jin
1678ece92f85SJason Jin /****************************************************************************
1679ece92f85SJason Jin REMARKS:
1680ece92f85SJason Jin Handles opcode 0x85
1681ece92f85SJason Jin ****************************************************************************/
x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED (op1))1682ece92f85SJason Jin void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
1683ece92f85SJason Jin {
1684ece92f85SJason Jin int mod, rl, rh;
1685ece92f85SJason Jin uint destoffset;
1686ece92f85SJason Jin
1687ece92f85SJason Jin START_OF_INSTR();
1688ece92f85SJason Jin DECODE_PRINTF("TEST\t");
1689ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1690ece92f85SJason Jin if (mod < 3) {
1691ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
1692ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1693ece92f85SJason Jin u32 destval;
1694ece92f85SJason Jin u32 *srcreg;
1695ece92f85SJason Jin
1696ece92f85SJason Jin DECODE_PRINTF(",");
1697ece92f85SJason Jin destval = fetch_data_long(destoffset);
1698ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh);
1699ece92f85SJason Jin DECODE_PRINTF("\n");
1700ece92f85SJason Jin TRACE_AND_STEP();
1701ece92f85SJason Jin test_long(destval, *srcreg);
1702ece92f85SJason Jin } else {
1703ece92f85SJason Jin u16 destval;
1704ece92f85SJason Jin u16 *srcreg;
1705ece92f85SJason Jin
1706ece92f85SJason Jin DECODE_PRINTF(",");
1707ece92f85SJason Jin destval = fetch_data_word(destoffset);
1708ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh);
1709ece92f85SJason Jin DECODE_PRINTF("\n");
1710ece92f85SJason Jin TRACE_AND_STEP();
1711ece92f85SJason Jin test_word(destval, *srcreg);
1712ece92f85SJason Jin }
1713ece92f85SJason Jin } else { /* register to register */
1714ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1715ece92f85SJason Jin u32 *destreg,*srcreg;
1716ece92f85SJason Jin
1717ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
1718ece92f85SJason Jin DECODE_PRINTF(",");
1719ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh);
1720ece92f85SJason Jin DECODE_PRINTF("\n");
1721ece92f85SJason Jin TRACE_AND_STEP();
1722ece92f85SJason Jin test_long(*destreg, *srcreg);
1723ece92f85SJason Jin } else {
1724ece92f85SJason Jin u16 *destreg,*srcreg;
1725ece92f85SJason Jin
1726ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
1727ece92f85SJason Jin DECODE_PRINTF(",");
1728ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh);
1729ece92f85SJason Jin DECODE_PRINTF("\n");
1730ece92f85SJason Jin TRACE_AND_STEP();
1731ece92f85SJason Jin test_word(*destreg, *srcreg);
1732ece92f85SJason Jin }
1733ece92f85SJason Jin }
1734ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1735ece92f85SJason Jin END_OF_INSTR();
1736ece92f85SJason Jin }
1737ece92f85SJason Jin
1738ece92f85SJason Jin /****************************************************************************
1739ece92f85SJason Jin REMARKS:
1740ece92f85SJason Jin Handles opcode 0x86
1741ece92f85SJason Jin ****************************************************************************/
x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED (op1))1742ece92f85SJason Jin void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
1743ece92f85SJason Jin {
1744ece92f85SJason Jin int mod, rl, rh;
1745ece92f85SJason Jin u8 *destreg, *srcreg;
1746ece92f85SJason Jin uint destoffset;
1747ece92f85SJason Jin u8 destval;
1748ece92f85SJason Jin u8 tmp;
1749ece92f85SJason Jin
1750ece92f85SJason Jin START_OF_INSTR();
1751ece92f85SJason Jin DECODE_PRINTF("XCHG\t");
1752ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1753ece92f85SJason Jin if (mod < 3) {
1754ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
1755ece92f85SJason Jin DECODE_PRINTF(",");
1756ece92f85SJason Jin destval = fetch_data_byte(destoffset);
1757ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh);
1758ece92f85SJason Jin DECODE_PRINTF("\n");
1759ece92f85SJason Jin TRACE_AND_STEP();
1760ece92f85SJason Jin tmp = *srcreg;
1761ece92f85SJason Jin *srcreg = destval;
1762ece92f85SJason Jin destval = tmp;
1763ece92f85SJason Jin store_data_byte(destoffset, destval);
1764ece92f85SJason Jin } else { /* register to register */
1765ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
1766ece92f85SJason Jin DECODE_PRINTF(",");
1767ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh);
1768ece92f85SJason Jin DECODE_PRINTF("\n");
1769ece92f85SJason Jin TRACE_AND_STEP();
1770ece92f85SJason Jin tmp = *srcreg;
1771ece92f85SJason Jin *srcreg = *destreg;
1772ece92f85SJason Jin *destreg = tmp;
1773ece92f85SJason Jin }
1774ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1775ece92f85SJason Jin END_OF_INSTR();
1776ece92f85SJason Jin }
1777ece92f85SJason Jin
1778ece92f85SJason Jin /****************************************************************************
1779ece92f85SJason Jin REMARKS:
1780ece92f85SJason Jin Handles opcode 0x87
1781ece92f85SJason Jin ****************************************************************************/
x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED (op1))1782ece92f85SJason Jin void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
1783ece92f85SJason Jin {
1784ece92f85SJason Jin int mod, rl, rh;
1785ece92f85SJason Jin uint destoffset;
1786ece92f85SJason Jin
1787ece92f85SJason Jin START_OF_INSTR();
1788ece92f85SJason Jin DECODE_PRINTF("XCHG\t");
1789ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1790ece92f85SJason Jin if (mod < 3) {
1791ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
1792ece92f85SJason Jin DECODE_PRINTF(",");
1793ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1794ece92f85SJason Jin u32 *srcreg;
1795ece92f85SJason Jin u32 destval,tmp;
1796ece92f85SJason Jin
1797ece92f85SJason Jin destval = fetch_data_long(destoffset);
1798ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh);
1799ece92f85SJason Jin DECODE_PRINTF("\n");
1800ece92f85SJason Jin TRACE_AND_STEP();
1801ece92f85SJason Jin tmp = *srcreg;
1802ece92f85SJason Jin *srcreg = destval;
1803ece92f85SJason Jin destval = tmp;
1804ece92f85SJason Jin store_data_long(destoffset, destval);
1805ece92f85SJason Jin } else {
1806ece92f85SJason Jin u16 *srcreg;
1807ece92f85SJason Jin u16 destval,tmp;
1808ece92f85SJason Jin
1809ece92f85SJason Jin destval = fetch_data_word(destoffset);
1810ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh);
1811ece92f85SJason Jin DECODE_PRINTF("\n");
1812ece92f85SJason Jin TRACE_AND_STEP();
1813ece92f85SJason Jin tmp = *srcreg;
1814ece92f85SJason Jin *srcreg = destval;
1815ece92f85SJason Jin destval = tmp;
1816ece92f85SJason Jin store_data_word(destoffset, destval);
1817ece92f85SJason Jin }
1818ece92f85SJason Jin } else { /* register to register */
1819ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1820ece92f85SJason Jin u32 *destreg,*srcreg;
1821ece92f85SJason Jin u32 tmp;
1822ece92f85SJason Jin
1823ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
1824ece92f85SJason Jin DECODE_PRINTF(",");
1825ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh);
1826ece92f85SJason Jin DECODE_PRINTF("\n");
1827ece92f85SJason Jin TRACE_AND_STEP();
1828ece92f85SJason Jin tmp = *srcreg;
1829ece92f85SJason Jin *srcreg = *destreg;
1830ece92f85SJason Jin *destreg = tmp;
1831ece92f85SJason Jin } else {
1832ece92f85SJason Jin u16 *destreg,*srcreg;
1833ece92f85SJason Jin u16 tmp;
1834ece92f85SJason Jin
1835ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
1836ece92f85SJason Jin DECODE_PRINTF(",");
1837ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh);
1838ece92f85SJason Jin DECODE_PRINTF("\n");
1839ece92f85SJason Jin TRACE_AND_STEP();
1840ece92f85SJason Jin tmp = *srcreg;
1841ece92f85SJason Jin *srcreg = *destreg;
1842ece92f85SJason Jin *destreg = tmp;
1843ece92f85SJason Jin }
1844ece92f85SJason Jin }
1845ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1846ece92f85SJason Jin END_OF_INSTR();
1847ece92f85SJason Jin }
1848ece92f85SJason Jin
1849ece92f85SJason Jin /****************************************************************************
1850ece92f85SJason Jin REMARKS:
1851ece92f85SJason Jin Handles opcode 0x88
1852ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED (op1))1853ece92f85SJason Jin void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
1854ece92f85SJason Jin {
1855ece92f85SJason Jin int mod, rl, rh;
1856ece92f85SJason Jin u8 *destreg, *srcreg;
1857ece92f85SJason Jin uint destoffset;
1858ece92f85SJason Jin
1859ece92f85SJason Jin START_OF_INSTR();
1860ece92f85SJason Jin DECODE_PRINTF("MOV\t");
1861ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1862ece92f85SJason Jin if (mod < 3) {
1863ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
1864ece92f85SJason Jin DECODE_PRINTF(",");
1865ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh);
1866ece92f85SJason Jin DECODE_PRINTF("\n");
1867ece92f85SJason Jin TRACE_AND_STEP();
1868ece92f85SJason Jin store_data_byte(destoffset, *srcreg);
1869ece92f85SJason Jin } else { /* register to register */
1870ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
1871ece92f85SJason Jin DECODE_PRINTF(",");
1872ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh);
1873ece92f85SJason Jin DECODE_PRINTF("\n");
1874ece92f85SJason Jin TRACE_AND_STEP();
1875ece92f85SJason Jin *destreg = *srcreg;
1876ece92f85SJason Jin }
1877ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1878ece92f85SJason Jin END_OF_INSTR();
1879ece92f85SJason Jin }
1880ece92f85SJason Jin
1881ece92f85SJason Jin /****************************************************************************
1882ece92f85SJason Jin REMARKS:
1883ece92f85SJason Jin Handles opcode 0x89
1884ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED (op1))1885ece92f85SJason Jin void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
1886ece92f85SJason Jin {
1887ece92f85SJason Jin int mod, rl, rh;
1888ece92f85SJason Jin uint destoffset;
1889ece92f85SJason Jin
1890ece92f85SJason Jin START_OF_INSTR();
1891ece92f85SJason Jin DECODE_PRINTF("MOV\t");
1892ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1893ece92f85SJason Jin if (mod < 3) {
1894ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
1895ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1896ece92f85SJason Jin u32 *srcreg;
1897ece92f85SJason Jin
1898ece92f85SJason Jin DECODE_PRINTF(",");
1899ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh);
1900ece92f85SJason Jin DECODE_PRINTF("\n");
1901ece92f85SJason Jin TRACE_AND_STEP();
1902ece92f85SJason Jin store_data_long(destoffset, *srcreg);
1903ece92f85SJason Jin } else {
1904ece92f85SJason Jin u16 *srcreg;
1905ece92f85SJason Jin
1906ece92f85SJason Jin DECODE_PRINTF(",");
1907ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh);
1908ece92f85SJason Jin DECODE_PRINTF("\n");
1909ece92f85SJason Jin TRACE_AND_STEP();
1910ece92f85SJason Jin store_data_word(destoffset, *srcreg);
1911ece92f85SJason Jin }
1912ece92f85SJason Jin } else { /* register to register */
1913ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1914ece92f85SJason Jin u32 *destreg,*srcreg;
1915ece92f85SJason Jin
1916ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
1917ece92f85SJason Jin DECODE_PRINTF(",");
1918ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh);
1919ece92f85SJason Jin DECODE_PRINTF("\n");
1920ece92f85SJason Jin TRACE_AND_STEP();
1921ece92f85SJason Jin *destreg = *srcreg;
1922ece92f85SJason Jin } else {
1923ece92f85SJason Jin u16 *destreg,*srcreg;
1924ece92f85SJason Jin
1925ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
1926ece92f85SJason Jin DECODE_PRINTF(",");
1927ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh);
1928ece92f85SJason Jin DECODE_PRINTF("\n");
1929ece92f85SJason Jin TRACE_AND_STEP();
1930ece92f85SJason Jin *destreg = *srcreg;
1931ece92f85SJason Jin }
1932ece92f85SJason Jin }
1933ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1934ece92f85SJason Jin END_OF_INSTR();
1935ece92f85SJason Jin }
1936ece92f85SJason Jin
1937ece92f85SJason Jin /****************************************************************************
1938ece92f85SJason Jin REMARKS:
1939ece92f85SJason Jin Handles opcode 0x8a
1940ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED (op1))1941ece92f85SJason Jin void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
1942ece92f85SJason Jin {
1943ece92f85SJason Jin int mod, rl, rh;
1944ece92f85SJason Jin u8 *destreg, *srcreg;
1945ece92f85SJason Jin uint srcoffset;
1946ece92f85SJason Jin u8 srcval;
1947ece92f85SJason Jin
1948ece92f85SJason Jin START_OF_INSTR();
1949ece92f85SJason Jin DECODE_PRINTF("MOV\t");
1950ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1951ece92f85SJason Jin if (mod < 3) {
1952ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rh);
1953ece92f85SJason Jin DECODE_PRINTF(",");
1954ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1955ece92f85SJason Jin srcval = fetch_data_byte(srcoffset);
1956ece92f85SJason Jin DECODE_PRINTF("\n");
1957ece92f85SJason Jin TRACE_AND_STEP();
1958ece92f85SJason Jin *destreg = srcval;
1959ece92f85SJason Jin } else { /* register to register */
1960ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rh);
1961ece92f85SJason Jin DECODE_PRINTF(",");
1962ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl);
1963ece92f85SJason Jin DECODE_PRINTF("\n");
1964ece92f85SJason Jin TRACE_AND_STEP();
1965ece92f85SJason Jin *destreg = *srcreg;
1966ece92f85SJason Jin }
1967ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1968ece92f85SJason Jin END_OF_INSTR();
1969ece92f85SJason Jin }
1970ece92f85SJason Jin
1971ece92f85SJason Jin /****************************************************************************
1972ece92f85SJason Jin REMARKS:
1973ece92f85SJason Jin Handles opcode 0x8b
1974ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED (op1))1975ece92f85SJason Jin void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
1976ece92f85SJason Jin {
1977ece92f85SJason Jin int mod, rl, rh;
1978ece92f85SJason Jin uint srcoffset;
1979ece92f85SJason Jin
1980ece92f85SJason Jin START_OF_INSTR();
1981ece92f85SJason Jin DECODE_PRINTF("MOV\t");
1982ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1983ece92f85SJason Jin if (mod < 3) {
1984ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1985ece92f85SJason Jin u32 *destreg;
1986ece92f85SJason Jin u32 srcval;
1987ece92f85SJason Jin
1988ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1989ece92f85SJason Jin DECODE_PRINTF(",");
1990ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1991ece92f85SJason Jin srcval = fetch_data_long(srcoffset);
1992ece92f85SJason Jin DECODE_PRINTF("\n");
1993ece92f85SJason Jin TRACE_AND_STEP();
1994ece92f85SJason Jin *destreg = srcval;
1995ece92f85SJason Jin } else {
1996ece92f85SJason Jin u16 *destreg;
1997ece92f85SJason Jin u16 srcval;
1998ece92f85SJason Jin
1999ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
2000ece92f85SJason Jin DECODE_PRINTF(",");
2001ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
2002ece92f85SJason Jin srcval = fetch_data_word(srcoffset);
2003ece92f85SJason Jin DECODE_PRINTF("\n");
2004ece92f85SJason Jin TRACE_AND_STEP();
2005ece92f85SJason Jin *destreg = srcval;
2006ece92f85SJason Jin }
2007ece92f85SJason Jin } else { /* register to register */
2008ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2009ece92f85SJason Jin u32 *destreg, *srcreg;
2010ece92f85SJason Jin
2011ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
2012ece92f85SJason Jin DECODE_PRINTF(",");
2013ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
2014ece92f85SJason Jin DECODE_PRINTF("\n");
2015ece92f85SJason Jin TRACE_AND_STEP();
2016ece92f85SJason Jin *destreg = *srcreg;
2017ece92f85SJason Jin } else {
2018ece92f85SJason Jin u16 *destreg, *srcreg;
2019ece92f85SJason Jin
2020ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
2021ece92f85SJason Jin DECODE_PRINTF(",");
2022ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
2023ece92f85SJason Jin DECODE_PRINTF("\n");
2024ece92f85SJason Jin TRACE_AND_STEP();
2025ece92f85SJason Jin *destreg = *srcreg;
2026ece92f85SJason Jin }
2027ece92f85SJason Jin }
2028ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2029ece92f85SJason Jin END_OF_INSTR();
2030ece92f85SJason Jin }
2031ece92f85SJason Jin
2032ece92f85SJason Jin /****************************************************************************
2033ece92f85SJason Jin REMARKS:
2034ece92f85SJason Jin Handles opcode 0x8c
2035ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED (op1))2036ece92f85SJason Jin void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
2037ece92f85SJason Jin {
2038ece92f85SJason Jin int mod, rl, rh;
2039ece92f85SJason Jin u16 *destreg, *srcreg;
2040ece92f85SJason Jin uint destoffset;
2041ece92f85SJason Jin u16 destval;
2042ece92f85SJason Jin
2043ece92f85SJason Jin START_OF_INSTR();
2044ece92f85SJason Jin DECODE_PRINTF("MOV\t");
2045ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
2046ece92f85SJason Jin if (mod < 3) {
2047ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
2048ece92f85SJason Jin DECODE_PRINTF(",");
2049ece92f85SJason Jin srcreg = decode_rm_seg_register(rh);
2050ece92f85SJason Jin DECODE_PRINTF("\n");
2051ece92f85SJason Jin TRACE_AND_STEP();
2052ece92f85SJason Jin destval = *srcreg;
2053ece92f85SJason Jin store_data_word(destoffset, destval);
2054ece92f85SJason Jin } else { /* register to register */
2055ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
2056ece92f85SJason Jin DECODE_PRINTF(",");
2057ece92f85SJason Jin srcreg = decode_rm_seg_register(rh);
2058ece92f85SJason Jin DECODE_PRINTF("\n");
2059ece92f85SJason Jin TRACE_AND_STEP();
2060ece92f85SJason Jin *destreg = *srcreg;
2061ece92f85SJason Jin }
2062ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2063ece92f85SJason Jin END_OF_INSTR();
2064ece92f85SJason Jin }
2065ece92f85SJason Jin
2066ece92f85SJason Jin /****************************************************************************
2067ece92f85SJason Jin REMARKS:
2068ece92f85SJason Jin Handles opcode 0x8d
2069ece92f85SJason Jin ****************************************************************************/
x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED (op1))2070ece92f85SJason Jin void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
2071ece92f85SJason Jin {
2072ece92f85SJason Jin int mod, rl, rh;
2073ece92f85SJason Jin u16 *srcreg;
2074ece92f85SJason Jin uint destoffset;
2075ece92f85SJason Jin
2076ece92f85SJason Jin /*
2077ece92f85SJason Jin * TODO: Need to handle address size prefix!
2078ece92f85SJason Jin *
2079ece92f85SJason Jin * lea eax,[eax+ebx*2] ??
2080ece92f85SJason Jin */
2081ece92f85SJason Jin
2082ece92f85SJason Jin START_OF_INSTR();
2083ece92f85SJason Jin DECODE_PRINTF("LEA\t");
2084ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
2085ece92f85SJason Jin if (mod < 3) {
2086ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh);
2087ece92f85SJason Jin DECODE_PRINTF(",");
2088ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
2089ece92f85SJason Jin DECODE_PRINTF("\n");
2090ece92f85SJason Jin TRACE_AND_STEP();
2091ece92f85SJason Jin *srcreg = (u16)destoffset;
2092ece92f85SJason Jin }
2093ece92f85SJason Jin /* } else { undefined. Do nothing. } */
2094ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2095ece92f85SJason Jin END_OF_INSTR();
2096ece92f85SJason Jin }
2097ece92f85SJason Jin
2098ece92f85SJason Jin /****************************************************************************
2099ece92f85SJason Jin REMARKS:
2100ece92f85SJason Jin Handles opcode 0x8e
2101ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED (op1))2102ece92f85SJason Jin void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
2103ece92f85SJason Jin {
2104ece92f85SJason Jin int mod, rl, rh;
2105ece92f85SJason Jin u16 *destreg, *srcreg;
2106ece92f85SJason Jin uint srcoffset;
2107ece92f85SJason Jin u16 srcval;
2108ece92f85SJason Jin
2109ece92f85SJason Jin START_OF_INSTR();
2110ece92f85SJason Jin DECODE_PRINTF("MOV\t");
2111ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
2112ece92f85SJason Jin if (mod < 3) {
2113ece92f85SJason Jin destreg = decode_rm_seg_register(rh);
2114ece92f85SJason Jin DECODE_PRINTF(",");
2115ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
2116ece92f85SJason Jin srcval = fetch_data_word(srcoffset);
2117ece92f85SJason Jin DECODE_PRINTF("\n");
2118ece92f85SJason Jin TRACE_AND_STEP();
2119ece92f85SJason Jin *destreg = srcval;
2120ece92f85SJason Jin } else { /* register to register */
2121ece92f85SJason Jin destreg = decode_rm_seg_register(rh);
2122ece92f85SJason Jin DECODE_PRINTF(",");
2123ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
2124ece92f85SJason Jin DECODE_PRINTF("\n");
2125ece92f85SJason Jin TRACE_AND_STEP();
2126ece92f85SJason Jin *destreg = *srcreg;
2127ece92f85SJason Jin }
2128ece92f85SJason Jin /*
2129ece92f85SJason Jin * Clean up, and reset all the R_xSP pointers to the correct
2130ece92f85SJason Jin * locations. This is about 3x too much overhead (doing all the
2131ece92f85SJason Jin * segreg ptrs when only one is needed, but this instruction
2132ece92f85SJason Jin * *cannot* be that common, and this isn't too much work anyway.
2133ece92f85SJason Jin */
2134ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2135ece92f85SJason Jin END_OF_INSTR();
2136ece92f85SJason Jin }
2137ece92f85SJason Jin
2138ece92f85SJason Jin /****************************************************************************
2139ece92f85SJason Jin REMARKS:
2140ece92f85SJason Jin Handles opcode 0x8f
2141ece92f85SJason Jin ****************************************************************************/
x86emuOp_pop_RM(u8 X86EMU_UNUSED (op1))2142ece92f85SJason Jin void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
2143ece92f85SJason Jin {
2144ece92f85SJason Jin int mod, rl, rh;
2145ece92f85SJason Jin uint destoffset;
2146ece92f85SJason Jin
2147ece92f85SJason Jin START_OF_INSTR();
2148ece92f85SJason Jin DECODE_PRINTF("POP\t");
2149ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
2150ece92f85SJason Jin if (rh != 0) {
21518c6ec412SSimon Glass ERR_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
2152ece92f85SJason Jin HALT_SYS();
2153ece92f85SJason Jin }
2154ece92f85SJason Jin if (mod < 3) {
2155ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
2156ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2157ece92f85SJason Jin u32 destval;
2158ece92f85SJason Jin
2159ece92f85SJason Jin DECODE_PRINTF("\n");
2160ece92f85SJason Jin TRACE_AND_STEP();
2161ece92f85SJason Jin destval = pop_long();
2162ece92f85SJason Jin store_data_long(destoffset, destval);
2163ece92f85SJason Jin } else {
2164ece92f85SJason Jin u16 destval;
2165ece92f85SJason Jin
2166ece92f85SJason Jin DECODE_PRINTF("\n");
2167ece92f85SJason Jin TRACE_AND_STEP();
2168ece92f85SJason Jin destval = pop_word();
2169ece92f85SJason Jin store_data_word(destoffset, destval);
2170ece92f85SJason Jin }
2171ece92f85SJason Jin } else { /* register to register */
2172ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2173ece92f85SJason Jin u32 *destreg;
2174ece92f85SJason Jin
2175ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
2176ece92f85SJason Jin DECODE_PRINTF("\n");
2177ece92f85SJason Jin TRACE_AND_STEP();
2178ece92f85SJason Jin *destreg = pop_long();
2179ece92f85SJason Jin } else {
2180ece92f85SJason Jin u16 *destreg;
2181ece92f85SJason Jin
2182ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
2183ece92f85SJason Jin DECODE_PRINTF("\n");
2184ece92f85SJason Jin TRACE_AND_STEP();
2185ece92f85SJason Jin *destreg = pop_word();
2186ece92f85SJason Jin }
2187ece92f85SJason Jin }
2188ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2189ece92f85SJason Jin END_OF_INSTR();
2190ece92f85SJason Jin }
2191ece92f85SJason Jin
2192ece92f85SJason Jin /****************************************************************************
2193ece92f85SJason Jin REMARKS:
2194ece92f85SJason Jin Handles opcode 0x90
2195ece92f85SJason Jin ****************************************************************************/
x86emuOp_nop(u8 X86EMU_UNUSED (op1))2196ece92f85SJason Jin void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
2197ece92f85SJason Jin {
2198ece92f85SJason Jin START_OF_INSTR();
2199ece92f85SJason Jin DECODE_PRINTF("NOP\n");
2200ece92f85SJason Jin TRACE_AND_STEP();
2201ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2202ece92f85SJason Jin END_OF_INSTR();
2203ece92f85SJason Jin }
2204ece92f85SJason Jin
2205ece92f85SJason Jin /****************************************************************************
2206ece92f85SJason Jin REMARKS:
2207ece92f85SJason Jin Handles opcode 0x91-0x97
2208ece92f85SJason Jin ****************************************************************************/
x86emuOp_xchg_word_AX_register(u8 X86EMU_UNUSED (op1))2209ece92f85SJason Jin void x86emuOp_xchg_word_AX_register(u8 X86EMU_UNUSED(op1))
2210ece92f85SJason Jin {
2211ece92f85SJason Jin u32 tmp;
2212ece92f85SJason Jin
2213ece92f85SJason Jin op1 &= 0x7;
2214ece92f85SJason Jin
2215ece92f85SJason Jin START_OF_INSTR();
2216ece92f85SJason Jin
2217ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2218ece92f85SJason Jin u32 *reg32;
2219ece92f85SJason Jin DECODE_PRINTF("XCHG\tEAX,");
2220ece92f85SJason Jin reg32 = DECODE_RM_LONG_REGISTER(op1);
2221ece92f85SJason Jin DECODE_PRINTF("\n");
2222ece92f85SJason Jin TRACE_AND_STEP();
2223ece92f85SJason Jin tmp = M.x86.R_EAX;
2224ece92f85SJason Jin M.x86.R_EAX = *reg32;
2225ece92f85SJason Jin *reg32 = tmp;
2226ece92f85SJason Jin } else {
2227ece92f85SJason Jin u16 *reg16;
2228ece92f85SJason Jin DECODE_PRINTF("XCHG\tAX,");
2229ece92f85SJason Jin reg16 = DECODE_RM_WORD_REGISTER(op1);
2230ece92f85SJason Jin DECODE_PRINTF("\n");
2231ece92f85SJason Jin TRACE_AND_STEP();
2232ece92f85SJason Jin tmp = M.x86.R_AX;
2233ece92f85SJason Jin M.x86.R_EAX = *reg16;
2234ece92f85SJason Jin *reg16 = (u16)tmp;
2235ece92f85SJason Jin }
2236ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2237ece92f85SJason Jin END_OF_INSTR();
2238ece92f85SJason Jin }
2239ece92f85SJason Jin
2240ece92f85SJason Jin /****************************************************************************
2241ece92f85SJason Jin REMARKS:
2242ece92f85SJason Jin Handles opcode 0x98
2243ece92f85SJason Jin ****************************************************************************/
x86emuOp_cbw(u8 X86EMU_UNUSED (op1))2244ece92f85SJason Jin void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
2245ece92f85SJason Jin {
2246ece92f85SJason Jin START_OF_INSTR();
2247ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2248ece92f85SJason Jin DECODE_PRINTF("CWDE\n");
2249ece92f85SJason Jin } else {
2250ece92f85SJason Jin DECODE_PRINTF("CBW\n");
2251ece92f85SJason Jin }
2252ece92f85SJason Jin TRACE_AND_STEP();
2253ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2254ece92f85SJason Jin if (M.x86.R_AX & 0x8000) {
2255ece92f85SJason Jin M.x86.R_EAX |= 0xffff0000;
2256ece92f85SJason Jin } else {
2257ece92f85SJason Jin M.x86.R_EAX &= 0x0000ffff;
2258ece92f85SJason Jin }
2259ece92f85SJason Jin } else {
2260ece92f85SJason Jin if (M.x86.R_AL & 0x80) {
2261ece92f85SJason Jin M.x86.R_AH = 0xff;
2262ece92f85SJason Jin } else {
2263ece92f85SJason Jin M.x86.R_AH = 0x0;
2264ece92f85SJason Jin }
2265ece92f85SJason Jin }
2266ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2267ece92f85SJason Jin END_OF_INSTR();
2268ece92f85SJason Jin }
2269ece92f85SJason Jin
2270ece92f85SJason Jin /****************************************************************************
2271ece92f85SJason Jin REMARKS:
2272ece92f85SJason Jin Handles opcode 0x99
2273ece92f85SJason Jin ****************************************************************************/
x86emuOp_cwd(u8 X86EMU_UNUSED (op1))2274ece92f85SJason Jin void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
2275ece92f85SJason Jin {
2276ece92f85SJason Jin START_OF_INSTR();
2277ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2278ece92f85SJason Jin DECODE_PRINTF("CDQ\n");
2279ece92f85SJason Jin } else {
2280ece92f85SJason Jin DECODE_PRINTF("CWD\n");
2281ece92f85SJason Jin }
2282ece92f85SJason Jin DECODE_PRINTF("CWD\n");
2283ece92f85SJason Jin TRACE_AND_STEP();
2284ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2285ece92f85SJason Jin if (M.x86.R_EAX & 0x80000000) {
2286ece92f85SJason Jin M.x86.R_EDX = 0xffffffff;
2287ece92f85SJason Jin } else {
2288ece92f85SJason Jin M.x86.R_EDX = 0x0;
2289ece92f85SJason Jin }
2290ece92f85SJason Jin } else {
2291ece92f85SJason Jin if (M.x86.R_AX & 0x8000) {
2292ece92f85SJason Jin M.x86.R_DX = 0xffff;
2293ece92f85SJason Jin } else {
2294ece92f85SJason Jin M.x86.R_DX = 0x0;
2295ece92f85SJason Jin }
2296ece92f85SJason Jin }
2297ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2298ece92f85SJason Jin END_OF_INSTR();
2299ece92f85SJason Jin }
2300ece92f85SJason Jin
2301ece92f85SJason Jin /****************************************************************************
2302ece92f85SJason Jin REMARKS:
2303ece92f85SJason Jin Handles opcode 0x9a
2304ece92f85SJason Jin ****************************************************************************/
x86emuOp_call_far_IMM(u8 X86EMU_UNUSED (op1))2305ece92f85SJason Jin void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
2306ece92f85SJason Jin {
2307ece92f85SJason Jin u16 farseg, faroff;
2308ece92f85SJason Jin
2309ece92f85SJason Jin START_OF_INSTR();
2310ece92f85SJason Jin DECODE_PRINTF("CALL\t");
2311ece92f85SJason Jin faroff = fetch_word_imm();
2312ece92f85SJason Jin farseg = fetch_word_imm();
2313ece92f85SJason Jin DECODE_PRINTF2("%04x:", farseg);
2314ece92f85SJason Jin DECODE_PRINTF2("%04x\n", faroff);
2315ece92f85SJason Jin CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
2316ece92f85SJason Jin
2317ece92f85SJason Jin /* XXX
2318ece92f85SJason Jin *
2319ece92f85SJason Jin * Hooked interrupt vectors calling into our "BIOS" will cause
2320ece92f85SJason Jin * problems unless all intersegment stuff is checked for BIOS
2321ece92f85SJason Jin * access. Check needed here. For moment, let it alone.
2322ece92f85SJason Jin */
2323ece92f85SJason Jin TRACE_AND_STEP();
2324ece92f85SJason Jin push_word(M.x86.R_CS);
2325ece92f85SJason Jin M.x86.R_CS = farseg;
2326ece92f85SJason Jin push_word(M.x86.R_IP);
2327ece92f85SJason Jin M.x86.R_IP = faroff;
2328ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2329ece92f85SJason Jin END_OF_INSTR();
2330ece92f85SJason Jin }
2331ece92f85SJason Jin
2332ece92f85SJason Jin /****************************************************************************
2333ece92f85SJason Jin REMARKS:
2334ece92f85SJason Jin Handles opcode 0x9b
2335ece92f85SJason Jin ****************************************************************************/
x86emuOp_wait(u8 X86EMU_UNUSED (op1))2336ece92f85SJason Jin void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
2337ece92f85SJason Jin {
2338ece92f85SJason Jin START_OF_INSTR();
2339ece92f85SJason Jin DECODE_PRINTF("WAIT");
2340ece92f85SJason Jin TRACE_AND_STEP();
2341ece92f85SJason Jin /* NADA. */
2342ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2343ece92f85SJason Jin END_OF_INSTR();
2344ece92f85SJason Jin }
2345ece92f85SJason Jin
2346ece92f85SJason Jin /****************************************************************************
2347ece92f85SJason Jin REMARKS:
2348ece92f85SJason Jin Handles opcode 0x9c
2349ece92f85SJason Jin ****************************************************************************/
x86emuOp_pushf_word(u8 X86EMU_UNUSED (op1))2350ece92f85SJason Jin void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
2351ece92f85SJason Jin {
2352ece92f85SJason Jin u32 flags;
2353ece92f85SJason Jin
2354ece92f85SJason Jin START_OF_INSTR();
2355ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2356ece92f85SJason Jin DECODE_PRINTF("PUSHFD\n");
2357ece92f85SJason Jin } else {
2358ece92f85SJason Jin DECODE_PRINTF("PUSHF\n");
2359ece92f85SJason Jin }
2360ece92f85SJason Jin TRACE_AND_STEP();
2361ece92f85SJason Jin
2362ece92f85SJason Jin /* clear out *all* bits not representing flags, and turn on real bits */
2363ece92f85SJason Jin flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
2364ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2365ece92f85SJason Jin push_long(flags);
2366ece92f85SJason Jin } else {
2367ece92f85SJason Jin push_word((u16)flags);
2368ece92f85SJason Jin }
2369ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2370ece92f85SJason Jin END_OF_INSTR();
2371ece92f85SJason Jin }
2372ece92f85SJason Jin
2373ece92f85SJason Jin /****************************************************************************
2374ece92f85SJason Jin REMARKS:
2375ece92f85SJason Jin Handles opcode 0x9d
2376ece92f85SJason Jin ****************************************************************************/
x86emuOp_popf_word(u8 X86EMU_UNUSED (op1))2377ece92f85SJason Jin void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
2378ece92f85SJason Jin {
2379ece92f85SJason Jin START_OF_INSTR();
2380ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2381ece92f85SJason Jin DECODE_PRINTF("POPFD\n");
2382ece92f85SJason Jin } else {
2383ece92f85SJason Jin DECODE_PRINTF("POPF\n");
2384ece92f85SJason Jin }
2385ece92f85SJason Jin TRACE_AND_STEP();
2386ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2387ece92f85SJason Jin M.x86.R_EFLG = pop_long();
2388ece92f85SJason Jin } else {
2389ece92f85SJason Jin M.x86.R_FLG = pop_word();
2390ece92f85SJason Jin }
2391ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2392ece92f85SJason Jin END_OF_INSTR();
2393ece92f85SJason Jin }
2394ece92f85SJason Jin
2395ece92f85SJason Jin /****************************************************************************
2396ece92f85SJason Jin REMARKS:
2397ece92f85SJason Jin Handles opcode 0x9e
2398ece92f85SJason Jin ****************************************************************************/
x86emuOp_sahf(u8 X86EMU_UNUSED (op1))2399ece92f85SJason Jin void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
2400ece92f85SJason Jin {
2401ece92f85SJason Jin START_OF_INSTR();
2402ece92f85SJason Jin DECODE_PRINTF("SAHF\n");
2403ece92f85SJason Jin TRACE_AND_STEP();
2404ece92f85SJason Jin /* clear the lower bits of the flag register */
2405ece92f85SJason Jin M.x86.R_FLG &= 0xffffff00;
2406ece92f85SJason Jin /* or in the AH register into the flags register */
2407ece92f85SJason Jin M.x86.R_FLG |= M.x86.R_AH;
2408ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2409ece92f85SJason Jin END_OF_INSTR();
2410ece92f85SJason Jin }
2411ece92f85SJason Jin
2412ece92f85SJason Jin /****************************************************************************
2413ece92f85SJason Jin REMARKS:
2414ece92f85SJason Jin Handles opcode 0x9f
2415ece92f85SJason Jin ****************************************************************************/
x86emuOp_lahf(u8 X86EMU_UNUSED (op1))2416ece92f85SJason Jin void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
2417ece92f85SJason Jin {
2418ece92f85SJason Jin START_OF_INSTR();
2419ece92f85SJason Jin DECODE_PRINTF("LAHF\n");
2420ece92f85SJason Jin TRACE_AND_STEP();
2421ece92f85SJason Jin M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
2422ece92f85SJason Jin /*undocumented TC++ behavior??? Nope. It's documented, but
2423ece92f85SJason Jin you have too look real hard to notice it. */
2424ece92f85SJason Jin M.x86.R_AH |= 0x2;
2425ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2426ece92f85SJason Jin END_OF_INSTR();
2427ece92f85SJason Jin }
2428ece92f85SJason Jin
2429ece92f85SJason Jin /****************************************************************************
2430ece92f85SJason Jin REMARKS:
2431ece92f85SJason Jin Handles opcode 0xa0
2432ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED (op1))2433ece92f85SJason Jin void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
2434ece92f85SJason Jin {
2435ece92f85SJason Jin u16 offset;
2436ece92f85SJason Jin
2437ece92f85SJason Jin START_OF_INSTR();
2438ece92f85SJason Jin DECODE_PRINTF("MOV\tAL,");
2439ece92f85SJason Jin offset = fetch_word_imm();
2440ece92f85SJason Jin DECODE_PRINTF2("[%04x]\n", offset);
2441ece92f85SJason Jin TRACE_AND_STEP();
2442ece92f85SJason Jin M.x86.R_AL = fetch_data_byte(offset);
2443ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2444ece92f85SJason Jin END_OF_INSTR();
2445ece92f85SJason Jin }
2446ece92f85SJason Jin
2447ece92f85SJason Jin /****************************************************************************
2448ece92f85SJason Jin REMARKS:
2449ece92f85SJason Jin Handles opcode 0xa1
2450ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED (op1))2451ece92f85SJason Jin void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
2452ece92f85SJason Jin {
2453ece92f85SJason Jin u16 offset;
2454ece92f85SJason Jin
2455ece92f85SJason Jin START_OF_INSTR();
2456ece92f85SJason Jin offset = fetch_word_imm();
2457ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2458ece92f85SJason Jin DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
2459ece92f85SJason Jin } else {
2460ece92f85SJason Jin DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
2461ece92f85SJason Jin }
2462ece92f85SJason Jin TRACE_AND_STEP();
2463ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2464ece92f85SJason Jin M.x86.R_EAX = fetch_data_long(offset);
2465ece92f85SJason Jin } else {
2466ece92f85SJason Jin M.x86.R_AX = fetch_data_word(offset);
2467ece92f85SJason Jin }
2468ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2469ece92f85SJason Jin END_OF_INSTR();
2470ece92f85SJason Jin }
2471ece92f85SJason Jin
2472ece92f85SJason Jin /****************************************************************************
2473ece92f85SJason Jin REMARKS:
2474ece92f85SJason Jin Handles opcode 0xa2
2475ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED (op1))2476ece92f85SJason Jin void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
2477ece92f85SJason Jin {
2478ece92f85SJason Jin u16 offset;
2479ece92f85SJason Jin
2480ece92f85SJason Jin START_OF_INSTR();
2481ece92f85SJason Jin DECODE_PRINTF("MOV\t");
2482ece92f85SJason Jin offset = fetch_word_imm();
2483ece92f85SJason Jin DECODE_PRINTF2("[%04x],AL\n", offset);
2484ece92f85SJason Jin TRACE_AND_STEP();
2485ece92f85SJason Jin store_data_byte(offset, M.x86.R_AL);
2486ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2487ece92f85SJason Jin END_OF_INSTR();
2488ece92f85SJason Jin }
2489ece92f85SJason Jin
2490ece92f85SJason Jin /****************************************************************************
2491ece92f85SJason Jin REMARKS:
2492ece92f85SJason Jin Handles opcode 0xa3
2493ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED (op1))2494ece92f85SJason Jin void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
2495ece92f85SJason Jin {
2496ece92f85SJason Jin u16 offset;
2497ece92f85SJason Jin
2498ece92f85SJason Jin START_OF_INSTR();
2499ece92f85SJason Jin offset = fetch_word_imm();
2500ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2501ece92f85SJason Jin DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
2502ece92f85SJason Jin } else {
2503ece92f85SJason Jin DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
2504ece92f85SJason Jin }
2505ece92f85SJason Jin TRACE_AND_STEP();
2506ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2507ece92f85SJason Jin store_data_long(offset, M.x86.R_EAX);
2508ece92f85SJason Jin } else {
2509ece92f85SJason Jin store_data_word(offset, M.x86.R_AX);
2510ece92f85SJason Jin }
2511ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2512ece92f85SJason Jin END_OF_INSTR();
2513ece92f85SJason Jin }
2514ece92f85SJason Jin
2515ece92f85SJason Jin /****************************************************************************
2516ece92f85SJason Jin REMARKS:
2517ece92f85SJason Jin Handles opcode 0xa4
2518ece92f85SJason Jin ****************************************************************************/
x86emuOp_movs_byte(u8 X86EMU_UNUSED (op1))2519ece92f85SJason Jin void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
2520ece92f85SJason Jin {
2521ece92f85SJason Jin u8 val;
2522ece92f85SJason Jin u32 count;
2523ece92f85SJason Jin int inc;
2524ece92f85SJason Jin
2525ece92f85SJason Jin START_OF_INSTR();
2526ece92f85SJason Jin DECODE_PRINTF("MOVS\tBYTE\n");
2527ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2528ece92f85SJason Jin inc = -1;
2529ece92f85SJason Jin else
2530ece92f85SJason Jin inc = 1;
2531ece92f85SJason Jin TRACE_AND_STEP();
2532ece92f85SJason Jin count = 1;
2533ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2534ece92f85SJason Jin /* dont care whether REPE or REPNE */
2535ece92f85SJason Jin /* move them until CX is ZERO. */
2536ece92f85SJason Jin count = M.x86.R_CX;
2537ece92f85SJason Jin M.x86.R_CX = 0;
2538ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2539ece92f85SJason Jin }
2540ece92f85SJason Jin while (count--) {
2541ece92f85SJason Jin val = fetch_data_byte(M.x86.R_SI);
2542ece92f85SJason Jin store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
2543ece92f85SJason Jin M.x86.R_SI += inc;
2544ece92f85SJason Jin M.x86.R_DI += inc;
2545ece92f85SJason Jin }
2546ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2547ece92f85SJason Jin END_OF_INSTR();
2548ece92f85SJason Jin }
2549ece92f85SJason Jin
2550ece92f85SJason Jin /****************************************************************************
2551ece92f85SJason Jin REMARKS:
2552ece92f85SJason Jin Handles opcode 0xa5
2553ece92f85SJason Jin ****************************************************************************/
x86emuOp_movs_word(u8 X86EMU_UNUSED (op1))2554ece92f85SJason Jin void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
2555ece92f85SJason Jin {
2556ece92f85SJason Jin u32 val;
2557ece92f85SJason Jin int inc;
2558ece92f85SJason Jin u32 count;
2559ece92f85SJason Jin
2560ece92f85SJason Jin START_OF_INSTR();
2561ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2562ece92f85SJason Jin DECODE_PRINTF("MOVS\tDWORD\n");
2563ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2564ece92f85SJason Jin inc = -4;
2565ece92f85SJason Jin else
2566ece92f85SJason Jin inc = 4;
2567ece92f85SJason Jin } else {
2568ece92f85SJason Jin DECODE_PRINTF("MOVS\tWORD\n");
2569ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2570ece92f85SJason Jin inc = -2;
2571ece92f85SJason Jin else
2572ece92f85SJason Jin inc = 2;
2573ece92f85SJason Jin }
2574ece92f85SJason Jin TRACE_AND_STEP();
2575ece92f85SJason Jin count = 1;
2576ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2577ece92f85SJason Jin /* dont care whether REPE or REPNE */
2578ece92f85SJason Jin /* move them until CX is ZERO. */
2579ece92f85SJason Jin count = M.x86.R_CX;
2580ece92f85SJason Jin M.x86.R_CX = 0;
2581ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2582ece92f85SJason Jin }
2583ece92f85SJason Jin while (count--) {
2584ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2585ece92f85SJason Jin val = fetch_data_long(M.x86.R_SI);
2586ece92f85SJason Jin store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
2587ece92f85SJason Jin } else {
2588ece92f85SJason Jin val = fetch_data_word(M.x86.R_SI);
2589ece92f85SJason Jin store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
2590ece92f85SJason Jin }
2591ece92f85SJason Jin M.x86.R_SI += inc;
2592ece92f85SJason Jin M.x86.R_DI += inc;
2593ece92f85SJason Jin }
2594ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2595ece92f85SJason Jin END_OF_INSTR();
2596ece92f85SJason Jin }
2597ece92f85SJason Jin
2598ece92f85SJason Jin /****************************************************************************
2599ece92f85SJason Jin REMARKS:
2600ece92f85SJason Jin Handles opcode 0xa6
2601ece92f85SJason Jin ****************************************************************************/
x86emuOp_cmps_byte(u8 X86EMU_UNUSED (op1))2602ece92f85SJason Jin void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
2603ece92f85SJason Jin {
2604ece92f85SJason Jin s8 val1, val2;
2605ece92f85SJason Jin int inc;
2606ece92f85SJason Jin
2607ece92f85SJason Jin START_OF_INSTR();
2608ece92f85SJason Jin DECODE_PRINTF("CMPS\tBYTE\n");
2609ece92f85SJason Jin TRACE_AND_STEP();
2610ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2611ece92f85SJason Jin inc = -1;
2612ece92f85SJason Jin else
2613ece92f85SJason Jin inc = 1;
2614ece92f85SJason Jin
2615ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2616ece92f85SJason Jin /* REPE */
2617ece92f85SJason Jin /* move them until CX is ZERO. */
2618ece92f85SJason Jin while (M.x86.R_CX != 0) {
2619ece92f85SJason Jin val1 = fetch_data_byte(M.x86.R_SI);
2620ece92f85SJason Jin val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2621ece92f85SJason Jin cmp_byte(val1, val2);
2622ece92f85SJason Jin M.x86.R_CX -= 1;
2623ece92f85SJason Jin M.x86.R_SI += inc;
2624ece92f85SJason Jin M.x86.R_DI += inc;
2625ece92f85SJason Jin if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && (ACCESS_FLAG(F_ZF) == 0) ) break;
2626ece92f85SJason Jin if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
2627ece92f85SJason Jin }
2628ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2629ece92f85SJason Jin } else {
2630ece92f85SJason Jin val1 = fetch_data_byte(M.x86.R_SI);
2631ece92f85SJason Jin val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2632ece92f85SJason Jin cmp_byte(val1, val2);
2633ece92f85SJason Jin M.x86.R_SI += inc;
2634ece92f85SJason Jin M.x86.R_DI += inc;
2635ece92f85SJason Jin }
2636ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2637ece92f85SJason Jin END_OF_INSTR();
2638ece92f85SJason Jin }
2639ece92f85SJason Jin
2640ece92f85SJason Jin /****************************************************************************
2641ece92f85SJason Jin REMARKS:
2642ece92f85SJason Jin Handles opcode 0xa7
2643ece92f85SJason Jin ****************************************************************************/
x86emuOp_cmps_word(u8 X86EMU_UNUSED (op1))2644ece92f85SJason Jin void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
2645ece92f85SJason Jin {
2646ece92f85SJason Jin u32 val1,val2;
2647ece92f85SJason Jin int inc;
2648ece92f85SJason Jin
2649ece92f85SJason Jin START_OF_INSTR();
2650ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2651ece92f85SJason Jin DECODE_PRINTF("CMPS\tDWORD\n");
2652ece92f85SJason Jin inc = 4;
2653ece92f85SJason Jin } else {
2654ece92f85SJason Jin DECODE_PRINTF("CMPS\tWORD\n");
2655ece92f85SJason Jin inc = 2;
2656ece92f85SJason Jin }
2657ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2658ece92f85SJason Jin inc = -inc;
2659ece92f85SJason Jin
2660ece92f85SJason Jin TRACE_AND_STEP();
2661ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2662ece92f85SJason Jin /* REPE */
2663ece92f85SJason Jin /* move them until CX is ZERO. */
2664ece92f85SJason Jin while (M.x86.R_CX != 0) {
2665ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2666ece92f85SJason Jin val1 = fetch_data_long(M.x86.R_SI);
2667ece92f85SJason Jin val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2668ece92f85SJason Jin cmp_long(val1, val2);
2669ece92f85SJason Jin } else {
2670ece92f85SJason Jin val1 = fetch_data_word(M.x86.R_SI);
2671ece92f85SJason Jin val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2672ece92f85SJason Jin cmp_word((u16)val1, (u16)val2);
2673ece92f85SJason Jin }
2674ece92f85SJason Jin M.x86.R_CX -= 1;
2675ece92f85SJason Jin M.x86.R_SI += inc;
2676ece92f85SJason Jin M.x86.R_DI += inc;
2677ece92f85SJason Jin if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && ACCESS_FLAG(F_ZF) == 0 ) break;
2678ece92f85SJason Jin if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
2679ece92f85SJason Jin }
2680ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2681ece92f85SJason Jin } else {
2682ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2683ece92f85SJason Jin val1 = fetch_data_long(M.x86.R_SI);
2684ece92f85SJason Jin val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2685ece92f85SJason Jin cmp_long(val1, val2);
2686ece92f85SJason Jin } else {
2687ece92f85SJason Jin val1 = fetch_data_word(M.x86.R_SI);
2688ece92f85SJason Jin val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2689ece92f85SJason Jin cmp_word((u16)val1, (u16)val2);
2690ece92f85SJason Jin }
2691ece92f85SJason Jin M.x86.R_SI += inc;
2692ece92f85SJason Jin M.x86.R_DI += inc;
2693ece92f85SJason Jin }
2694ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2695ece92f85SJason Jin END_OF_INSTR();
2696ece92f85SJason Jin }
2697ece92f85SJason Jin
2698ece92f85SJason Jin /****************************************************************************
2699ece92f85SJason Jin REMARKS:
2700ece92f85SJason Jin Handles opcode 0xa8
2701ece92f85SJason Jin ****************************************************************************/
x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED (op1))2702ece92f85SJason Jin void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
2703ece92f85SJason Jin {
2704ece92f85SJason Jin int imm;
2705ece92f85SJason Jin
2706ece92f85SJason Jin START_OF_INSTR();
2707ece92f85SJason Jin DECODE_PRINTF("TEST\tAL,");
2708ece92f85SJason Jin imm = fetch_byte_imm();
2709ece92f85SJason Jin DECODE_PRINTF2("%04x\n", imm);
2710ece92f85SJason Jin TRACE_AND_STEP();
2711ece92f85SJason Jin test_byte(M.x86.R_AL, (u8)imm);
2712ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2713ece92f85SJason Jin END_OF_INSTR();
2714ece92f85SJason Jin }
2715ece92f85SJason Jin
2716ece92f85SJason Jin /****************************************************************************
2717ece92f85SJason Jin REMARKS:
2718ece92f85SJason Jin Handles opcode 0xa9
2719ece92f85SJason Jin ****************************************************************************/
x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED (op1))2720ece92f85SJason Jin void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
2721ece92f85SJason Jin {
2722ece92f85SJason Jin u32 srcval;
2723ece92f85SJason Jin
2724ece92f85SJason Jin START_OF_INSTR();
2725ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2726ece92f85SJason Jin DECODE_PRINTF("TEST\tEAX,");
2727ece92f85SJason Jin srcval = fetch_long_imm();
2728ece92f85SJason Jin } else {
2729ece92f85SJason Jin DECODE_PRINTF("TEST\tAX,");
2730ece92f85SJason Jin srcval = fetch_word_imm();
2731ece92f85SJason Jin }
2732ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval);
2733ece92f85SJason Jin TRACE_AND_STEP();
2734ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2735ece92f85SJason Jin test_long(M.x86.R_EAX, srcval);
2736ece92f85SJason Jin } else {
2737ece92f85SJason Jin test_word(M.x86.R_AX, (u16)srcval);
2738ece92f85SJason Jin }
2739ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2740ece92f85SJason Jin END_OF_INSTR();
2741ece92f85SJason Jin }
2742ece92f85SJason Jin
2743ece92f85SJason Jin /****************************************************************************
2744ece92f85SJason Jin REMARKS:
2745ece92f85SJason Jin Handles opcode 0xaa
2746ece92f85SJason Jin ****************************************************************************/
x86emuOp_stos_byte(u8 X86EMU_UNUSED (op1))2747ece92f85SJason Jin void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
2748ece92f85SJason Jin {
2749ece92f85SJason Jin int inc;
2750ece92f85SJason Jin
2751ece92f85SJason Jin START_OF_INSTR();
2752ece92f85SJason Jin DECODE_PRINTF("STOS\tBYTE\n");
2753ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2754ece92f85SJason Jin inc = -1;
2755ece92f85SJason Jin else
2756ece92f85SJason Jin inc = 1;
2757ece92f85SJason Jin TRACE_AND_STEP();
2758ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2759ece92f85SJason Jin /* dont care whether REPE or REPNE */
2760ece92f85SJason Jin /* move them until CX is ZERO. */
2761ece92f85SJason Jin while (M.x86.R_CX != 0) {
2762ece92f85SJason Jin store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
2763ece92f85SJason Jin M.x86.R_CX -= 1;
2764ece92f85SJason Jin M.x86.R_DI += inc;
2765ece92f85SJason Jin }
2766ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2767ece92f85SJason Jin } else {
2768ece92f85SJason Jin store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
2769ece92f85SJason Jin M.x86.R_DI += inc;
2770ece92f85SJason Jin }
2771ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2772ece92f85SJason Jin END_OF_INSTR();
2773ece92f85SJason Jin }
2774ece92f85SJason Jin
2775ece92f85SJason Jin /****************************************************************************
2776ece92f85SJason Jin REMARKS:
2777ece92f85SJason Jin Handles opcode 0xab
2778ece92f85SJason Jin ****************************************************************************/
x86emuOp_stos_word(u8 X86EMU_UNUSED (op1))2779ece92f85SJason Jin void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
2780ece92f85SJason Jin {
2781ece92f85SJason Jin int inc;
2782ece92f85SJason Jin u32 count;
2783ece92f85SJason Jin
2784ece92f85SJason Jin START_OF_INSTR();
2785ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2786ece92f85SJason Jin DECODE_PRINTF("STOS\tDWORD\n");
2787ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2788ece92f85SJason Jin inc = -4;
2789ece92f85SJason Jin else
2790ece92f85SJason Jin inc = 4;
2791ece92f85SJason Jin } else {
2792ece92f85SJason Jin DECODE_PRINTF("STOS\tWORD\n");
2793ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2794ece92f85SJason Jin inc = -2;
2795ece92f85SJason Jin else
2796ece92f85SJason Jin inc = 2;
2797ece92f85SJason Jin }
2798ece92f85SJason Jin TRACE_AND_STEP();
2799ece92f85SJason Jin count = 1;
2800ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2801ece92f85SJason Jin /* dont care whether REPE or REPNE */
2802ece92f85SJason Jin /* move them until CX is ZERO. */
2803ece92f85SJason Jin count = M.x86.R_CX;
2804ece92f85SJason Jin M.x86.R_CX = 0;
2805ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2806ece92f85SJason Jin }
2807ece92f85SJason Jin while (count--) {
2808ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2809ece92f85SJason Jin store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
2810ece92f85SJason Jin } else {
2811ece92f85SJason Jin store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
2812ece92f85SJason Jin }
2813ece92f85SJason Jin M.x86.R_DI += inc;
2814ece92f85SJason Jin }
2815ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2816ece92f85SJason Jin END_OF_INSTR();
2817ece92f85SJason Jin }
2818ece92f85SJason Jin
2819ece92f85SJason Jin /****************************************************************************
2820ece92f85SJason Jin REMARKS:
2821ece92f85SJason Jin Handles opcode 0xac
2822ece92f85SJason Jin ****************************************************************************/
x86emuOp_lods_byte(u8 X86EMU_UNUSED (op1))2823ece92f85SJason Jin void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
2824ece92f85SJason Jin {
2825ece92f85SJason Jin int inc;
2826ece92f85SJason Jin
2827ece92f85SJason Jin START_OF_INSTR();
2828ece92f85SJason Jin DECODE_PRINTF("LODS\tBYTE\n");
2829ece92f85SJason Jin TRACE_AND_STEP();
2830ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2831ece92f85SJason Jin inc = -1;
2832ece92f85SJason Jin else
2833ece92f85SJason Jin inc = 1;
2834ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2835ece92f85SJason Jin /* dont care whether REPE or REPNE */
2836ece92f85SJason Jin /* move them until CX is ZERO. */
2837ece92f85SJason Jin while (M.x86.R_CX != 0) {
2838ece92f85SJason Jin M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
2839ece92f85SJason Jin M.x86.R_CX -= 1;
2840ece92f85SJason Jin M.x86.R_SI += inc;
2841ece92f85SJason Jin }
2842ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2843ece92f85SJason Jin } else {
2844ece92f85SJason Jin M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
2845ece92f85SJason Jin M.x86.R_SI += inc;
2846ece92f85SJason Jin }
2847ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2848ece92f85SJason Jin END_OF_INSTR();
2849ece92f85SJason Jin }
2850ece92f85SJason Jin
2851ece92f85SJason Jin /****************************************************************************
2852ece92f85SJason Jin REMARKS:
2853ece92f85SJason Jin Handles opcode 0xad
2854ece92f85SJason Jin ****************************************************************************/
x86emuOp_lods_word(u8 X86EMU_UNUSED (op1))2855ece92f85SJason Jin void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
2856ece92f85SJason Jin {
2857ece92f85SJason Jin int inc;
2858ece92f85SJason Jin u32 count;
2859ece92f85SJason Jin
2860ece92f85SJason Jin START_OF_INSTR();
2861ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2862ece92f85SJason Jin DECODE_PRINTF("LODS\tDWORD\n");
2863ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2864ece92f85SJason Jin inc = -4;
2865ece92f85SJason Jin else
2866ece92f85SJason Jin inc = 4;
2867ece92f85SJason Jin } else {
2868ece92f85SJason Jin DECODE_PRINTF("LODS\tWORD\n");
2869ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2870ece92f85SJason Jin inc = -2;
2871ece92f85SJason Jin else
2872ece92f85SJason Jin inc = 2;
2873ece92f85SJason Jin }
2874ece92f85SJason Jin TRACE_AND_STEP();
2875ece92f85SJason Jin count = 1;
2876ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2877ece92f85SJason Jin /* dont care whether REPE or REPNE */
2878ece92f85SJason Jin /* move them until CX is ZERO. */
2879ece92f85SJason Jin count = M.x86.R_CX;
2880ece92f85SJason Jin M.x86.R_CX = 0;
2881ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2882ece92f85SJason Jin }
2883ece92f85SJason Jin while (count--) {
2884ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2885ece92f85SJason Jin M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
2886ece92f85SJason Jin } else {
2887ece92f85SJason Jin M.x86.R_AX = fetch_data_word(M.x86.R_SI);
2888ece92f85SJason Jin }
2889ece92f85SJason Jin M.x86.R_SI += inc;
2890ece92f85SJason Jin }
2891ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2892ece92f85SJason Jin END_OF_INSTR();
2893ece92f85SJason Jin }
2894ece92f85SJason Jin
2895ece92f85SJason Jin /****************************************************************************
2896ece92f85SJason Jin REMARKS:
2897ece92f85SJason Jin Handles opcode 0xae
2898ece92f85SJason Jin ****************************************************************************/
x86emuOp_scas_byte(u8 X86EMU_UNUSED (op1))2899ece92f85SJason Jin void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
2900ece92f85SJason Jin {
2901ece92f85SJason Jin s8 val2;
2902ece92f85SJason Jin int inc;
2903ece92f85SJason Jin
2904ece92f85SJason Jin START_OF_INSTR();
2905ece92f85SJason Jin DECODE_PRINTF("SCAS\tBYTE\n");
2906ece92f85SJason Jin TRACE_AND_STEP();
2907ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2908ece92f85SJason Jin inc = -1;
2909ece92f85SJason Jin else
2910ece92f85SJason Jin inc = 1;
2911ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_REPE) {
2912ece92f85SJason Jin /* REPE */
2913ece92f85SJason Jin /* move them until CX is ZERO. */
2914ece92f85SJason Jin while (M.x86.R_CX != 0) {
2915ece92f85SJason Jin val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2916ece92f85SJason Jin cmp_byte(M.x86.R_AL, val2);
2917ece92f85SJason Jin M.x86.R_CX -= 1;
2918ece92f85SJason Jin M.x86.R_DI += inc;
2919ece92f85SJason Jin if (ACCESS_FLAG(F_ZF) == 0)
2920ece92f85SJason Jin break;
2921ece92f85SJason Jin }
2922ece92f85SJason Jin M.x86.mode &= ~SYSMODE_PREFIX_REPE;
2923ece92f85SJason Jin } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
2924ece92f85SJason Jin /* REPNE */
2925ece92f85SJason Jin /* move them until CX is ZERO. */
2926ece92f85SJason Jin while (M.x86.R_CX != 0) {
2927ece92f85SJason Jin val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2928ece92f85SJason Jin cmp_byte(M.x86.R_AL, val2);
2929ece92f85SJason Jin M.x86.R_CX -= 1;
2930ece92f85SJason Jin M.x86.R_DI += inc;
2931ece92f85SJason Jin if (ACCESS_FLAG(F_ZF))
2932ece92f85SJason Jin break; /* zero flag set means equal */
2933ece92f85SJason Jin }
2934ece92f85SJason Jin M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
2935ece92f85SJason Jin } else {
2936ece92f85SJason Jin val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2937ece92f85SJason Jin cmp_byte(M.x86.R_AL, val2);
2938ece92f85SJason Jin M.x86.R_DI += inc;
2939ece92f85SJason Jin }
2940ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
2941ece92f85SJason Jin END_OF_INSTR();
2942ece92f85SJason Jin }
2943ece92f85SJason Jin
2944ece92f85SJason Jin /****************************************************************************
2945ece92f85SJason Jin REMARKS:
2946ece92f85SJason Jin Handles opcode 0xaf
2947ece92f85SJason Jin ****************************************************************************/
x86emuOp_scas_word(u8 X86EMU_UNUSED (op1))2948ece92f85SJason Jin void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
2949ece92f85SJason Jin {
2950ece92f85SJason Jin int inc;
2951ece92f85SJason Jin u32 val;
2952ece92f85SJason Jin
2953ece92f85SJason Jin START_OF_INSTR();
2954ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2955ece92f85SJason Jin DECODE_PRINTF("SCAS\tDWORD\n");
2956ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2957ece92f85SJason Jin inc = -4;
2958ece92f85SJason Jin else
2959ece92f85SJason Jin inc = 4;
2960ece92f85SJason Jin } else {
2961ece92f85SJason Jin DECODE_PRINTF("SCAS\tWORD\n");
2962ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */
2963ece92f85SJason Jin inc = -2;
2964ece92f85SJason Jin else
2965ece92f85SJason Jin inc = 2;
2966ece92f85SJason Jin }
2967ece92f85SJason Jin TRACE_AND_STEP();
2968ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_REPE) {
2969ece92f85SJason Jin /* REPE */
2970ece92f85SJason Jin /* move them until CX is ZERO. */
2971ece92f85SJason Jin while (M.x86.R_CX != 0) {
2972ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2973ece92f85SJason Jin val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2974ece92f85SJason Jin cmp_long(M.x86.R_EAX, val);
2975ece92f85SJason Jin } else {
2976ece92f85SJason Jin val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2977ece92f85SJason Jin cmp_word(M.x86.R_AX, (u16)val);
2978ece92f85SJason Jin }
2979ece92f85SJason Jin M.x86.R_CX -= 1;
2980ece92f85SJason Jin M.x86.R_DI += inc;
2981ece92f85SJason Jin if (ACCESS_FLAG(F_ZF) == 0)
2982ece92f85SJason Jin break;
2983ece92f85SJason Jin }
2984ece92f85SJason Jin M.x86.mode &= ~SYSMODE_PREFIX_REPE;
2985ece92f85SJason Jin } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
2986ece92f85SJason Jin /* REPNE */
2987ece92f85SJason Jin /* move them until CX is ZERO. */
2988ece92f85SJason Jin while (M.x86.R_CX != 0) {
2989ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2990ece92f85SJason Jin val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2991ece92f85SJason Jin cmp_long(M.x86.R_EAX, val);
2992ece92f85SJason Jin } else {
2993ece92f85SJason Jin val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2994ece92f85SJason Jin cmp_word(M.x86.R_AX, (u16)val);
2995ece92f85SJason Jin }
2996ece92f85SJason Jin M.x86.R_CX -= 1;
2997ece92f85SJason Jin M.x86.R_DI += inc;
2998ece92f85SJason Jin if (ACCESS_FLAG(F_ZF))
2999ece92f85SJason Jin break; /* zero flag set means equal */
3000ece92f85SJason Jin }
3001ece92f85SJason Jin M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
3002ece92f85SJason Jin } else {
3003ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3004ece92f85SJason Jin val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
3005ece92f85SJason Jin cmp_long(M.x86.R_EAX, val);
3006ece92f85SJason Jin } else {
3007ece92f85SJason Jin val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
3008ece92f85SJason Jin cmp_word(M.x86.R_AX, (u16)val);
3009ece92f85SJason Jin }
3010ece92f85SJason Jin M.x86.R_DI += inc;
3011ece92f85SJason Jin }
3012ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3013ece92f85SJason Jin END_OF_INSTR();
3014ece92f85SJason Jin }
3015ece92f85SJason Jin
3016ece92f85SJason Jin /****************************************************************************
3017ece92f85SJason Jin REMARKS:
3018ece92f85SJason Jin Handles opcode 0xb0 - 0xb7
3019ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_byte_register_IMM(u8 op1)3020ece92f85SJason Jin void x86emuOp_mov_byte_register_IMM(u8 op1)
3021ece92f85SJason Jin {
3022ece92f85SJason Jin u8 imm, *ptr;
3023ece92f85SJason Jin
3024ece92f85SJason Jin START_OF_INSTR();
3025ece92f85SJason Jin DECODE_PRINTF("MOV\t");
3026ece92f85SJason Jin ptr = DECODE_RM_BYTE_REGISTER(op1 & 0x7);
3027ece92f85SJason Jin DECODE_PRINTF(",");
3028ece92f85SJason Jin imm = fetch_byte_imm();
3029ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm);
3030ece92f85SJason Jin TRACE_AND_STEP();
3031ece92f85SJason Jin *ptr = imm;
3032ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3033ece92f85SJason Jin END_OF_INSTR();
3034ece92f85SJason Jin }
3035ece92f85SJason Jin
3036ece92f85SJason Jin /****************************************************************************
3037ece92f85SJason Jin REMARKS:
3038ece92f85SJason Jin Handles opcode 0xb8 - 0xbf
3039ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_word_register_IMM(u8 X86EMU_UNUSED (op1))3040ece92f85SJason Jin void x86emuOp_mov_word_register_IMM(u8 X86EMU_UNUSED(op1))
3041ece92f85SJason Jin {
3042ece92f85SJason Jin u32 srcval;
3043ece92f85SJason Jin
3044ece92f85SJason Jin op1 &= 0x7;
3045ece92f85SJason Jin
3046ece92f85SJason Jin START_OF_INSTR();
3047ece92f85SJason Jin DECODE_PRINTF("MOV\t");
3048ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3049ece92f85SJason Jin u32 *reg32;
3050ece92f85SJason Jin reg32 = DECODE_RM_LONG_REGISTER(op1);
3051ece92f85SJason Jin srcval = fetch_long_imm();
3052ece92f85SJason Jin DECODE_PRINTF2(",%x\n", srcval);
3053ece92f85SJason Jin TRACE_AND_STEP();
3054ece92f85SJason Jin *reg32 = srcval;
3055ece92f85SJason Jin } else {
3056ece92f85SJason Jin u16 *reg16;
3057ece92f85SJason Jin reg16 = DECODE_RM_WORD_REGISTER(op1);
3058ece92f85SJason Jin srcval = fetch_word_imm();
3059ece92f85SJason Jin DECODE_PRINTF2(",%x\n", srcval);
3060ece92f85SJason Jin TRACE_AND_STEP();
3061ece92f85SJason Jin *reg16 = (u16)srcval;
3062ece92f85SJason Jin }
3063ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3064ece92f85SJason Jin END_OF_INSTR();
3065ece92f85SJason Jin }
3066ece92f85SJason Jin
3067ece92f85SJason Jin /****************************************************************************
3068ece92f85SJason Jin REMARKS:
3069ece92f85SJason Jin Handles opcode 0xc0
3070ece92f85SJason Jin ****************************************************************************/
x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED (op1))3071ece92f85SJason Jin void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
3072ece92f85SJason Jin {
3073ece92f85SJason Jin int mod, rl, rh;
3074ece92f85SJason Jin u8 *destreg;
3075ece92f85SJason Jin uint destoffset;
3076ece92f85SJason Jin u8 destval;
3077ece92f85SJason Jin u8 amt;
3078ece92f85SJason Jin
3079ece92f85SJason Jin /*
3080ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of
3081ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would
3082ece92f85SJason Jin * result, except that the decoded instruction
3083ece92f85SJason Jin */
3084ece92f85SJason Jin START_OF_INSTR();
3085ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
3086b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
3087ece92f85SJason Jin if (DEBUG_DECODE()) {
3088ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
3089ece92f85SJason Jin general, so that it is important to leave the strings
3090ece92f85SJason Jin in the same format, even though the result is that the
3091ece92f85SJason Jin above test is done twice. */
3092ece92f85SJason Jin
3093ece92f85SJason Jin switch (rh) {
3094ece92f85SJason Jin case 0:
3095ece92f85SJason Jin DECODE_PRINTF("ROL\t");
3096ece92f85SJason Jin break;
3097ece92f85SJason Jin case 1:
3098ece92f85SJason Jin DECODE_PRINTF("ROR\t");
3099ece92f85SJason Jin break;
3100ece92f85SJason Jin case 2:
3101ece92f85SJason Jin DECODE_PRINTF("RCL\t");
3102ece92f85SJason Jin break;
3103ece92f85SJason Jin case 3:
3104ece92f85SJason Jin DECODE_PRINTF("RCR\t");
3105ece92f85SJason Jin break;
3106ece92f85SJason Jin case 4:
3107ece92f85SJason Jin DECODE_PRINTF("SHL\t");
3108ece92f85SJason Jin break;
3109ece92f85SJason Jin case 5:
3110ece92f85SJason Jin DECODE_PRINTF("SHR\t");
3111ece92f85SJason Jin break;
3112ece92f85SJason Jin case 6:
3113ece92f85SJason Jin DECODE_PRINTF("SAL\t");
3114ece92f85SJason Jin break;
3115ece92f85SJason Jin case 7:
3116ece92f85SJason Jin DECODE_PRINTF("SAR\t");
3117ece92f85SJason Jin break;
3118ece92f85SJason Jin }
3119ece92f85SJason Jin }
3120ece92f85SJason Jin #endif
3121ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing
3122ece92f85SJason Jin mode. */
3123ece92f85SJason Jin if (mod < 3) {
3124ece92f85SJason Jin DECODE_PRINTF("BYTE PTR ");
3125ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3126ece92f85SJason Jin amt = fetch_byte_imm();
3127ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt);
3128ece92f85SJason Jin destval = fetch_data_byte(destoffset);
3129ece92f85SJason Jin TRACE_AND_STEP();
3130ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (destval, amt);
3131ece92f85SJason Jin store_data_byte(destoffset, destval);
3132ece92f85SJason Jin } else { /* register to register */
3133ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
3134ece92f85SJason Jin amt = fetch_byte_imm();
3135ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt);
3136ece92f85SJason Jin TRACE_AND_STEP();
3137ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
3138ece92f85SJason Jin *destreg = destval;
3139ece92f85SJason Jin }
3140ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3141ece92f85SJason Jin END_OF_INSTR();
3142ece92f85SJason Jin }
3143ece92f85SJason Jin
3144ece92f85SJason Jin /****************************************************************************
3145ece92f85SJason Jin REMARKS:
3146ece92f85SJason Jin Handles opcode 0xc1
3147ece92f85SJason Jin ****************************************************************************/
x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED (op1))3148ece92f85SJason Jin void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
3149ece92f85SJason Jin {
3150ece92f85SJason Jin int mod, rl, rh;
3151ece92f85SJason Jin uint destoffset;
3152ece92f85SJason Jin u8 amt;
3153ece92f85SJason Jin
3154ece92f85SJason Jin /*
3155ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of
3156ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would
3157ece92f85SJason Jin * result, except that the decoded instruction
3158ece92f85SJason Jin */
3159ece92f85SJason Jin START_OF_INSTR();
3160ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
3161b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
3162ece92f85SJason Jin if (DEBUG_DECODE()) {
3163ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
3164ece92f85SJason Jin general, so that it is important to leave the strings
3165ece92f85SJason Jin in the same format, even though the result is that the
3166ece92f85SJason Jin above test is done twice. */
3167ece92f85SJason Jin
3168ece92f85SJason Jin switch (rh) {
3169ece92f85SJason Jin case 0:
3170ece92f85SJason Jin DECODE_PRINTF("ROL\t");
3171ece92f85SJason Jin break;
3172ece92f85SJason Jin case 1:
3173ece92f85SJason Jin DECODE_PRINTF("ROR\t");
3174ece92f85SJason Jin break;
3175ece92f85SJason Jin case 2:
3176ece92f85SJason Jin DECODE_PRINTF("RCL\t");
3177ece92f85SJason Jin break;
3178ece92f85SJason Jin case 3:
3179ece92f85SJason Jin DECODE_PRINTF("RCR\t");
3180ece92f85SJason Jin break;
3181ece92f85SJason Jin case 4:
3182ece92f85SJason Jin DECODE_PRINTF("SHL\t");
3183ece92f85SJason Jin break;
3184ece92f85SJason Jin case 5:
3185ece92f85SJason Jin DECODE_PRINTF("SHR\t");
3186ece92f85SJason Jin break;
3187ece92f85SJason Jin case 6:
3188ece92f85SJason Jin DECODE_PRINTF("SAL\t");
3189ece92f85SJason Jin break;
3190ece92f85SJason Jin case 7:
3191ece92f85SJason Jin DECODE_PRINTF("SAR\t");
3192ece92f85SJason Jin break;
3193ece92f85SJason Jin }
3194ece92f85SJason Jin }
3195ece92f85SJason Jin #endif
3196ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing
3197ece92f85SJason Jin mode. */
3198ece92f85SJason Jin if (mod < 3) {
3199ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3200ece92f85SJason Jin u32 destval;
3201ece92f85SJason Jin
3202ece92f85SJason Jin DECODE_PRINTF("DWORD PTR ");
3203ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3204ece92f85SJason Jin amt = fetch_byte_imm();
3205ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt);
3206ece92f85SJason Jin destval = fetch_data_long(destoffset);
3207ece92f85SJason Jin TRACE_AND_STEP();
3208ece92f85SJason Jin destval = (*opcD1_long_operation[rh]) (destval, amt);
3209ece92f85SJason Jin store_data_long(destoffset, destval);
3210ece92f85SJason Jin } else {
3211ece92f85SJason Jin u16 destval;
3212ece92f85SJason Jin
3213ece92f85SJason Jin DECODE_PRINTF("WORD PTR ");
3214ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3215ece92f85SJason Jin amt = fetch_byte_imm();
3216ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt);
3217ece92f85SJason Jin destval = fetch_data_word(destoffset);
3218ece92f85SJason Jin TRACE_AND_STEP();
3219ece92f85SJason Jin destval = (*opcD1_word_operation[rh]) (destval, amt);
3220ece92f85SJason Jin store_data_word(destoffset, destval);
3221ece92f85SJason Jin }
3222ece92f85SJason Jin } else { /* register to register */
3223ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3224ece92f85SJason Jin u32 *destreg;
3225ece92f85SJason Jin
3226ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
3227ece92f85SJason Jin amt = fetch_byte_imm();
3228ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt);
3229ece92f85SJason Jin TRACE_AND_STEP();
3230ece92f85SJason Jin *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
3231ece92f85SJason Jin } else {
3232ece92f85SJason Jin u16 *destreg;
3233ece92f85SJason Jin
3234ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
3235ece92f85SJason Jin amt = fetch_byte_imm();
3236ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt);
3237ece92f85SJason Jin TRACE_AND_STEP();
3238ece92f85SJason Jin *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
3239ece92f85SJason Jin }
3240ece92f85SJason Jin }
3241ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3242ece92f85SJason Jin END_OF_INSTR();
3243ece92f85SJason Jin }
3244ece92f85SJason Jin
3245ece92f85SJason Jin /****************************************************************************
3246ece92f85SJason Jin REMARKS:
3247ece92f85SJason Jin Handles opcode 0xc2
3248ece92f85SJason Jin ****************************************************************************/
x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED (op1))3249ece92f85SJason Jin void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
3250ece92f85SJason Jin {
3251ece92f85SJason Jin u16 imm;
3252ece92f85SJason Jin
3253ece92f85SJason Jin START_OF_INSTR();
3254ece92f85SJason Jin DECODE_PRINTF("RET\t");
3255ece92f85SJason Jin imm = fetch_word_imm();
3256ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm);
3257ece92f85SJason Jin RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
3258ece92f85SJason Jin TRACE_AND_STEP();
3259ece92f85SJason Jin M.x86.R_IP = pop_word();
3260ece92f85SJason Jin M.x86.R_SP += imm;
3261ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3262ece92f85SJason Jin END_OF_INSTR();
3263ece92f85SJason Jin }
3264ece92f85SJason Jin
3265ece92f85SJason Jin /****************************************************************************
3266ece92f85SJason Jin REMARKS:
3267ece92f85SJason Jin Handles opcode 0xc3
3268ece92f85SJason Jin ****************************************************************************/
x86emuOp_ret_near(u8 X86EMU_UNUSED (op1))3269ece92f85SJason Jin void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
3270ece92f85SJason Jin {
3271ece92f85SJason Jin START_OF_INSTR();
3272ece92f85SJason Jin DECODE_PRINTF("RET\n");
3273ece92f85SJason Jin RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
3274ece92f85SJason Jin TRACE_AND_STEP();
3275ece92f85SJason Jin M.x86.R_IP = pop_word();
3276ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3277ece92f85SJason Jin END_OF_INSTR();
3278ece92f85SJason Jin }
3279ece92f85SJason Jin
3280ece92f85SJason Jin /****************************************************************************
3281ece92f85SJason Jin REMARKS:
3282ece92f85SJason Jin Handles opcode 0xc4
3283ece92f85SJason Jin ****************************************************************************/
x86emuOp_les_R_IMM(u8 X86EMU_UNUSED (op1))3284ece92f85SJason Jin void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
3285ece92f85SJason Jin {
3286ece92f85SJason Jin int mod, rh, rl;
3287ece92f85SJason Jin u16 *dstreg;
3288ece92f85SJason Jin uint srcoffset;
3289ece92f85SJason Jin
3290ece92f85SJason Jin START_OF_INSTR();
3291ece92f85SJason Jin DECODE_PRINTF("LES\t");
3292ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
3293ece92f85SJason Jin if (mod < 3) {
3294ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh);
3295ece92f85SJason Jin DECODE_PRINTF(",");
3296ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
3297ece92f85SJason Jin DECODE_PRINTF("\n");
3298ece92f85SJason Jin TRACE_AND_STEP();
3299ece92f85SJason Jin *dstreg = fetch_data_word(srcoffset);
3300ece92f85SJason Jin M.x86.R_ES = fetch_data_word(srcoffset + 2);
3301ece92f85SJason Jin }
3302ece92f85SJason Jin /* else UNDEFINED! register to register */
3303ece92f85SJason Jin
3304ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3305ece92f85SJason Jin END_OF_INSTR();
3306ece92f85SJason Jin }
3307ece92f85SJason Jin
3308ece92f85SJason Jin /****************************************************************************
3309ece92f85SJason Jin REMARKS:
3310ece92f85SJason Jin Handles opcode 0xc5
3311ece92f85SJason Jin ****************************************************************************/
x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED (op1))3312ece92f85SJason Jin void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
3313ece92f85SJason Jin {
3314ece92f85SJason Jin int mod, rh, rl;
3315ece92f85SJason Jin u16 *dstreg;
3316ece92f85SJason Jin uint srcoffset;
3317ece92f85SJason Jin
3318ece92f85SJason Jin START_OF_INSTR();
3319ece92f85SJason Jin DECODE_PRINTF("LDS\t");
3320ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
3321ece92f85SJason Jin if (mod < 3) {
3322ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh);
3323ece92f85SJason Jin DECODE_PRINTF(",");
3324ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
3325ece92f85SJason Jin DECODE_PRINTF("\n");
3326ece92f85SJason Jin TRACE_AND_STEP();
3327ece92f85SJason Jin *dstreg = fetch_data_word(srcoffset);
3328ece92f85SJason Jin M.x86.R_DS = fetch_data_word(srcoffset + 2);
3329ece92f85SJason Jin }
3330ece92f85SJason Jin /* else UNDEFINED! */
3331ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3332ece92f85SJason Jin END_OF_INSTR();
3333ece92f85SJason Jin }
3334ece92f85SJason Jin
3335ece92f85SJason Jin /****************************************************************************
3336ece92f85SJason Jin REMARKS:
3337ece92f85SJason Jin Handles opcode 0xc6
3338ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED (op1))3339ece92f85SJason Jin void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
3340ece92f85SJason Jin {
3341ece92f85SJason Jin int mod, rl, rh;
3342ece92f85SJason Jin u8 *destreg;
3343ece92f85SJason Jin uint destoffset;
3344ece92f85SJason Jin u8 imm;
3345ece92f85SJason Jin
3346ece92f85SJason Jin START_OF_INSTR();
3347ece92f85SJason Jin DECODE_PRINTF("MOV\t");
3348ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
3349ece92f85SJason Jin if (rh != 0) {
33508c6ec412SSimon Glass ERR_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
3351ece92f85SJason Jin HALT_SYS();
3352ece92f85SJason Jin }
3353ece92f85SJason Jin if (mod < 3) {
3354ece92f85SJason Jin DECODE_PRINTF("BYTE PTR ");
3355ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3356ece92f85SJason Jin imm = fetch_byte_imm();
3357ece92f85SJason Jin DECODE_PRINTF2(",%2x\n", imm);
3358ece92f85SJason Jin TRACE_AND_STEP();
3359ece92f85SJason Jin store_data_byte(destoffset, imm);
3360ece92f85SJason Jin } else { /* register to register */
3361ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
3362ece92f85SJason Jin imm = fetch_byte_imm();
3363ece92f85SJason Jin DECODE_PRINTF2(",%2x\n", imm);
3364ece92f85SJason Jin TRACE_AND_STEP();
3365ece92f85SJason Jin *destreg = imm;
3366ece92f85SJason Jin }
3367ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3368ece92f85SJason Jin END_OF_INSTR();
3369ece92f85SJason Jin }
3370ece92f85SJason Jin
3371ece92f85SJason Jin /****************************************************************************
3372ece92f85SJason Jin REMARKS:
3373ece92f85SJason Jin Handles opcode 0xc7
3374ece92f85SJason Jin ****************************************************************************/
x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED (op1))3375ece92f85SJason Jin void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
3376ece92f85SJason Jin {
3377ece92f85SJason Jin int mod, rl, rh;
3378ece92f85SJason Jin uint destoffset;
3379ece92f85SJason Jin
3380ece92f85SJason Jin START_OF_INSTR();
3381ece92f85SJason Jin DECODE_PRINTF("MOV\t");
3382ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
3383ece92f85SJason Jin if (rh != 0) {
33848c6ec412SSimon Glass ERR_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
3385ece92f85SJason Jin HALT_SYS();
3386ece92f85SJason Jin }
3387ece92f85SJason Jin if (mod < 3) {
3388ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3389ece92f85SJason Jin u32 imm;
3390ece92f85SJason Jin
3391ece92f85SJason Jin DECODE_PRINTF("DWORD PTR ");
3392ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3393ece92f85SJason Jin imm = fetch_long_imm();
3394ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm);
3395ece92f85SJason Jin TRACE_AND_STEP();
3396ece92f85SJason Jin store_data_long(destoffset, imm);
3397ece92f85SJason Jin } else {
3398ece92f85SJason Jin u16 imm;
3399ece92f85SJason Jin
3400ece92f85SJason Jin DECODE_PRINTF("WORD PTR ");
3401ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3402ece92f85SJason Jin imm = fetch_word_imm();
3403ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm);
3404ece92f85SJason Jin TRACE_AND_STEP();
3405ece92f85SJason Jin store_data_word(destoffset, imm);
3406ece92f85SJason Jin }
3407ece92f85SJason Jin } else { /* register to register */
3408ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3409ece92f85SJason Jin u32 *destreg;
3410ece92f85SJason Jin u32 imm;
3411ece92f85SJason Jin
3412ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
3413ece92f85SJason Jin imm = fetch_long_imm();
3414ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm);
3415ece92f85SJason Jin TRACE_AND_STEP();
3416ece92f85SJason Jin *destreg = imm;
3417ece92f85SJason Jin } else {
3418ece92f85SJason Jin u16 *destreg;
3419ece92f85SJason Jin u16 imm;
3420ece92f85SJason Jin
3421ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
3422ece92f85SJason Jin imm = fetch_word_imm();
3423ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm);
3424ece92f85SJason Jin TRACE_AND_STEP();
3425ece92f85SJason Jin *destreg = imm;
3426ece92f85SJason Jin }
3427ece92f85SJason Jin }
3428ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3429ece92f85SJason Jin END_OF_INSTR();
3430ece92f85SJason Jin }
3431ece92f85SJason Jin
3432ece92f85SJason Jin /****************************************************************************
3433ece92f85SJason Jin REMARKS:
3434ece92f85SJason Jin Handles opcode 0xc8
3435ece92f85SJason Jin ****************************************************************************/
x86emuOp_enter(u8 X86EMU_UNUSED (op1))3436ece92f85SJason Jin void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
3437ece92f85SJason Jin {
3438ece92f85SJason Jin u16 local,frame_pointer;
3439ece92f85SJason Jin u8 nesting;
3440ece92f85SJason Jin int i;
3441ece92f85SJason Jin
3442ece92f85SJason Jin START_OF_INSTR();
3443ece92f85SJason Jin local = fetch_word_imm();
3444ece92f85SJason Jin nesting = fetch_byte_imm();
3445ece92f85SJason Jin DECODE_PRINTF2("ENTER %x\n", local);
3446ece92f85SJason Jin DECODE_PRINTF2(",%x\n", nesting);
3447ece92f85SJason Jin TRACE_AND_STEP();
3448ece92f85SJason Jin push_word(M.x86.R_BP);
3449ece92f85SJason Jin frame_pointer = M.x86.R_SP;
3450ece92f85SJason Jin if (nesting > 0) {
3451ece92f85SJason Jin for (i = 1; i < nesting; i++) {
3452ece92f85SJason Jin M.x86.R_BP -= 2;
3453ece92f85SJason Jin push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
3454ece92f85SJason Jin }
3455ece92f85SJason Jin push_word(frame_pointer);
3456ece92f85SJason Jin }
3457ece92f85SJason Jin M.x86.R_BP = frame_pointer;
3458ece92f85SJason Jin M.x86.R_SP = (u16)(M.x86.R_SP - local);
3459ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3460ece92f85SJason Jin END_OF_INSTR();
3461ece92f85SJason Jin }
3462ece92f85SJason Jin
3463ece92f85SJason Jin /****************************************************************************
3464ece92f85SJason Jin REMARKS:
3465ece92f85SJason Jin Handles opcode 0xc9
3466ece92f85SJason Jin ****************************************************************************/
x86emuOp_leave(u8 X86EMU_UNUSED (op1))3467ece92f85SJason Jin void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
3468ece92f85SJason Jin {
3469ece92f85SJason Jin START_OF_INSTR();
3470ece92f85SJason Jin DECODE_PRINTF("LEAVE\n");
3471ece92f85SJason Jin TRACE_AND_STEP();
3472ece92f85SJason Jin M.x86.R_SP = M.x86.R_BP;
3473ece92f85SJason Jin M.x86.R_BP = pop_word();
3474ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3475ece92f85SJason Jin END_OF_INSTR();
3476ece92f85SJason Jin }
3477ece92f85SJason Jin
3478ece92f85SJason Jin /****************************************************************************
3479ece92f85SJason Jin REMARKS:
3480ece92f85SJason Jin Handles opcode 0xca
3481ece92f85SJason Jin ****************************************************************************/
x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED (op1))3482ece92f85SJason Jin void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
3483ece92f85SJason Jin {
3484ece92f85SJason Jin u16 imm;
3485ece92f85SJason Jin
3486ece92f85SJason Jin START_OF_INSTR();
3487ece92f85SJason Jin DECODE_PRINTF("RETF\t");
3488ece92f85SJason Jin imm = fetch_word_imm();
3489ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm);
3490ece92f85SJason Jin RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
3491ece92f85SJason Jin TRACE_AND_STEP();
3492ece92f85SJason Jin M.x86.R_IP = pop_word();
3493ece92f85SJason Jin M.x86.R_CS = pop_word();
3494ece92f85SJason Jin M.x86.R_SP += imm;
3495ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3496ece92f85SJason Jin END_OF_INSTR();
3497ece92f85SJason Jin }
3498ece92f85SJason Jin
3499ece92f85SJason Jin /****************************************************************************
3500ece92f85SJason Jin REMARKS:
3501ece92f85SJason Jin Handles opcode 0xcb
3502ece92f85SJason Jin ****************************************************************************/
x86emuOp_ret_far(u8 X86EMU_UNUSED (op1))3503ece92f85SJason Jin void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
3504ece92f85SJason Jin {
3505ece92f85SJason Jin START_OF_INSTR();
3506ece92f85SJason Jin DECODE_PRINTF("RETF\n");
3507ece92f85SJason Jin RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
3508ece92f85SJason Jin TRACE_AND_STEP();
3509ece92f85SJason Jin M.x86.R_IP = pop_word();
3510ece92f85SJason Jin M.x86.R_CS = pop_word();
3511ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3512ece92f85SJason Jin END_OF_INSTR();
3513ece92f85SJason Jin }
3514ece92f85SJason Jin
3515ece92f85SJason Jin /****************************************************************************
3516ece92f85SJason Jin REMARKS:
3517ece92f85SJason Jin Handles opcode 0xcc
3518ece92f85SJason Jin ****************************************************************************/
x86emuOp_int3(u8 X86EMU_UNUSED (op1))3519ece92f85SJason Jin void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
3520ece92f85SJason Jin {
3521ece92f85SJason Jin START_OF_INSTR();
3522ece92f85SJason Jin DECODE_PRINTF("INT 3\n");
3523755cf792SKumar Gala (void)mem_access_word(3 * 4 + 2);
3524ece92f85SJason Jin /* access the segment register */
3525ece92f85SJason Jin TRACE_AND_STEP();
3526ece92f85SJason Jin if (_X86EMU_intrTab[3]) {
3527ece92f85SJason Jin (*_X86EMU_intrTab[3])(3);
3528ece92f85SJason Jin } else {
3529ece92f85SJason Jin push_word((u16)M.x86.R_FLG);
3530ece92f85SJason Jin CLEAR_FLAG(F_IF);
3531ece92f85SJason Jin CLEAR_FLAG(F_TF);
3532ece92f85SJason Jin push_word(M.x86.R_CS);
3533ece92f85SJason Jin M.x86.R_CS = mem_access_word(3 * 4 + 2);
3534ece92f85SJason Jin push_word(M.x86.R_IP);
3535ece92f85SJason Jin M.x86.R_IP = mem_access_word(3 * 4);
3536ece92f85SJason Jin }
3537ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3538ece92f85SJason Jin END_OF_INSTR();
3539ece92f85SJason Jin }
3540ece92f85SJason Jin
3541ece92f85SJason Jin /****************************************************************************
3542ece92f85SJason Jin REMARKS:
3543ece92f85SJason Jin Handles opcode 0xcd
3544ece92f85SJason Jin ****************************************************************************/
x86emuOp_int_IMM(u8 X86EMU_UNUSED (op1))3545ece92f85SJason Jin void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
3546ece92f85SJason Jin {
3547ece92f85SJason Jin u8 intnum;
3548ece92f85SJason Jin
3549ece92f85SJason Jin START_OF_INSTR();
3550ece92f85SJason Jin DECODE_PRINTF("INT\t");
3551ece92f85SJason Jin intnum = fetch_byte_imm();
3552ece92f85SJason Jin DECODE_PRINTF2("%x\n", intnum);
3553755cf792SKumar Gala (void)mem_access_word(intnum * 4 + 2);
3554ece92f85SJason Jin TRACE_AND_STEP();
3555ece92f85SJason Jin if (_X86EMU_intrTab[intnum]) {
3556ece92f85SJason Jin (*_X86EMU_intrTab[intnum])(intnum);
3557ece92f85SJason Jin } else {
3558ece92f85SJason Jin push_word((u16)M.x86.R_FLG);
3559ece92f85SJason Jin CLEAR_FLAG(F_IF);
3560ece92f85SJason Jin CLEAR_FLAG(F_TF);
3561ece92f85SJason Jin push_word(M.x86.R_CS);
3562ece92f85SJason Jin M.x86.R_CS = mem_access_word(intnum * 4 + 2);
3563ece92f85SJason Jin push_word(M.x86.R_IP);
3564ece92f85SJason Jin M.x86.R_IP = mem_access_word(intnum * 4);
3565ece92f85SJason Jin }
3566ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3567ece92f85SJason Jin END_OF_INSTR();
3568ece92f85SJason Jin }
3569ece92f85SJason Jin
3570ece92f85SJason Jin /****************************************************************************
3571ece92f85SJason Jin REMARKS:
3572ece92f85SJason Jin Handles opcode 0xce
3573ece92f85SJason Jin ****************************************************************************/
x86emuOp_into(u8 X86EMU_UNUSED (op1))3574ece92f85SJason Jin void x86emuOp_into(u8 X86EMU_UNUSED(op1))
3575ece92f85SJason Jin {
3576ece92f85SJason Jin START_OF_INSTR();
3577ece92f85SJason Jin DECODE_PRINTF("INTO\n");
3578ece92f85SJason Jin TRACE_AND_STEP();
3579ece92f85SJason Jin if (ACCESS_FLAG(F_OF)) {
3580755cf792SKumar Gala (void)mem_access_word(4 * 4 + 2);
3581ece92f85SJason Jin if (_X86EMU_intrTab[4]) {
3582ece92f85SJason Jin (*_X86EMU_intrTab[4])(4);
3583ece92f85SJason Jin } else {
3584ece92f85SJason Jin push_word((u16)M.x86.R_FLG);
3585ece92f85SJason Jin CLEAR_FLAG(F_IF);
3586ece92f85SJason Jin CLEAR_FLAG(F_TF);
3587ece92f85SJason Jin push_word(M.x86.R_CS);
3588ece92f85SJason Jin M.x86.R_CS = mem_access_word(4 * 4 + 2);
3589ece92f85SJason Jin push_word(M.x86.R_IP);
3590ece92f85SJason Jin M.x86.R_IP = mem_access_word(4 * 4);
3591ece92f85SJason Jin }
3592ece92f85SJason Jin }
3593ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3594ece92f85SJason Jin END_OF_INSTR();
3595ece92f85SJason Jin }
3596ece92f85SJason Jin
3597ece92f85SJason Jin /****************************************************************************
3598ece92f85SJason Jin REMARKS:
3599ece92f85SJason Jin Handles opcode 0xcf
3600ece92f85SJason Jin ****************************************************************************/
x86emuOp_iret(u8 X86EMU_UNUSED (op1))3601ece92f85SJason Jin void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
3602ece92f85SJason Jin {
3603ece92f85SJason Jin START_OF_INSTR();
3604ece92f85SJason Jin DECODE_PRINTF("IRET\n");
3605ece92f85SJason Jin
3606ece92f85SJason Jin TRACE_AND_STEP();
3607ece92f85SJason Jin
3608ece92f85SJason Jin M.x86.R_IP = pop_word();
3609ece92f85SJason Jin M.x86.R_CS = pop_word();
3610ece92f85SJason Jin M.x86.R_FLG = pop_word();
3611ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3612ece92f85SJason Jin END_OF_INSTR();
3613ece92f85SJason Jin }
3614ece92f85SJason Jin
3615ece92f85SJason Jin /****************************************************************************
3616ece92f85SJason Jin REMARKS:
3617ece92f85SJason Jin Handles opcode 0xd0
3618ece92f85SJason Jin ****************************************************************************/
x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED (op1))3619ece92f85SJason Jin void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
3620ece92f85SJason Jin {
3621ece92f85SJason Jin int mod, rl, rh;
3622ece92f85SJason Jin u8 *destreg;
3623ece92f85SJason Jin uint destoffset;
3624ece92f85SJason Jin u8 destval;
3625ece92f85SJason Jin
3626ece92f85SJason Jin /*
3627ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of
3628ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would
3629ece92f85SJason Jin * result, except that the decoded instruction
3630ece92f85SJason Jin */
3631ece92f85SJason Jin START_OF_INSTR();
3632ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
3633b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
3634ece92f85SJason Jin if (DEBUG_DECODE()) {
3635ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
3636ece92f85SJason Jin general, so that it is important to leave the strings
3637ece92f85SJason Jin in the same format, even though the result is that the
3638ece92f85SJason Jin above test is done twice. */
3639ece92f85SJason Jin switch (rh) {
3640ece92f85SJason Jin case 0:
3641ece92f85SJason Jin DECODE_PRINTF("ROL\t");
3642ece92f85SJason Jin break;
3643ece92f85SJason Jin case 1:
3644ece92f85SJason Jin DECODE_PRINTF("ROR\t");
3645ece92f85SJason Jin break;
3646ece92f85SJason Jin case 2:
3647ece92f85SJason Jin DECODE_PRINTF("RCL\t");
3648ece92f85SJason Jin break;
3649ece92f85SJason Jin case 3:
3650ece92f85SJason Jin DECODE_PRINTF("RCR\t");
3651ece92f85SJason Jin break;
3652ece92f85SJason Jin case 4:
3653ece92f85SJason Jin DECODE_PRINTF("SHL\t");
3654ece92f85SJason Jin break;
3655ece92f85SJason Jin case 5:
3656ece92f85SJason Jin DECODE_PRINTF("SHR\t");
3657ece92f85SJason Jin break;
3658ece92f85SJason Jin case 6:
3659ece92f85SJason Jin DECODE_PRINTF("SAL\t");
3660ece92f85SJason Jin break;
3661ece92f85SJason Jin case 7:
3662ece92f85SJason Jin DECODE_PRINTF("SAR\t");
3663ece92f85SJason Jin break;
3664ece92f85SJason Jin }
3665ece92f85SJason Jin }
3666ece92f85SJason Jin #endif
3667ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing
3668ece92f85SJason Jin mode. */
3669ece92f85SJason Jin if (mod < 3) {
3670ece92f85SJason Jin DECODE_PRINTF("BYTE PTR ");
3671ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3672ece92f85SJason Jin DECODE_PRINTF(",1\n");
3673ece92f85SJason Jin destval = fetch_data_byte(destoffset);
3674ece92f85SJason Jin TRACE_AND_STEP();
3675ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (destval, 1);
3676ece92f85SJason Jin store_data_byte(destoffset, destval);
3677ece92f85SJason Jin } else { /* register to register */
3678ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
3679ece92f85SJason Jin DECODE_PRINTF(",1\n");
3680ece92f85SJason Jin TRACE_AND_STEP();
3681ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
3682ece92f85SJason Jin *destreg = destval;
3683ece92f85SJason Jin }
3684ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3685ece92f85SJason Jin END_OF_INSTR();
3686ece92f85SJason Jin }
3687ece92f85SJason Jin
3688ece92f85SJason Jin /****************************************************************************
3689ece92f85SJason Jin REMARKS:
3690ece92f85SJason Jin Handles opcode 0xd1
3691ece92f85SJason Jin ****************************************************************************/
x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED (op1))3692ece92f85SJason Jin void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
3693ece92f85SJason Jin {
3694ece92f85SJason Jin int mod, rl, rh;
3695ece92f85SJason Jin uint destoffset;
3696ece92f85SJason Jin
3697ece92f85SJason Jin /*
3698ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of
3699ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would
3700ece92f85SJason Jin * result, except that the decoded instruction
3701ece92f85SJason Jin */
3702ece92f85SJason Jin START_OF_INSTR();
3703ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
3704b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
3705ece92f85SJason Jin if (DEBUG_DECODE()) {
3706ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
3707ece92f85SJason Jin general, so that it is important to leave the strings
3708ece92f85SJason Jin in the same format, even though the result is that the
3709ece92f85SJason Jin above test is done twice. */
3710ece92f85SJason Jin switch (rh) {
3711ece92f85SJason Jin case 0:
3712ece92f85SJason Jin DECODE_PRINTF("ROL\t");
3713ece92f85SJason Jin break;
3714ece92f85SJason Jin case 1:
3715ece92f85SJason Jin DECODE_PRINTF("ROR\t");
3716ece92f85SJason Jin break;
3717ece92f85SJason Jin case 2:
3718ece92f85SJason Jin DECODE_PRINTF("RCL\t");
3719ece92f85SJason Jin break;
3720ece92f85SJason Jin case 3:
3721ece92f85SJason Jin DECODE_PRINTF("RCR\t");
3722ece92f85SJason Jin break;
3723ece92f85SJason Jin case 4:
3724ece92f85SJason Jin DECODE_PRINTF("SHL\t");
3725ece92f85SJason Jin break;
3726ece92f85SJason Jin case 5:
3727ece92f85SJason Jin DECODE_PRINTF("SHR\t");
3728ece92f85SJason Jin break;
3729ece92f85SJason Jin case 6:
3730ece92f85SJason Jin DECODE_PRINTF("SAL\t");
3731ece92f85SJason Jin break;
3732ece92f85SJason Jin case 7:
3733ece92f85SJason Jin DECODE_PRINTF("SAR\t");
3734ece92f85SJason Jin break;
3735ece92f85SJason Jin }
3736ece92f85SJason Jin }
3737ece92f85SJason Jin #endif
3738ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing
3739ece92f85SJason Jin mode. */
3740ece92f85SJason Jin if (mod < 3) {
3741ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3742ece92f85SJason Jin u32 destval;
3743ece92f85SJason Jin
3744ece92f85SJason Jin DECODE_PRINTF("DWORD PTR ");
3745ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3746ece92f85SJason Jin DECODE_PRINTF(",1\n");
3747ece92f85SJason Jin destval = fetch_data_long(destoffset);
3748ece92f85SJason Jin TRACE_AND_STEP();
3749ece92f85SJason Jin destval = (*opcD1_long_operation[rh]) (destval, 1);
3750ece92f85SJason Jin store_data_long(destoffset, destval);
3751ece92f85SJason Jin } else {
3752ece92f85SJason Jin u16 destval;
3753ece92f85SJason Jin
3754ece92f85SJason Jin DECODE_PRINTF("WORD PTR ");
3755ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3756ece92f85SJason Jin DECODE_PRINTF(",1\n");
3757ece92f85SJason Jin destval = fetch_data_word(destoffset);
3758ece92f85SJason Jin TRACE_AND_STEP();
3759ece92f85SJason Jin destval = (*opcD1_word_operation[rh]) (destval, 1);
3760ece92f85SJason Jin store_data_word(destoffset, destval);
3761ece92f85SJason Jin }
3762ece92f85SJason Jin } else { /* register to register */
3763ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3764ece92f85SJason Jin u32 destval;
3765ece92f85SJason Jin u32 *destreg;
3766ece92f85SJason Jin
3767ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
3768ece92f85SJason Jin DECODE_PRINTF(",1\n");
3769ece92f85SJason Jin TRACE_AND_STEP();
3770ece92f85SJason Jin destval = (*opcD1_long_operation[rh]) (*destreg, 1);
3771ece92f85SJason Jin *destreg = destval;
3772ece92f85SJason Jin } else {
3773ece92f85SJason Jin u16 destval;
3774ece92f85SJason Jin u16 *destreg;
3775ece92f85SJason Jin
3776ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
3777ece92f85SJason Jin DECODE_PRINTF(",1\n");
3778ece92f85SJason Jin TRACE_AND_STEP();
3779ece92f85SJason Jin destval = (*opcD1_word_operation[rh]) (*destreg, 1);
3780ece92f85SJason Jin *destreg = destval;
3781ece92f85SJason Jin }
3782ece92f85SJason Jin }
3783ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3784ece92f85SJason Jin END_OF_INSTR();
3785ece92f85SJason Jin }
3786ece92f85SJason Jin
3787ece92f85SJason Jin /****************************************************************************
3788ece92f85SJason Jin REMARKS:
3789ece92f85SJason Jin Handles opcode 0xd2
3790ece92f85SJason Jin ****************************************************************************/
x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED (op1))3791ece92f85SJason Jin void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
3792ece92f85SJason Jin {
3793ece92f85SJason Jin int mod, rl, rh;
3794ece92f85SJason Jin u8 *destreg;
3795ece92f85SJason Jin uint destoffset;
3796ece92f85SJason Jin u8 destval;
3797ece92f85SJason Jin u8 amt;
3798ece92f85SJason Jin
3799ece92f85SJason Jin /*
3800ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of
3801ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would
3802ece92f85SJason Jin * result, except that the decoded instruction
3803ece92f85SJason Jin */
3804ece92f85SJason Jin START_OF_INSTR();
3805ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
3806b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
3807ece92f85SJason Jin if (DEBUG_DECODE()) {
3808ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
3809ece92f85SJason Jin general, so that it is important to leave the strings
3810ece92f85SJason Jin in the same format, even though the result is that the
3811ece92f85SJason Jin above test is done twice. */
3812ece92f85SJason Jin switch (rh) {
3813ece92f85SJason Jin case 0:
3814ece92f85SJason Jin DECODE_PRINTF("ROL\t");
3815ece92f85SJason Jin break;
3816ece92f85SJason Jin case 1:
3817ece92f85SJason Jin DECODE_PRINTF("ROR\t");
3818ece92f85SJason Jin break;
3819ece92f85SJason Jin case 2:
3820ece92f85SJason Jin DECODE_PRINTF("RCL\t");
3821ece92f85SJason Jin break;
3822ece92f85SJason Jin case 3:
3823ece92f85SJason Jin DECODE_PRINTF("RCR\t");
3824ece92f85SJason Jin break;
3825ece92f85SJason Jin case 4:
3826ece92f85SJason Jin DECODE_PRINTF("SHL\t");
3827ece92f85SJason Jin break;
3828ece92f85SJason Jin case 5:
3829ece92f85SJason Jin DECODE_PRINTF("SHR\t");
3830ece92f85SJason Jin break;
3831ece92f85SJason Jin case 6:
3832ece92f85SJason Jin DECODE_PRINTF("SAL\t");
3833ece92f85SJason Jin break;
3834ece92f85SJason Jin case 7:
3835ece92f85SJason Jin DECODE_PRINTF("SAR\t");
3836ece92f85SJason Jin break;
3837ece92f85SJason Jin }
3838ece92f85SJason Jin }
3839ece92f85SJason Jin #endif
3840ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing
3841ece92f85SJason Jin mode. */
3842ece92f85SJason Jin amt = M.x86.R_CL;
3843ece92f85SJason Jin if (mod < 3) {
3844ece92f85SJason Jin DECODE_PRINTF("BYTE PTR ");
3845ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3846ece92f85SJason Jin DECODE_PRINTF(",CL\n");
3847ece92f85SJason Jin destval = fetch_data_byte(destoffset);
3848ece92f85SJason Jin TRACE_AND_STEP();
3849ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (destval, amt);
3850ece92f85SJason Jin store_data_byte(destoffset, destval);
3851ece92f85SJason Jin } else { /* register to register */
3852ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
3853ece92f85SJason Jin DECODE_PRINTF(",CL\n");
3854ece92f85SJason Jin TRACE_AND_STEP();
3855ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
3856ece92f85SJason Jin *destreg = destval;
3857ece92f85SJason Jin }
3858ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3859ece92f85SJason Jin END_OF_INSTR();
3860ece92f85SJason Jin }
3861ece92f85SJason Jin
3862ece92f85SJason Jin /****************************************************************************
3863ece92f85SJason Jin REMARKS:
3864ece92f85SJason Jin Handles opcode 0xd3
3865ece92f85SJason Jin ****************************************************************************/
x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED (op1))3866ece92f85SJason Jin void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
3867ece92f85SJason Jin {
3868ece92f85SJason Jin int mod, rl, rh;
3869ece92f85SJason Jin uint destoffset;
3870ece92f85SJason Jin u8 amt;
3871ece92f85SJason Jin
3872ece92f85SJason Jin /*
3873ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of
3874ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would
3875ece92f85SJason Jin * result, except that the decoded instruction
3876ece92f85SJason Jin */
3877ece92f85SJason Jin START_OF_INSTR();
3878ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
3879b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
3880ece92f85SJason Jin if (DEBUG_DECODE()) {
3881ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
3882ece92f85SJason Jin general, so that it is important to leave the strings
3883ece92f85SJason Jin in the same format, even though the result is that the
3884ece92f85SJason Jin above test is done twice. */
3885ece92f85SJason Jin switch (rh) {
3886ece92f85SJason Jin case 0:
3887ece92f85SJason Jin DECODE_PRINTF("ROL\t");
3888ece92f85SJason Jin break;
3889ece92f85SJason Jin case 1:
3890ece92f85SJason Jin DECODE_PRINTF("ROR\t");
3891ece92f85SJason Jin break;
3892ece92f85SJason Jin case 2:
3893ece92f85SJason Jin DECODE_PRINTF("RCL\t");
3894ece92f85SJason Jin break;
3895ece92f85SJason Jin case 3:
3896ece92f85SJason Jin DECODE_PRINTF("RCR\t");
3897ece92f85SJason Jin break;
3898ece92f85SJason Jin case 4:
3899ece92f85SJason Jin DECODE_PRINTF("SHL\t");
3900ece92f85SJason Jin break;
3901ece92f85SJason Jin case 5:
3902ece92f85SJason Jin DECODE_PRINTF("SHR\t");
3903ece92f85SJason Jin break;
3904ece92f85SJason Jin case 6:
3905ece92f85SJason Jin DECODE_PRINTF("SAL\t");
3906ece92f85SJason Jin break;
3907ece92f85SJason Jin case 7:
3908ece92f85SJason Jin DECODE_PRINTF("SAR\t");
3909ece92f85SJason Jin break;
3910ece92f85SJason Jin }
3911ece92f85SJason Jin }
3912ece92f85SJason Jin #endif
3913ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing
3914ece92f85SJason Jin mode. */
3915ece92f85SJason Jin amt = M.x86.R_CL;
3916ece92f85SJason Jin if (mod < 3) {
3917ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3918ece92f85SJason Jin u32 destval;
3919ece92f85SJason Jin
3920ece92f85SJason Jin DECODE_PRINTF("DWORD PTR ");
3921ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3922ece92f85SJason Jin DECODE_PRINTF(",CL\n");
3923ece92f85SJason Jin destval = fetch_data_long(destoffset);
3924ece92f85SJason Jin TRACE_AND_STEP();
3925ece92f85SJason Jin destval = (*opcD1_long_operation[rh]) (destval, amt);
3926ece92f85SJason Jin store_data_long(destoffset, destval);
3927ece92f85SJason Jin } else {
3928ece92f85SJason Jin u16 destval;
3929ece92f85SJason Jin
3930ece92f85SJason Jin DECODE_PRINTF("WORD PTR ");
3931ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
3932ece92f85SJason Jin DECODE_PRINTF(",CL\n");
3933ece92f85SJason Jin destval = fetch_data_word(destoffset);
3934ece92f85SJason Jin TRACE_AND_STEP();
3935ece92f85SJason Jin destval = (*opcD1_word_operation[rh]) (destval, amt);
3936ece92f85SJason Jin store_data_word(destoffset, destval);
3937ece92f85SJason Jin }
3938ece92f85SJason Jin } else { /* register to register */
3939ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3940ece92f85SJason Jin u32 *destreg;
3941ece92f85SJason Jin
3942ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
3943ece92f85SJason Jin DECODE_PRINTF(",CL\n");
3944ece92f85SJason Jin TRACE_AND_STEP();
3945ece92f85SJason Jin *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
3946ece92f85SJason Jin } else {
3947ece92f85SJason Jin u16 *destreg;
3948ece92f85SJason Jin
3949ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
3950ece92f85SJason Jin DECODE_PRINTF(",CL\n");
3951ece92f85SJason Jin TRACE_AND_STEP();
3952ece92f85SJason Jin *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
3953ece92f85SJason Jin }
3954ece92f85SJason Jin }
3955ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3956ece92f85SJason Jin END_OF_INSTR();
3957ece92f85SJason Jin }
3958ece92f85SJason Jin
3959ece92f85SJason Jin /****************************************************************************
3960ece92f85SJason Jin REMARKS:
3961ece92f85SJason Jin Handles opcode 0xd4
3962ece92f85SJason Jin ****************************************************************************/
x86emuOp_aam(u8 X86EMU_UNUSED (op1))3963ece92f85SJason Jin void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
3964ece92f85SJason Jin {
3965ece92f85SJason Jin u8 a;
3966ece92f85SJason Jin
3967ece92f85SJason Jin START_OF_INSTR();
3968ece92f85SJason Jin DECODE_PRINTF("AAM\n");
3969ece92f85SJason Jin a = fetch_byte_imm(); /* this is a stupid encoding. */
3970ece92f85SJason Jin if (a != 10) {
39718c6ec412SSimon Glass ERR_PRINTF("ERROR DECODING AAM\n");
3972ece92f85SJason Jin TRACE_REGS();
3973ece92f85SJason Jin HALT_SYS();
3974ece92f85SJason Jin }
3975ece92f85SJason Jin TRACE_AND_STEP();
3976ece92f85SJason Jin /* note the type change here --- returning AL and AH in AX. */
3977ece92f85SJason Jin M.x86.R_AX = aam_word(M.x86.R_AL);
3978ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3979ece92f85SJason Jin END_OF_INSTR();
3980ece92f85SJason Jin }
3981ece92f85SJason Jin
3982ece92f85SJason Jin /****************************************************************************
3983ece92f85SJason Jin REMARKS:
3984ece92f85SJason Jin Handles opcode 0xd5
3985ece92f85SJason Jin ****************************************************************************/
x86emuOp_aad(u8 X86EMU_UNUSED (op1))3986ece92f85SJason Jin void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
3987ece92f85SJason Jin {
3988ece92f85SJason Jin START_OF_INSTR();
3989ece92f85SJason Jin DECODE_PRINTF("AAD\n");
3990755cf792SKumar Gala (void)fetch_byte_imm();
3991ece92f85SJason Jin TRACE_AND_STEP();
3992ece92f85SJason Jin M.x86.R_AX = aad_word(M.x86.R_AX);
3993ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
3994ece92f85SJason Jin END_OF_INSTR();
3995ece92f85SJason Jin }
3996ece92f85SJason Jin
3997ece92f85SJason Jin /* opcode 0xd6 ILLEGAL OPCODE */
3998ece92f85SJason Jin
3999ece92f85SJason Jin /****************************************************************************
4000ece92f85SJason Jin REMARKS:
4001ece92f85SJason Jin Handles opcode 0xd7
4002ece92f85SJason Jin ****************************************************************************/
x86emuOp_xlat(u8 X86EMU_UNUSED (op1))4003ece92f85SJason Jin void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
4004ece92f85SJason Jin {
4005ece92f85SJason Jin u16 addr;
4006ece92f85SJason Jin
4007ece92f85SJason Jin START_OF_INSTR();
4008ece92f85SJason Jin DECODE_PRINTF("XLAT\n");
4009ece92f85SJason Jin TRACE_AND_STEP();
4010ece92f85SJason Jin addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
4011ece92f85SJason Jin M.x86.R_AL = fetch_data_byte(addr);
4012ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4013ece92f85SJason Jin END_OF_INSTR();
4014ece92f85SJason Jin }
4015ece92f85SJason Jin
4016ece92f85SJason Jin /* instuctions D8 .. DF are in i87_ops.c */
4017ece92f85SJason Jin
4018ece92f85SJason Jin /****************************************************************************
4019ece92f85SJason Jin REMARKS:
4020ece92f85SJason Jin Handles opcode 0xe0
4021ece92f85SJason Jin ****************************************************************************/
x86emuOp_loopne(u8 X86EMU_UNUSED (op1))4022ece92f85SJason Jin void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
4023ece92f85SJason Jin {
4024ece92f85SJason Jin s16 ip;
4025ece92f85SJason Jin
4026ece92f85SJason Jin START_OF_INSTR();
4027ece92f85SJason Jin DECODE_PRINTF("LOOPNE\t");
4028ece92f85SJason Jin ip = (s8) fetch_byte_imm();
4029ece92f85SJason Jin ip += (s16) M.x86.R_IP;
4030ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip);
4031ece92f85SJason Jin TRACE_AND_STEP();
4032ece92f85SJason Jin M.x86.R_CX -= 1;
4033ece92f85SJason Jin if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
4034ece92f85SJason Jin M.x86.R_IP = ip;
4035ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4036ece92f85SJason Jin END_OF_INSTR();
4037ece92f85SJason Jin }
4038ece92f85SJason Jin
4039ece92f85SJason Jin /****************************************************************************
4040ece92f85SJason Jin REMARKS:
4041ece92f85SJason Jin Handles opcode 0xe1
4042ece92f85SJason Jin ****************************************************************************/
x86emuOp_loope(u8 X86EMU_UNUSED (op1))4043ece92f85SJason Jin void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
4044ece92f85SJason Jin {
4045ece92f85SJason Jin s16 ip;
4046ece92f85SJason Jin
4047ece92f85SJason Jin START_OF_INSTR();
4048ece92f85SJason Jin DECODE_PRINTF("LOOPE\t");
4049ece92f85SJason Jin ip = (s8) fetch_byte_imm();
4050ece92f85SJason Jin ip += (s16) M.x86.R_IP;
4051ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip);
4052ece92f85SJason Jin TRACE_AND_STEP();
4053ece92f85SJason Jin M.x86.R_CX -= 1;
4054ece92f85SJason Jin if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
4055ece92f85SJason Jin M.x86.R_IP = ip;
4056ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4057ece92f85SJason Jin END_OF_INSTR();
4058ece92f85SJason Jin }
4059ece92f85SJason Jin
4060ece92f85SJason Jin /****************************************************************************
4061ece92f85SJason Jin REMARKS:
4062ece92f85SJason Jin Handles opcode 0xe2
4063ece92f85SJason Jin ****************************************************************************/
x86emuOp_loop(u8 X86EMU_UNUSED (op1))4064ece92f85SJason Jin void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
4065ece92f85SJason Jin {
4066ece92f85SJason Jin s16 ip;
4067ece92f85SJason Jin
4068ece92f85SJason Jin START_OF_INSTR();
4069ece92f85SJason Jin DECODE_PRINTF("LOOP\t");
4070ece92f85SJason Jin ip = (s8) fetch_byte_imm();
4071ece92f85SJason Jin ip += (s16) M.x86.R_IP;
4072ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip);
4073ece92f85SJason Jin TRACE_AND_STEP();
4074ece92f85SJason Jin M.x86.R_CX -= 1;
4075ece92f85SJason Jin if (M.x86.R_CX != 0)
4076ece92f85SJason Jin M.x86.R_IP = ip;
4077ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4078ece92f85SJason Jin END_OF_INSTR();
4079ece92f85SJason Jin }
4080ece92f85SJason Jin
4081ece92f85SJason Jin /****************************************************************************
4082ece92f85SJason Jin REMARKS:
4083ece92f85SJason Jin Handles opcode 0xe3
4084ece92f85SJason Jin ****************************************************************************/
x86emuOp_jcxz(u8 X86EMU_UNUSED (op1))4085ece92f85SJason Jin void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
4086ece92f85SJason Jin {
4087ece92f85SJason Jin u16 target;
4088ece92f85SJason Jin s8 offset;
4089ece92f85SJason Jin
4090ece92f85SJason Jin /* jump to byte offset if overflow flag is set */
4091ece92f85SJason Jin START_OF_INSTR();
4092ece92f85SJason Jin DECODE_PRINTF("JCXZ\t");
4093ece92f85SJason Jin offset = (s8)fetch_byte_imm();
4094ece92f85SJason Jin target = (u16)(M.x86.R_IP + offset);
4095ece92f85SJason Jin DECODE_PRINTF2("%x\n", target);
4096ece92f85SJason Jin TRACE_AND_STEP();
4097ece92f85SJason Jin if (M.x86.R_CX == 0)
4098ece92f85SJason Jin M.x86.R_IP = target;
4099ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4100ece92f85SJason Jin END_OF_INSTR();
4101ece92f85SJason Jin }
4102ece92f85SJason Jin
4103ece92f85SJason Jin /****************************************************************************
4104ece92f85SJason Jin REMARKS:
4105ece92f85SJason Jin Handles opcode 0xe4
4106ece92f85SJason Jin ****************************************************************************/
x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED (op1))4107ece92f85SJason Jin void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
4108ece92f85SJason Jin {
4109ece92f85SJason Jin u8 port;
4110ece92f85SJason Jin
4111ece92f85SJason Jin START_OF_INSTR();
4112ece92f85SJason Jin DECODE_PRINTF("IN\t");
4113ece92f85SJason Jin port = (u8) fetch_byte_imm();
4114ece92f85SJason Jin DECODE_PRINTF2("%x,AL\n", port);
4115ece92f85SJason Jin TRACE_AND_STEP();
4116ece92f85SJason Jin M.x86.R_AL = (*sys_inb)(port);
4117ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4118ece92f85SJason Jin END_OF_INSTR();
4119ece92f85SJason Jin }
4120ece92f85SJason Jin
4121ece92f85SJason Jin /****************************************************************************
4122ece92f85SJason Jin REMARKS:
4123ece92f85SJason Jin Handles opcode 0xe5
4124ece92f85SJason Jin ****************************************************************************/
x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED (op1))4125ece92f85SJason Jin void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
4126ece92f85SJason Jin {
4127ece92f85SJason Jin u8 port;
4128ece92f85SJason Jin
4129ece92f85SJason Jin START_OF_INSTR();
4130ece92f85SJason Jin DECODE_PRINTF("IN\t");
4131ece92f85SJason Jin port = (u8) fetch_byte_imm();
4132ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4133ece92f85SJason Jin DECODE_PRINTF2("EAX,%x\n", port);
4134ece92f85SJason Jin } else {
4135ece92f85SJason Jin DECODE_PRINTF2("AX,%x\n", port);
4136ece92f85SJason Jin }
4137ece92f85SJason Jin TRACE_AND_STEP();
4138ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4139ece92f85SJason Jin M.x86.R_EAX = (*sys_inl)(port);
4140ece92f85SJason Jin } else {
4141ece92f85SJason Jin M.x86.R_AX = (*sys_inw)(port);
4142ece92f85SJason Jin }
4143ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4144ece92f85SJason Jin END_OF_INSTR();
4145ece92f85SJason Jin }
4146ece92f85SJason Jin
4147ece92f85SJason Jin /****************************************************************************
4148ece92f85SJason Jin REMARKS:
4149ece92f85SJason Jin Handles opcode 0xe6
4150ece92f85SJason Jin ****************************************************************************/
x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED (op1))4151ece92f85SJason Jin void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
4152ece92f85SJason Jin {
4153ece92f85SJason Jin u8 port;
4154ece92f85SJason Jin
4155ece92f85SJason Jin START_OF_INSTR();
4156ece92f85SJason Jin DECODE_PRINTF("OUT\t");
4157ece92f85SJason Jin port = (u8) fetch_byte_imm();
4158ece92f85SJason Jin DECODE_PRINTF2("%x,AL\n", port);
4159ece92f85SJason Jin TRACE_AND_STEP();
4160ece92f85SJason Jin (*sys_outb)(port, M.x86.R_AL);
4161ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4162ece92f85SJason Jin END_OF_INSTR();
4163ece92f85SJason Jin }
4164ece92f85SJason Jin
4165ece92f85SJason Jin /****************************************************************************
4166ece92f85SJason Jin REMARKS:
4167ece92f85SJason Jin Handles opcode 0xe7
4168ece92f85SJason Jin ****************************************************************************/
x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED (op1))4169ece92f85SJason Jin void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
4170ece92f85SJason Jin {
4171ece92f85SJason Jin u8 port;
4172ece92f85SJason Jin
4173ece92f85SJason Jin START_OF_INSTR();
4174ece92f85SJason Jin DECODE_PRINTF("OUT\t");
4175ece92f85SJason Jin port = (u8) fetch_byte_imm();
4176ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4177ece92f85SJason Jin DECODE_PRINTF2("%x,EAX\n", port);
4178ece92f85SJason Jin } else {
4179ece92f85SJason Jin DECODE_PRINTF2("%x,AX\n", port);
4180ece92f85SJason Jin }
4181ece92f85SJason Jin TRACE_AND_STEP();
4182ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4183ece92f85SJason Jin (*sys_outl)(port, M.x86.R_EAX);
4184ece92f85SJason Jin } else {
4185ece92f85SJason Jin (*sys_outw)(port, M.x86.R_AX);
4186ece92f85SJason Jin }
4187ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4188ece92f85SJason Jin END_OF_INSTR();
4189ece92f85SJason Jin }
4190ece92f85SJason Jin
4191ece92f85SJason Jin /****************************************************************************
4192ece92f85SJason Jin REMARKS:
4193ece92f85SJason Jin Handles opcode 0xe8
4194ece92f85SJason Jin ****************************************************************************/
x86emuOp_call_near_IMM(u8 X86EMU_UNUSED (op1))4195ece92f85SJason Jin void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
4196ece92f85SJason Jin {
4197ece92f85SJason Jin s16 ip;
4198ece92f85SJason Jin
4199ece92f85SJason Jin START_OF_INSTR();
4200ece92f85SJason Jin DECODE_PRINTF("CALL\t");
4201ece92f85SJason Jin ip = (s16) fetch_word_imm();
4202ece92f85SJason Jin ip += (s16) M.x86.R_IP; /* CHECK SIGN */
4203ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip);
4204ece92f85SJason Jin CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
4205ece92f85SJason Jin TRACE_AND_STEP();
4206ece92f85SJason Jin push_word(M.x86.R_IP);
4207ece92f85SJason Jin M.x86.R_IP = ip;
4208ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4209ece92f85SJason Jin END_OF_INSTR();
4210ece92f85SJason Jin }
4211ece92f85SJason Jin
4212ece92f85SJason Jin /****************************************************************************
4213ece92f85SJason Jin REMARKS:
4214ece92f85SJason Jin Handles opcode 0xe9
4215ece92f85SJason Jin ****************************************************************************/
x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED (op1))4216ece92f85SJason Jin void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
4217ece92f85SJason Jin {
4218ece92f85SJason Jin int ip;
4219ece92f85SJason Jin
4220ece92f85SJason Jin START_OF_INSTR();
4221ece92f85SJason Jin DECODE_PRINTF("JMP\t");
4222ece92f85SJason Jin ip = (s16)fetch_word_imm();
4223ece92f85SJason Jin ip += (s16)M.x86.R_IP;
4224ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip);
4225ece92f85SJason Jin TRACE_AND_STEP();
4226ece92f85SJason Jin M.x86.R_IP = (u16)ip;
4227ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4228ece92f85SJason Jin END_OF_INSTR();
4229ece92f85SJason Jin }
4230ece92f85SJason Jin
4231ece92f85SJason Jin /****************************************************************************
4232ece92f85SJason Jin REMARKS:
4233ece92f85SJason Jin Handles opcode 0xea
4234ece92f85SJason Jin ****************************************************************************/
x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED (op1))4235ece92f85SJason Jin void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
4236ece92f85SJason Jin {
4237ece92f85SJason Jin u16 cs, ip;
4238ece92f85SJason Jin
4239ece92f85SJason Jin START_OF_INSTR();
4240ece92f85SJason Jin DECODE_PRINTF("JMP\tFAR ");
4241ece92f85SJason Jin ip = fetch_word_imm();
4242ece92f85SJason Jin cs = fetch_word_imm();
4243ece92f85SJason Jin DECODE_PRINTF2("%04x:", cs);
4244ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip);
4245ece92f85SJason Jin TRACE_AND_STEP();
4246ece92f85SJason Jin M.x86.R_IP = ip;
4247ece92f85SJason Jin M.x86.R_CS = cs;
4248ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4249ece92f85SJason Jin END_OF_INSTR();
4250ece92f85SJason Jin }
4251ece92f85SJason Jin
4252ece92f85SJason Jin /****************************************************************************
4253ece92f85SJason Jin REMARKS:
4254ece92f85SJason Jin Handles opcode 0xeb
4255ece92f85SJason Jin ****************************************************************************/
x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED (op1))4256ece92f85SJason Jin void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
4257ece92f85SJason Jin {
4258ece92f85SJason Jin u16 target;
4259ece92f85SJason Jin s8 offset;
4260ece92f85SJason Jin
4261ece92f85SJason Jin START_OF_INSTR();
4262ece92f85SJason Jin DECODE_PRINTF("JMP\t");
4263ece92f85SJason Jin offset = (s8)fetch_byte_imm();
4264ece92f85SJason Jin target = (u16)(M.x86.R_IP + offset);
4265ece92f85SJason Jin DECODE_PRINTF2("%x\n", target);
4266ece92f85SJason Jin TRACE_AND_STEP();
4267ece92f85SJason Jin M.x86.R_IP = target;
4268ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4269ece92f85SJason Jin END_OF_INSTR();
4270ece92f85SJason Jin }
4271ece92f85SJason Jin
4272ece92f85SJason Jin /****************************************************************************
4273ece92f85SJason Jin REMARKS:
4274ece92f85SJason Jin Handles opcode 0xec
4275ece92f85SJason Jin ****************************************************************************/
x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED (op1))4276ece92f85SJason Jin void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
4277ece92f85SJason Jin {
4278ece92f85SJason Jin START_OF_INSTR();
4279ece92f85SJason Jin DECODE_PRINTF("IN\tAL,DX\n");
4280ece92f85SJason Jin TRACE_AND_STEP();
4281ece92f85SJason Jin M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
4282ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4283ece92f85SJason Jin END_OF_INSTR();
4284ece92f85SJason Jin }
4285ece92f85SJason Jin
4286ece92f85SJason Jin /****************************************************************************
4287ece92f85SJason Jin REMARKS:
4288ece92f85SJason Jin Handles opcode 0xed
4289ece92f85SJason Jin ****************************************************************************/
x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED (op1))4290ece92f85SJason Jin void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
4291ece92f85SJason Jin {
4292ece92f85SJason Jin START_OF_INSTR();
4293ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4294ece92f85SJason Jin DECODE_PRINTF("IN\tEAX,DX\n");
4295ece92f85SJason Jin } else {
4296ece92f85SJason Jin DECODE_PRINTF("IN\tAX,DX\n");
4297ece92f85SJason Jin }
4298ece92f85SJason Jin TRACE_AND_STEP();
4299ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4300ece92f85SJason Jin M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
4301ece92f85SJason Jin } else {
4302ece92f85SJason Jin M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
4303ece92f85SJason Jin }
4304ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4305ece92f85SJason Jin END_OF_INSTR();
4306ece92f85SJason Jin }
4307ece92f85SJason Jin
4308ece92f85SJason Jin /****************************************************************************
4309ece92f85SJason Jin REMARKS:
4310ece92f85SJason Jin Handles opcode 0xee
4311ece92f85SJason Jin ****************************************************************************/
x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED (op1))4312ece92f85SJason Jin void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
4313ece92f85SJason Jin {
4314ece92f85SJason Jin START_OF_INSTR();
4315ece92f85SJason Jin DECODE_PRINTF("OUT\tDX,AL\n");
4316ece92f85SJason Jin TRACE_AND_STEP();
4317ece92f85SJason Jin (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
4318ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4319ece92f85SJason Jin END_OF_INSTR();
4320ece92f85SJason Jin }
4321ece92f85SJason Jin
4322ece92f85SJason Jin /****************************************************************************
4323ece92f85SJason Jin REMARKS:
4324ece92f85SJason Jin Handles opcode 0xef
4325ece92f85SJason Jin ****************************************************************************/
x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED (op1))4326ece92f85SJason Jin void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
4327ece92f85SJason Jin {
4328ece92f85SJason Jin START_OF_INSTR();
4329ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4330ece92f85SJason Jin DECODE_PRINTF("OUT\tDX,EAX\n");
4331ece92f85SJason Jin } else {
4332ece92f85SJason Jin DECODE_PRINTF("OUT\tDX,AX\n");
4333ece92f85SJason Jin }
4334ece92f85SJason Jin TRACE_AND_STEP();
4335ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4336ece92f85SJason Jin (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
4337ece92f85SJason Jin } else {
4338ece92f85SJason Jin (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
4339ece92f85SJason Jin }
4340ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4341ece92f85SJason Jin END_OF_INSTR();
4342ece92f85SJason Jin }
4343ece92f85SJason Jin
4344ece92f85SJason Jin /****************************************************************************
4345ece92f85SJason Jin REMARKS:
4346ece92f85SJason Jin Handles opcode 0xf0
4347ece92f85SJason Jin ****************************************************************************/
x86emuOp_lock(u8 X86EMU_UNUSED (op1))4348ece92f85SJason Jin void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
4349ece92f85SJason Jin {
4350ece92f85SJason Jin START_OF_INSTR();
4351ece92f85SJason Jin DECODE_PRINTF("LOCK:\n");
4352ece92f85SJason Jin TRACE_AND_STEP();
4353ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4354ece92f85SJason Jin END_OF_INSTR();
4355ece92f85SJason Jin }
4356ece92f85SJason Jin
4357ece92f85SJason Jin /*opcode 0xf1 ILLEGAL OPERATION */
4358ece92f85SJason Jin
4359ece92f85SJason Jin /****************************************************************************
4360ece92f85SJason Jin REMARKS:
4361ece92f85SJason Jin Handles opcode 0xf2
4362ece92f85SJason Jin ****************************************************************************/
x86emuOp_repne(u8 X86EMU_UNUSED (op1))4363ece92f85SJason Jin void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
4364ece92f85SJason Jin {
4365ece92f85SJason Jin START_OF_INSTR();
4366ece92f85SJason Jin DECODE_PRINTF("REPNE\n");
4367ece92f85SJason Jin TRACE_AND_STEP();
4368ece92f85SJason Jin M.x86.mode |= SYSMODE_PREFIX_REPNE;
4369ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4370ece92f85SJason Jin END_OF_INSTR();
4371ece92f85SJason Jin }
4372ece92f85SJason Jin
4373ece92f85SJason Jin /****************************************************************************
4374ece92f85SJason Jin REMARKS:
4375ece92f85SJason Jin Handles opcode 0xf3
4376ece92f85SJason Jin ****************************************************************************/
x86emuOp_repe(u8 X86EMU_UNUSED (op1))4377ece92f85SJason Jin void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
4378ece92f85SJason Jin {
4379ece92f85SJason Jin START_OF_INSTR();
4380ece92f85SJason Jin DECODE_PRINTF("REPE\n");
4381ece92f85SJason Jin TRACE_AND_STEP();
4382ece92f85SJason Jin M.x86.mode |= SYSMODE_PREFIX_REPE;
4383ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4384ece92f85SJason Jin END_OF_INSTR();
4385ece92f85SJason Jin }
4386ece92f85SJason Jin
4387ece92f85SJason Jin /****************************************************************************
4388ece92f85SJason Jin REMARKS:
4389ece92f85SJason Jin Handles opcode 0xf4
4390ece92f85SJason Jin ****************************************************************************/
x86emuOp_halt(u8 X86EMU_UNUSED (op1))4391ece92f85SJason Jin void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
4392ece92f85SJason Jin {
4393ece92f85SJason Jin START_OF_INSTR();
4394ece92f85SJason Jin DECODE_PRINTF("HALT\n");
4395ece92f85SJason Jin TRACE_AND_STEP();
4396ece92f85SJason Jin HALT_SYS();
4397ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4398ece92f85SJason Jin END_OF_INSTR();
4399ece92f85SJason Jin }
4400ece92f85SJason Jin
4401ece92f85SJason Jin /****************************************************************************
4402ece92f85SJason Jin REMARKS:
4403ece92f85SJason Jin Handles opcode 0xf5
4404ece92f85SJason Jin ****************************************************************************/
x86emuOp_cmc(u8 X86EMU_UNUSED (op1))4405ece92f85SJason Jin void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
4406ece92f85SJason Jin {
4407ece92f85SJason Jin /* complement the carry flag. */
4408ece92f85SJason Jin START_OF_INSTR();
4409ece92f85SJason Jin DECODE_PRINTF("CMC\n");
4410ece92f85SJason Jin TRACE_AND_STEP();
4411ece92f85SJason Jin TOGGLE_FLAG(F_CF);
4412ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4413ece92f85SJason Jin END_OF_INSTR();
4414ece92f85SJason Jin }
4415ece92f85SJason Jin
4416ece92f85SJason Jin /****************************************************************************
4417ece92f85SJason Jin REMARKS:
4418ece92f85SJason Jin Handles opcode 0xf6
4419ece92f85SJason Jin ****************************************************************************/
x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED (op1))4420ece92f85SJason Jin void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
4421ece92f85SJason Jin {
4422ece92f85SJason Jin int mod, rl, rh;
4423ece92f85SJason Jin u8 *destreg;
4424ece92f85SJason Jin uint destoffset;
4425ece92f85SJason Jin u8 destval, srcval;
4426ece92f85SJason Jin
4427ece92f85SJason Jin /* long, drawn out code follows. Double switch for a total
4428ece92f85SJason Jin of 32 cases. */
4429ece92f85SJason Jin START_OF_INSTR();
4430ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
4431ece92f85SJason Jin DECODE_PRINTF(opF6_names[rh]);
4432ece92f85SJason Jin if (mod < 3) {
4433ece92f85SJason Jin DECODE_PRINTF("BYTE PTR ");
4434ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
4435ece92f85SJason Jin destval = fetch_data_byte(destoffset);
4436ece92f85SJason Jin
4437ece92f85SJason Jin switch (rh) {
4438ece92f85SJason Jin case 0: /* test byte imm */
4439ece92f85SJason Jin DECODE_PRINTF(",");
4440ece92f85SJason Jin srcval = fetch_byte_imm();
4441ece92f85SJason Jin DECODE_PRINTF2("%02x\n", srcval);
4442ece92f85SJason Jin TRACE_AND_STEP();
4443ece92f85SJason Jin test_byte(destval, srcval);
4444ece92f85SJason Jin break;
4445ece92f85SJason Jin case 1:
44468c6ec412SSimon Glass ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4447ece92f85SJason Jin HALT_SYS();
4448ece92f85SJason Jin break;
4449ece92f85SJason Jin case 2:
4450ece92f85SJason Jin DECODE_PRINTF("\n");
4451ece92f85SJason Jin TRACE_AND_STEP();
4452ece92f85SJason Jin destval = not_byte(destval);
4453ece92f85SJason Jin store_data_byte(destoffset, destval);
4454ece92f85SJason Jin break;
4455ece92f85SJason Jin case 3:
4456ece92f85SJason Jin DECODE_PRINTF("\n");
4457ece92f85SJason Jin TRACE_AND_STEP();
4458ece92f85SJason Jin destval = neg_byte(destval);
4459ece92f85SJason Jin store_data_byte(destoffset, destval);
4460ece92f85SJason Jin break;
4461ece92f85SJason Jin case 4:
4462ece92f85SJason Jin DECODE_PRINTF("\n");
4463ece92f85SJason Jin TRACE_AND_STEP();
4464ece92f85SJason Jin mul_byte(destval);
4465ece92f85SJason Jin break;
4466ece92f85SJason Jin case 5:
4467ece92f85SJason Jin DECODE_PRINTF("\n");
4468ece92f85SJason Jin TRACE_AND_STEP();
4469ece92f85SJason Jin imul_byte(destval);
4470ece92f85SJason Jin break;
4471ece92f85SJason Jin case 6:
4472ece92f85SJason Jin DECODE_PRINTF("\n");
4473ece92f85SJason Jin TRACE_AND_STEP();
4474ece92f85SJason Jin div_byte(destval);
4475ece92f85SJason Jin break;
4476ece92f85SJason Jin default:
4477ece92f85SJason Jin DECODE_PRINTF("\n");
4478ece92f85SJason Jin TRACE_AND_STEP();
4479ece92f85SJason Jin idiv_byte(destval);
4480ece92f85SJason Jin break;
4481ece92f85SJason Jin }
4482ece92f85SJason Jin } else { /* mod=11 */
4483ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
4484ece92f85SJason Jin switch (rh) {
4485ece92f85SJason Jin case 0: /* test byte imm */
4486ece92f85SJason Jin DECODE_PRINTF(",");
4487ece92f85SJason Jin srcval = fetch_byte_imm();
4488ece92f85SJason Jin DECODE_PRINTF2("%02x\n", srcval);
4489ece92f85SJason Jin TRACE_AND_STEP();
4490ece92f85SJason Jin test_byte(*destreg, srcval);
4491ece92f85SJason Jin break;
4492ece92f85SJason Jin case 1:
44938c6ec412SSimon Glass ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4494ece92f85SJason Jin HALT_SYS();
4495ece92f85SJason Jin break;
4496ece92f85SJason Jin case 2:
4497ece92f85SJason Jin DECODE_PRINTF("\n");
4498ece92f85SJason Jin TRACE_AND_STEP();
4499ece92f85SJason Jin *destreg = not_byte(*destreg);
4500ece92f85SJason Jin break;
4501ece92f85SJason Jin case 3:
4502ece92f85SJason Jin DECODE_PRINTF("\n");
4503ece92f85SJason Jin TRACE_AND_STEP();
4504ece92f85SJason Jin *destreg = neg_byte(*destreg);
4505ece92f85SJason Jin break;
4506ece92f85SJason Jin case 4:
4507ece92f85SJason Jin DECODE_PRINTF("\n");
4508ece92f85SJason Jin TRACE_AND_STEP();
4509ece92f85SJason Jin mul_byte(*destreg); /*!!! */
4510ece92f85SJason Jin break;
4511ece92f85SJason Jin case 5:
4512ece92f85SJason Jin DECODE_PRINTF("\n");
4513ece92f85SJason Jin TRACE_AND_STEP();
4514ece92f85SJason Jin imul_byte(*destreg);
4515ece92f85SJason Jin break;
4516ece92f85SJason Jin case 6:
4517ece92f85SJason Jin DECODE_PRINTF("\n");
4518ece92f85SJason Jin TRACE_AND_STEP();
4519ece92f85SJason Jin div_byte(*destreg);
4520ece92f85SJason Jin break;
4521ece92f85SJason Jin default:
4522ece92f85SJason Jin DECODE_PRINTF("\n");
4523ece92f85SJason Jin TRACE_AND_STEP();
4524ece92f85SJason Jin idiv_byte(*destreg);
4525ece92f85SJason Jin break;
4526ece92f85SJason Jin }
4527ece92f85SJason Jin }
4528ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4529ece92f85SJason Jin END_OF_INSTR();
4530ece92f85SJason Jin }
4531ece92f85SJason Jin
4532ece92f85SJason Jin /****************************************************************************
4533ece92f85SJason Jin REMARKS:
4534ece92f85SJason Jin Handles opcode 0xf7
4535ece92f85SJason Jin ****************************************************************************/
x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED (op1))4536ece92f85SJason Jin void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
4537ece92f85SJason Jin {
4538ece92f85SJason Jin int mod, rl, rh;
4539ece92f85SJason Jin uint destoffset;
4540ece92f85SJason Jin
4541ece92f85SJason Jin START_OF_INSTR();
4542ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
4543ece92f85SJason Jin DECODE_PRINTF(opF6_names[rh]);
4544ece92f85SJason Jin if (mod < 3) {
4545ece92f85SJason Jin
4546ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4547ece92f85SJason Jin u32 destval, srcval;
4548ece92f85SJason Jin
4549ece92f85SJason Jin DECODE_PRINTF("DWORD PTR ");
4550ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
4551ece92f85SJason Jin destval = fetch_data_long(destoffset);
4552ece92f85SJason Jin
4553ece92f85SJason Jin switch (rh) {
4554ece92f85SJason Jin case 0:
4555ece92f85SJason Jin DECODE_PRINTF(",");
4556ece92f85SJason Jin srcval = fetch_long_imm();
4557ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval);
4558ece92f85SJason Jin TRACE_AND_STEP();
4559ece92f85SJason Jin test_long(destval, srcval);
4560ece92f85SJason Jin break;
4561ece92f85SJason Jin case 1:
45628c6ec412SSimon Glass ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
4563ece92f85SJason Jin HALT_SYS();
4564ece92f85SJason Jin break;
4565ece92f85SJason Jin case 2:
4566ece92f85SJason Jin DECODE_PRINTF("\n");
4567ece92f85SJason Jin TRACE_AND_STEP();
4568ece92f85SJason Jin destval = not_long(destval);
4569ece92f85SJason Jin store_data_long(destoffset, destval);
4570ece92f85SJason Jin break;
4571ece92f85SJason Jin case 3:
4572ece92f85SJason Jin DECODE_PRINTF("\n");
4573ece92f85SJason Jin TRACE_AND_STEP();
4574ece92f85SJason Jin destval = neg_long(destval);
4575ece92f85SJason Jin store_data_long(destoffset, destval);
4576ece92f85SJason Jin break;
4577ece92f85SJason Jin case 4:
4578ece92f85SJason Jin DECODE_PRINTF("\n");
4579ece92f85SJason Jin TRACE_AND_STEP();
4580ece92f85SJason Jin mul_long(destval);
4581ece92f85SJason Jin break;
4582ece92f85SJason Jin case 5:
4583ece92f85SJason Jin DECODE_PRINTF("\n");
4584ece92f85SJason Jin TRACE_AND_STEP();
4585ece92f85SJason Jin imul_long(destval);
4586ece92f85SJason Jin break;
4587ece92f85SJason Jin case 6:
4588ece92f85SJason Jin DECODE_PRINTF("\n");
4589ece92f85SJason Jin TRACE_AND_STEP();
4590ece92f85SJason Jin div_long(destval);
4591ece92f85SJason Jin break;
4592ece92f85SJason Jin case 7:
4593ece92f85SJason Jin DECODE_PRINTF("\n");
4594ece92f85SJason Jin TRACE_AND_STEP();
4595ece92f85SJason Jin idiv_long(destval);
4596ece92f85SJason Jin break;
4597ece92f85SJason Jin }
4598ece92f85SJason Jin } else {
4599ece92f85SJason Jin u16 destval, srcval;
4600ece92f85SJason Jin
4601ece92f85SJason Jin DECODE_PRINTF("WORD PTR ");
4602ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
4603ece92f85SJason Jin destval = fetch_data_word(destoffset);
4604ece92f85SJason Jin
4605ece92f85SJason Jin switch (rh) {
4606ece92f85SJason Jin case 0: /* test word imm */
4607ece92f85SJason Jin DECODE_PRINTF(",");
4608ece92f85SJason Jin srcval = fetch_word_imm();
4609ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval);
4610ece92f85SJason Jin TRACE_AND_STEP();
4611ece92f85SJason Jin test_word(destval, srcval);
4612ece92f85SJason Jin break;
4613ece92f85SJason Jin case 1:
46148c6ec412SSimon Glass ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
4615ece92f85SJason Jin HALT_SYS();
4616ece92f85SJason Jin break;
4617ece92f85SJason Jin case 2:
4618ece92f85SJason Jin DECODE_PRINTF("\n");
4619ece92f85SJason Jin TRACE_AND_STEP();
4620ece92f85SJason Jin destval = not_word(destval);
4621ece92f85SJason Jin store_data_word(destoffset, destval);
4622ece92f85SJason Jin break;
4623ece92f85SJason Jin case 3:
4624ece92f85SJason Jin DECODE_PRINTF("\n");
4625ece92f85SJason Jin TRACE_AND_STEP();
4626ece92f85SJason Jin destval = neg_word(destval);
4627ece92f85SJason Jin store_data_word(destoffset, destval);
4628ece92f85SJason Jin break;
4629ece92f85SJason Jin case 4:
4630ece92f85SJason Jin DECODE_PRINTF("\n");
4631ece92f85SJason Jin TRACE_AND_STEP();
4632ece92f85SJason Jin mul_word(destval);
4633ece92f85SJason Jin break;
4634ece92f85SJason Jin case 5:
4635ece92f85SJason Jin DECODE_PRINTF("\n");
4636ece92f85SJason Jin TRACE_AND_STEP();
4637ece92f85SJason Jin imul_word(destval);
4638ece92f85SJason Jin break;
4639ece92f85SJason Jin case 6:
4640ece92f85SJason Jin DECODE_PRINTF("\n");
4641ece92f85SJason Jin TRACE_AND_STEP();
4642ece92f85SJason Jin div_word(destval);
4643ece92f85SJason Jin break;
4644ece92f85SJason Jin case 7:
4645ece92f85SJason Jin DECODE_PRINTF("\n");
4646ece92f85SJason Jin TRACE_AND_STEP();
4647ece92f85SJason Jin idiv_word(destval);
4648ece92f85SJason Jin break;
4649ece92f85SJason Jin }
4650ece92f85SJason Jin }
4651ece92f85SJason Jin
4652ece92f85SJason Jin } else { /* mod=11 */
4653ece92f85SJason Jin
4654ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4655ece92f85SJason Jin u32 *destreg;
4656ece92f85SJason Jin u32 srcval;
4657ece92f85SJason Jin
4658ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
4659ece92f85SJason Jin
4660ece92f85SJason Jin switch (rh) {
4661ece92f85SJason Jin case 0: /* test word imm */
4662ece92f85SJason Jin DECODE_PRINTF(",");
4663ece92f85SJason Jin srcval = fetch_long_imm();
4664ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval);
4665ece92f85SJason Jin TRACE_AND_STEP();
4666ece92f85SJason Jin test_long(*destreg, srcval);
4667ece92f85SJason Jin break;
4668ece92f85SJason Jin case 1:
46698c6ec412SSimon Glass ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4670ece92f85SJason Jin HALT_SYS();
4671ece92f85SJason Jin break;
4672ece92f85SJason Jin case 2:
4673ece92f85SJason Jin DECODE_PRINTF("\n");
4674ece92f85SJason Jin TRACE_AND_STEP();
4675ece92f85SJason Jin *destreg = not_long(*destreg);
4676ece92f85SJason Jin break;
4677ece92f85SJason Jin case 3:
4678ece92f85SJason Jin DECODE_PRINTF("\n");
4679ece92f85SJason Jin TRACE_AND_STEP();
4680ece92f85SJason Jin *destreg = neg_long(*destreg);
4681ece92f85SJason Jin break;
4682ece92f85SJason Jin case 4:
4683ece92f85SJason Jin DECODE_PRINTF("\n");
4684ece92f85SJason Jin TRACE_AND_STEP();
4685ece92f85SJason Jin mul_long(*destreg); /*!!! */
4686ece92f85SJason Jin break;
4687ece92f85SJason Jin case 5:
4688ece92f85SJason Jin DECODE_PRINTF("\n");
4689ece92f85SJason Jin TRACE_AND_STEP();
4690ece92f85SJason Jin imul_long(*destreg);
4691ece92f85SJason Jin break;
4692ece92f85SJason Jin case 6:
4693ece92f85SJason Jin DECODE_PRINTF("\n");
4694ece92f85SJason Jin TRACE_AND_STEP();
4695ece92f85SJason Jin div_long(*destreg);
4696ece92f85SJason Jin break;
4697ece92f85SJason Jin case 7:
4698ece92f85SJason Jin DECODE_PRINTF("\n");
4699ece92f85SJason Jin TRACE_AND_STEP();
4700ece92f85SJason Jin idiv_long(*destreg);
4701ece92f85SJason Jin break;
4702ece92f85SJason Jin }
4703ece92f85SJason Jin } else {
4704ece92f85SJason Jin u16 *destreg;
4705ece92f85SJason Jin u16 srcval;
4706ece92f85SJason Jin
4707ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
4708ece92f85SJason Jin
4709ece92f85SJason Jin switch (rh) {
4710ece92f85SJason Jin case 0: /* test word imm */
4711ece92f85SJason Jin DECODE_PRINTF(",");
4712ece92f85SJason Jin srcval = fetch_word_imm();
4713ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval);
4714ece92f85SJason Jin TRACE_AND_STEP();
4715ece92f85SJason Jin test_word(*destreg, srcval);
4716ece92f85SJason Jin break;
4717ece92f85SJason Jin case 1:
47188c6ec412SSimon Glass ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4719ece92f85SJason Jin HALT_SYS();
4720ece92f85SJason Jin break;
4721ece92f85SJason Jin case 2:
4722ece92f85SJason Jin DECODE_PRINTF("\n");
4723ece92f85SJason Jin TRACE_AND_STEP();
4724ece92f85SJason Jin *destreg = not_word(*destreg);
4725ece92f85SJason Jin break;
4726ece92f85SJason Jin case 3:
4727ece92f85SJason Jin DECODE_PRINTF("\n");
4728ece92f85SJason Jin TRACE_AND_STEP();
4729ece92f85SJason Jin *destreg = neg_word(*destreg);
4730ece92f85SJason Jin break;
4731ece92f85SJason Jin case 4:
4732ece92f85SJason Jin DECODE_PRINTF("\n");
4733ece92f85SJason Jin TRACE_AND_STEP();
4734ece92f85SJason Jin mul_word(*destreg); /*!!! */
4735ece92f85SJason Jin break;
4736ece92f85SJason Jin case 5:
4737ece92f85SJason Jin DECODE_PRINTF("\n");
4738ece92f85SJason Jin TRACE_AND_STEP();
4739ece92f85SJason Jin imul_word(*destreg);
4740ece92f85SJason Jin break;
4741ece92f85SJason Jin case 6:
4742ece92f85SJason Jin DECODE_PRINTF("\n");
4743ece92f85SJason Jin TRACE_AND_STEP();
4744ece92f85SJason Jin div_word(*destreg);
4745ece92f85SJason Jin break;
4746ece92f85SJason Jin case 7:
4747ece92f85SJason Jin DECODE_PRINTF("\n");
4748ece92f85SJason Jin TRACE_AND_STEP();
4749ece92f85SJason Jin idiv_word(*destreg);
4750ece92f85SJason Jin break;
4751ece92f85SJason Jin }
4752ece92f85SJason Jin }
4753ece92f85SJason Jin }
4754ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4755ece92f85SJason Jin END_OF_INSTR();
4756ece92f85SJason Jin }
4757ece92f85SJason Jin
4758ece92f85SJason Jin /****************************************************************************
4759ece92f85SJason Jin REMARKS:
4760ece92f85SJason Jin Handles opcode 0xf8
4761ece92f85SJason Jin ****************************************************************************/
x86emuOp_clc(u8 X86EMU_UNUSED (op1))4762ece92f85SJason Jin void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
4763ece92f85SJason Jin {
4764ece92f85SJason Jin /* clear the carry flag. */
4765ece92f85SJason Jin START_OF_INSTR();
4766ece92f85SJason Jin DECODE_PRINTF("CLC\n");
4767ece92f85SJason Jin TRACE_AND_STEP();
4768ece92f85SJason Jin CLEAR_FLAG(F_CF);
4769ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4770ece92f85SJason Jin END_OF_INSTR();
4771ece92f85SJason Jin }
4772ece92f85SJason Jin
4773ece92f85SJason Jin /****************************************************************************
4774ece92f85SJason Jin REMARKS:
4775ece92f85SJason Jin Handles opcode 0xf9
4776ece92f85SJason Jin ****************************************************************************/
x86emuOp_stc(u8 X86EMU_UNUSED (op1))4777ece92f85SJason Jin void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
4778ece92f85SJason Jin {
4779ece92f85SJason Jin /* set the carry flag. */
4780ece92f85SJason Jin START_OF_INSTR();
4781ece92f85SJason Jin DECODE_PRINTF("STC\n");
4782ece92f85SJason Jin TRACE_AND_STEP();
4783ece92f85SJason Jin SET_FLAG(F_CF);
4784ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4785ece92f85SJason Jin END_OF_INSTR();
4786ece92f85SJason Jin }
4787ece92f85SJason Jin
4788ece92f85SJason Jin /****************************************************************************
4789ece92f85SJason Jin REMARKS:
4790ece92f85SJason Jin Handles opcode 0xfa
4791ece92f85SJason Jin ****************************************************************************/
x86emuOp_cli(u8 X86EMU_UNUSED (op1))4792ece92f85SJason Jin void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
4793ece92f85SJason Jin {
4794ece92f85SJason Jin /* clear interrupts. */
4795ece92f85SJason Jin START_OF_INSTR();
4796ece92f85SJason Jin DECODE_PRINTF("CLI\n");
4797ece92f85SJason Jin TRACE_AND_STEP();
4798ece92f85SJason Jin CLEAR_FLAG(F_IF);
4799ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4800ece92f85SJason Jin END_OF_INSTR();
4801ece92f85SJason Jin }
4802ece92f85SJason Jin
4803ece92f85SJason Jin /****************************************************************************
4804ece92f85SJason Jin REMARKS:
4805ece92f85SJason Jin Handles opcode 0xfb
4806ece92f85SJason Jin ****************************************************************************/
x86emuOp_sti(u8 X86EMU_UNUSED (op1))4807ece92f85SJason Jin void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
4808ece92f85SJason Jin {
4809ece92f85SJason Jin /* enable interrupts. */
4810ece92f85SJason Jin START_OF_INSTR();
4811ece92f85SJason Jin DECODE_PRINTF("STI\n");
4812ece92f85SJason Jin TRACE_AND_STEP();
4813ece92f85SJason Jin SET_FLAG(F_IF);
4814ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4815ece92f85SJason Jin END_OF_INSTR();
4816ece92f85SJason Jin }
4817ece92f85SJason Jin
4818ece92f85SJason Jin /****************************************************************************
4819ece92f85SJason Jin REMARKS:
4820ece92f85SJason Jin Handles opcode 0xfc
4821ece92f85SJason Jin ****************************************************************************/
x86emuOp_cld(u8 X86EMU_UNUSED (op1))4822ece92f85SJason Jin void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
4823ece92f85SJason Jin {
4824ece92f85SJason Jin /* clear interrupts. */
4825ece92f85SJason Jin START_OF_INSTR();
4826ece92f85SJason Jin DECODE_PRINTF("CLD\n");
4827ece92f85SJason Jin TRACE_AND_STEP();
4828ece92f85SJason Jin CLEAR_FLAG(F_DF);
4829ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4830ece92f85SJason Jin END_OF_INSTR();
4831ece92f85SJason Jin }
4832ece92f85SJason Jin
4833ece92f85SJason Jin /****************************************************************************
4834ece92f85SJason Jin REMARKS:
4835ece92f85SJason Jin Handles opcode 0xfd
4836ece92f85SJason Jin ****************************************************************************/
x86emuOp_std(u8 X86EMU_UNUSED (op1))4837ece92f85SJason Jin void x86emuOp_std(u8 X86EMU_UNUSED(op1))
4838ece92f85SJason Jin {
4839ece92f85SJason Jin /* clear interrupts. */
4840ece92f85SJason Jin START_OF_INSTR();
4841ece92f85SJason Jin DECODE_PRINTF("STD\n");
4842ece92f85SJason Jin TRACE_AND_STEP();
4843ece92f85SJason Jin SET_FLAG(F_DF);
4844ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4845ece92f85SJason Jin END_OF_INSTR();
4846ece92f85SJason Jin }
4847ece92f85SJason Jin
4848ece92f85SJason Jin /****************************************************************************
4849ece92f85SJason Jin REMARKS:
4850ece92f85SJason Jin Handles opcode 0xfe
4851ece92f85SJason Jin ****************************************************************************/
x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED (op1))4852ece92f85SJason Jin void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
4853ece92f85SJason Jin {
4854ece92f85SJason Jin int mod, rh, rl;
4855ece92f85SJason Jin u8 destval;
4856ece92f85SJason Jin uint destoffset;
4857ece92f85SJason Jin u8 *destreg;
4858ece92f85SJason Jin
4859ece92f85SJason Jin /* Yet another special case instruction. */
4860ece92f85SJason Jin START_OF_INSTR();
4861ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
4862b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
4863ece92f85SJason Jin if (DEBUG_DECODE()) {
4864ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
4865ece92f85SJason Jin general, so that it is important to leave the strings
4866ece92f85SJason Jin in the same format, even though the result is that the
4867ece92f85SJason Jin above test is done twice. */
4868ece92f85SJason Jin
4869ece92f85SJason Jin switch (rh) {
4870ece92f85SJason Jin case 0:
4871ece92f85SJason Jin DECODE_PRINTF("INC\t");
4872ece92f85SJason Jin break;
4873ece92f85SJason Jin case 1:
4874ece92f85SJason Jin DECODE_PRINTF("DEC\t");
4875ece92f85SJason Jin break;
4876ece92f85SJason Jin case 2:
4877ece92f85SJason Jin case 3:
4878ece92f85SJason Jin case 4:
4879ece92f85SJason Jin case 5:
4880ece92f85SJason Jin case 6:
4881ece92f85SJason Jin case 7:
48828c6ec412SSimon Glass ERR_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x\n", mod);
4883ece92f85SJason Jin HALT_SYS();
4884ece92f85SJason Jin break;
4885ece92f85SJason Jin }
4886ece92f85SJason Jin }
4887ece92f85SJason Jin #endif
4888ece92f85SJason Jin if (mod < 3) {
4889ece92f85SJason Jin DECODE_PRINTF("BYTE PTR ");
4890ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
4891ece92f85SJason Jin DECODE_PRINTF("\n");
4892ece92f85SJason Jin destval = fetch_data_byte(destoffset);
4893ece92f85SJason Jin TRACE_AND_STEP();
4894ece92f85SJason Jin if (rh == 0)
4895ece92f85SJason Jin destval = inc_byte(destval);
4896ece92f85SJason Jin else
4897ece92f85SJason Jin destval = dec_byte(destval);
4898ece92f85SJason Jin store_data_byte(destoffset, destval);
4899ece92f85SJason Jin } else {
4900ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
4901ece92f85SJason Jin DECODE_PRINTF("\n");
4902ece92f85SJason Jin TRACE_AND_STEP();
4903ece92f85SJason Jin if (rh == 0)
4904ece92f85SJason Jin *destreg = inc_byte(*destreg);
4905ece92f85SJason Jin else
4906ece92f85SJason Jin *destreg = dec_byte(*destreg);
4907ece92f85SJason Jin }
4908ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
4909ece92f85SJason Jin END_OF_INSTR();
4910ece92f85SJason Jin }
4911ece92f85SJason Jin
4912ece92f85SJason Jin /****************************************************************************
4913ece92f85SJason Jin REMARKS:
4914ece92f85SJason Jin Handles opcode 0xff
4915ece92f85SJason Jin ****************************************************************************/
x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED (op1))4916ece92f85SJason Jin void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
4917ece92f85SJason Jin {
4918ece92f85SJason Jin int mod, rh, rl;
4919ece92f85SJason Jin uint destoffset = 0;
4920ece92f85SJason Jin u16 *destreg;
4921ece92f85SJason Jin u16 destval,destval2;
4922ece92f85SJason Jin
4923ece92f85SJason Jin /* Yet another special case instruction. */
4924ece92f85SJason Jin START_OF_INSTR();
4925ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
4926b3521f2eSSimon Glass #ifdef CONFIG_X86EMU_DEBUG
4927ece92f85SJason Jin if (DEBUG_DECODE()) {
4928ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more
4929ece92f85SJason Jin general, so that it is important to leave the strings
4930ece92f85SJason Jin in the same format, even though the result is that the
4931ece92f85SJason Jin above test is done twice. */
4932ece92f85SJason Jin
4933ece92f85SJason Jin switch (rh) {
4934ece92f85SJason Jin case 0:
4935ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4936ece92f85SJason Jin DECODE_PRINTF("INC\tDWORD PTR ");
4937ece92f85SJason Jin } else {
4938ece92f85SJason Jin DECODE_PRINTF("INC\tWORD PTR ");
4939ece92f85SJason Jin }
4940ece92f85SJason Jin break;
4941ece92f85SJason Jin case 1:
4942ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4943ece92f85SJason Jin DECODE_PRINTF("DEC\tDWORD PTR ");
4944ece92f85SJason Jin } else {
4945ece92f85SJason Jin DECODE_PRINTF("DEC\tWORD PTR ");
4946ece92f85SJason Jin }
4947ece92f85SJason Jin break;
4948ece92f85SJason Jin case 2:
4949ece92f85SJason Jin DECODE_PRINTF("CALL\t ");
4950ece92f85SJason Jin break;
4951ece92f85SJason Jin case 3:
4952ece92f85SJason Jin DECODE_PRINTF("CALL\tFAR ");
4953ece92f85SJason Jin break;
4954ece92f85SJason Jin case 4:
4955ece92f85SJason Jin DECODE_PRINTF("JMP\t");
4956ece92f85SJason Jin break;
4957ece92f85SJason Jin case 5:
4958ece92f85SJason Jin DECODE_PRINTF("JMP\tFAR ");
4959ece92f85SJason Jin break;
4960ece92f85SJason Jin case 6:
4961ece92f85SJason Jin DECODE_PRINTF("PUSH\t");
4962ece92f85SJason Jin break;
4963ece92f85SJason Jin case 7:
49648c6ec412SSimon Glass ERR_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
4965ece92f85SJason Jin HALT_SYS();
4966ece92f85SJason Jin break;
4967ece92f85SJason Jin }
4968ece92f85SJason Jin }
4969ece92f85SJason Jin #endif
4970ece92f85SJason Jin if (mod < 3) {
4971ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
4972ece92f85SJason Jin DECODE_PRINTF("\n");
4973ece92f85SJason Jin switch (rh) {
4974ece92f85SJason Jin case 0: /* inc word ptr ... */
4975ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4976ece92f85SJason Jin u32 destval;
4977ece92f85SJason Jin
4978ece92f85SJason Jin destval = fetch_data_long(destoffset);
4979ece92f85SJason Jin TRACE_AND_STEP();
4980ece92f85SJason Jin destval = inc_long(destval);
4981ece92f85SJason Jin store_data_long(destoffset, destval);
4982ece92f85SJason Jin } else {
4983ece92f85SJason Jin u16 destval;
4984ece92f85SJason Jin
4985ece92f85SJason Jin destval = fetch_data_word(destoffset);
4986ece92f85SJason Jin TRACE_AND_STEP();
4987ece92f85SJason Jin destval = inc_word(destval);
4988ece92f85SJason Jin store_data_word(destoffset, destval);
4989ece92f85SJason Jin }
4990ece92f85SJason Jin break;
4991ece92f85SJason Jin case 1: /* dec word ptr ... */
4992ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4993ece92f85SJason Jin u32 destval;
4994ece92f85SJason Jin
4995ece92f85SJason Jin destval = fetch_data_long(destoffset);
4996ece92f85SJason Jin TRACE_AND_STEP();
4997ece92f85SJason Jin destval = dec_long(destval);
4998ece92f85SJason Jin store_data_long(destoffset, destval);
4999ece92f85SJason Jin } else {
5000ece92f85SJason Jin u16 destval;
5001ece92f85SJason Jin
5002ece92f85SJason Jin destval = fetch_data_word(destoffset);
5003ece92f85SJason Jin TRACE_AND_STEP();
5004ece92f85SJason Jin destval = dec_word(destval);
5005ece92f85SJason Jin store_data_word(destoffset, destval);
5006ece92f85SJason Jin }
5007ece92f85SJason Jin break;
5008ece92f85SJason Jin case 2: /* call word ptr ... */
5009ece92f85SJason Jin destval = fetch_data_word(destoffset);
5010ece92f85SJason Jin TRACE_AND_STEP();
5011ece92f85SJason Jin push_word(M.x86.R_IP);
5012ece92f85SJason Jin M.x86.R_IP = destval;
5013ece92f85SJason Jin break;
5014ece92f85SJason Jin case 3: /* call far ptr ... */
5015ece92f85SJason Jin destval = fetch_data_word(destoffset);
5016ece92f85SJason Jin destval2 = fetch_data_word(destoffset + 2);
5017ece92f85SJason Jin TRACE_AND_STEP();
5018ece92f85SJason Jin push_word(M.x86.R_CS);
5019ece92f85SJason Jin M.x86.R_CS = destval2;
5020ece92f85SJason Jin push_word(M.x86.R_IP);
5021ece92f85SJason Jin M.x86.R_IP = destval;
5022ece92f85SJason Jin break;
5023ece92f85SJason Jin case 4: /* jmp word ptr ... */
5024ece92f85SJason Jin destval = fetch_data_word(destoffset);
5025ece92f85SJason Jin TRACE_AND_STEP();
5026ece92f85SJason Jin M.x86.R_IP = destval;
5027ece92f85SJason Jin break;
5028ece92f85SJason Jin case 5: /* jmp far ptr ... */
5029ece92f85SJason Jin destval = fetch_data_word(destoffset);
5030ece92f85SJason Jin destval2 = fetch_data_word(destoffset + 2);
5031ece92f85SJason Jin TRACE_AND_STEP();
5032ece92f85SJason Jin M.x86.R_IP = destval;
5033ece92f85SJason Jin M.x86.R_CS = destval2;
5034ece92f85SJason Jin break;
5035ece92f85SJason Jin case 6: /* push word ptr ... */
5036ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5037ece92f85SJason Jin u32 destval;
5038ece92f85SJason Jin
5039ece92f85SJason Jin destval = fetch_data_long(destoffset);
5040ece92f85SJason Jin TRACE_AND_STEP();
5041ece92f85SJason Jin push_long(destval);
5042ece92f85SJason Jin } else {
5043ece92f85SJason Jin u16 destval;
5044ece92f85SJason Jin
5045ece92f85SJason Jin destval = fetch_data_word(destoffset);
5046ece92f85SJason Jin TRACE_AND_STEP();
5047ece92f85SJason Jin push_word(destval);
5048ece92f85SJason Jin }
5049ece92f85SJason Jin break;
5050ece92f85SJason Jin }
5051ece92f85SJason Jin } else {
5052ece92f85SJason Jin switch (rh) {
5053ece92f85SJason Jin case 0:
5054ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5055ece92f85SJason Jin u32 *destreg;
5056ece92f85SJason Jin
5057ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
5058ece92f85SJason Jin DECODE_PRINTF("\n");
5059ece92f85SJason Jin TRACE_AND_STEP();
5060ece92f85SJason Jin *destreg = inc_long(*destreg);
5061ece92f85SJason Jin } else {
5062ece92f85SJason Jin u16 *destreg;
5063ece92f85SJason Jin
5064ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
5065ece92f85SJason Jin DECODE_PRINTF("\n");
5066ece92f85SJason Jin TRACE_AND_STEP();
5067ece92f85SJason Jin *destreg = inc_word(*destreg);
5068ece92f85SJason Jin }
5069ece92f85SJason Jin break;
5070ece92f85SJason Jin case 1:
5071ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5072ece92f85SJason Jin u32 *destreg;
5073ece92f85SJason Jin
5074ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
5075ece92f85SJason Jin DECODE_PRINTF("\n");
5076ece92f85SJason Jin TRACE_AND_STEP();
5077ece92f85SJason Jin *destreg = dec_long(*destreg);
5078ece92f85SJason Jin } else {
5079ece92f85SJason Jin u16 *destreg;
5080ece92f85SJason Jin
5081ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
5082ece92f85SJason Jin DECODE_PRINTF("\n");
5083ece92f85SJason Jin TRACE_AND_STEP();
5084ece92f85SJason Jin *destreg = dec_word(*destreg);
5085ece92f85SJason Jin }
5086ece92f85SJason Jin break;
5087ece92f85SJason Jin case 2: /* call word ptr ... */
5088ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
5089ece92f85SJason Jin DECODE_PRINTF("\n");
5090ece92f85SJason Jin TRACE_AND_STEP();
5091ece92f85SJason Jin push_word(M.x86.R_IP);
5092ece92f85SJason Jin M.x86.R_IP = *destreg;
5093ece92f85SJason Jin break;
5094ece92f85SJason Jin case 3: /* jmp far ptr ... */
50958c6ec412SSimon Glass ERR_PRINTF("OPERATION UNDEFINED 0XFF\n");
5096ece92f85SJason Jin TRACE_AND_STEP();
5097ece92f85SJason Jin HALT_SYS();
5098ece92f85SJason Jin break;
5099ece92f85SJason Jin
5100ece92f85SJason Jin case 4: /* jmp ... */
5101ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
5102ece92f85SJason Jin DECODE_PRINTF("\n");
5103ece92f85SJason Jin TRACE_AND_STEP();
5104ece92f85SJason Jin M.x86.R_IP = (u16) (*destreg);
5105ece92f85SJason Jin break;
5106ece92f85SJason Jin case 5: /* jmp far ptr ... */
51078c6ec412SSimon Glass ERR_PRINTF("OPERATION UNDEFINED 0XFF\n");
5108ece92f85SJason Jin TRACE_AND_STEP();
5109ece92f85SJason Jin HALT_SYS();
5110ece92f85SJason Jin break;
5111ece92f85SJason Jin case 6:
5112ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5113ece92f85SJason Jin u32 *destreg;
5114ece92f85SJason Jin
5115ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
5116ece92f85SJason Jin DECODE_PRINTF("\n");
5117ece92f85SJason Jin TRACE_AND_STEP();
5118ece92f85SJason Jin push_long(*destreg);
5119ece92f85SJason Jin } else {
5120ece92f85SJason Jin u16 *destreg;
5121ece92f85SJason Jin
5122ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
5123ece92f85SJason Jin DECODE_PRINTF("\n");
5124ece92f85SJason Jin TRACE_AND_STEP();
5125ece92f85SJason Jin push_word(*destreg);
5126ece92f85SJason Jin }
5127ece92f85SJason Jin break;
5128ece92f85SJason Jin }
5129ece92f85SJason Jin }
5130ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
5131ece92f85SJason Jin END_OF_INSTR();
5132ece92f85SJason Jin }
5133ece92f85SJason Jin
5134ece92f85SJason Jin /***************************************************************************
5135ece92f85SJason Jin * Single byte operation code table:
5136ece92f85SJason Jin **************************************************************************/
5137285870f7SEd Swarthout void (*x86emu_optab[256])(u8) =
5138ece92f85SJason Jin {
5139ece92f85SJason Jin /* 0x00 */ x86emuOp_genop_byte_RM_R,
5140ece92f85SJason Jin /* 0x01 */ x86emuOp_genop_word_RM_R,
5141ece92f85SJason Jin /* 0x02 */ x86emuOp_genop_byte_R_RM,
5142ece92f85SJason Jin /* 0x03 */ x86emuOp_genop_word_R_RM,
5143ece92f85SJason Jin /* 0x04 */ x86emuOp_genop_byte_AL_IMM,
5144ece92f85SJason Jin /* 0x05 */ x86emuOp_genop_word_AX_IMM,
5145ece92f85SJason Jin /* 0x06 */ x86emuOp_push_ES,
5146ece92f85SJason Jin /* 0x07 */ x86emuOp_pop_ES,
5147ece92f85SJason Jin
5148ece92f85SJason Jin /* 0x08 */ x86emuOp_genop_byte_RM_R,
5149ece92f85SJason Jin /* 0x09 */ x86emuOp_genop_word_RM_R,
5150ece92f85SJason Jin /* 0x0a */ x86emuOp_genop_byte_R_RM,
5151ece92f85SJason Jin /* 0x0b */ x86emuOp_genop_word_R_RM,
5152ece92f85SJason Jin /* 0x0c */ x86emuOp_genop_byte_AL_IMM,
5153ece92f85SJason Jin /* 0x0d */ x86emuOp_genop_word_AX_IMM,
5154ece92f85SJason Jin /* 0x0e */ x86emuOp_push_CS,
5155ece92f85SJason Jin /* 0x0f */ x86emuOp_two_byte,
5156ece92f85SJason Jin
5157ece92f85SJason Jin /* 0x10 */ x86emuOp_genop_byte_RM_R,
5158ece92f85SJason Jin /* 0x11 */ x86emuOp_genop_word_RM_R,
5159ece92f85SJason Jin /* 0x12 */ x86emuOp_genop_byte_R_RM,
5160ece92f85SJason Jin /* 0x13 */ x86emuOp_genop_word_R_RM,
5161ece92f85SJason Jin /* 0x14 */ x86emuOp_genop_byte_AL_IMM,
5162ece92f85SJason Jin /* 0x15 */ x86emuOp_genop_word_AX_IMM,
5163ece92f85SJason Jin /* 0x16 */ x86emuOp_push_SS,
5164ece92f85SJason Jin /* 0x17 */ x86emuOp_pop_SS,
5165ece92f85SJason Jin
5166ece92f85SJason Jin /* 0x18 */ x86emuOp_genop_byte_RM_R,
5167ece92f85SJason Jin /* 0x19 */ x86emuOp_genop_word_RM_R,
5168ece92f85SJason Jin /* 0x1a */ x86emuOp_genop_byte_R_RM,
5169ece92f85SJason Jin /* 0x1b */ x86emuOp_genop_word_R_RM,
5170ece92f85SJason Jin /* 0x1c */ x86emuOp_genop_byte_AL_IMM,
5171ece92f85SJason Jin /* 0x1d */ x86emuOp_genop_word_AX_IMM,
5172ece92f85SJason Jin /* 0x1e */ x86emuOp_push_DS,
5173ece92f85SJason Jin /* 0x1f */ x86emuOp_pop_DS,
5174ece92f85SJason Jin
5175ece92f85SJason Jin /* 0x20 */ x86emuOp_genop_byte_RM_R,
5176ece92f85SJason Jin /* 0x21 */ x86emuOp_genop_word_RM_R,
5177ece92f85SJason Jin /* 0x22 */ x86emuOp_genop_byte_R_RM,
5178ece92f85SJason Jin /* 0x23 */ x86emuOp_genop_word_R_RM,
5179ece92f85SJason Jin /* 0x24 */ x86emuOp_genop_byte_AL_IMM,
5180ece92f85SJason Jin /* 0x25 */ x86emuOp_genop_word_AX_IMM,
5181ece92f85SJason Jin /* 0x26 */ x86emuOp_segovr_ES,
5182ece92f85SJason Jin /* 0x27 */ x86emuOp_daa,
5183ece92f85SJason Jin
5184ece92f85SJason Jin /* 0x28 */ x86emuOp_genop_byte_RM_R,
5185ece92f85SJason Jin /* 0x29 */ x86emuOp_genop_word_RM_R,
5186ece92f85SJason Jin /* 0x2a */ x86emuOp_genop_byte_R_RM,
5187ece92f85SJason Jin /* 0x2b */ x86emuOp_genop_word_R_RM,
5188ece92f85SJason Jin /* 0x2c */ x86emuOp_genop_byte_AL_IMM,
5189ece92f85SJason Jin /* 0x2d */ x86emuOp_genop_word_AX_IMM,
5190ece92f85SJason Jin /* 0x2e */ x86emuOp_segovr_CS,
5191ece92f85SJason Jin /* 0x2f */ x86emuOp_das,
5192ece92f85SJason Jin
5193ece92f85SJason Jin /* 0x30 */ x86emuOp_genop_byte_RM_R,
5194ece92f85SJason Jin /* 0x31 */ x86emuOp_genop_word_RM_R,
5195ece92f85SJason Jin /* 0x32 */ x86emuOp_genop_byte_R_RM,
5196ece92f85SJason Jin /* 0x33 */ x86emuOp_genop_word_R_RM,
5197ece92f85SJason Jin /* 0x34 */ x86emuOp_genop_byte_AL_IMM,
5198ece92f85SJason Jin /* 0x35 */ x86emuOp_genop_word_AX_IMM,
5199ece92f85SJason Jin /* 0x36 */ x86emuOp_segovr_SS,
5200ece92f85SJason Jin /* 0x37 */ x86emuOp_aaa,
5201ece92f85SJason Jin
5202ece92f85SJason Jin /* 0x38 */ x86emuOp_genop_byte_RM_R,
5203ece92f85SJason Jin /* 0x39 */ x86emuOp_genop_word_RM_R,
5204ece92f85SJason Jin /* 0x3a */ x86emuOp_genop_byte_R_RM,
5205ece92f85SJason Jin /* 0x3b */ x86emuOp_genop_word_R_RM,
5206ece92f85SJason Jin /* 0x3c */ x86emuOp_genop_byte_AL_IMM,
5207ece92f85SJason Jin /* 0x3d */ x86emuOp_genop_word_AX_IMM,
5208ece92f85SJason Jin /* 0x3e */ x86emuOp_segovr_DS,
5209ece92f85SJason Jin /* 0x3f */ x86emuOp_aas,
5210ece92f85SJason Jin
5211ece92f85SJason Jin /* 0x40 */ x86emuOp_inc_register,
5212ece92f85SJason Jin /* 0x41 */ x86emuOp_inc_register,
5213ece92f85SJason Jin /* 0x42 */ x86emuOp_inc_register,
5214ece92f85SJason Jin /* 0x43 */ x86emuOp_inc_register,
5215ece92f85SJason Jin /* 0x44 */ x86emuOp_inc_register,
5216ece92f85SJason Jin /* 0x45 */ x86emuOp_inc_register,
5217ece92f85SJason Jin /* 0x46 */ x86emuOp_inc_register,
5218ece92f85SJason Jin /* 0x47 */ x86emuOp_inc_register,
5219ece92f85SJason Jin
5220ece92f85SJason Jin /* 0x48 */ x86emuOp_dec_register,
5221ece92f85SJason Jin /* 0x49 */ x86emuOp_dec_register,
5222ece92f85SJason Jin /* 0x4a */ x86emuOp_dec_register,
5223ece92f85SJason Jin /* 0x4b */ x86emuOp_dec_register,
5224ece92f85SJason Jin /* 0x4c */ x86emuOp_dec_register,
5225ece92f85SJason Jin /* 0x4d */ x86emuOp_dec_register,
5226ece92f85SJason Jin /* 0x4e */ x86emuOp_dec_register,
5227ece92f85SJason Jin /* 0x4f */ x86emuOp_dec_register,
5228ece92f85SJason Jin
5229ece92f85SJason Jin /* 0x50 */ x86emuOp_push_register,
5230ece92f85SJason Jin /* 0x51 */ x86emuOp_push_register,
5231ece92f85SJason Jin /* 0x52 */ x86emuOp_push_register,
5232ece92f85SJason Jin /* 0x53 */ x86emuOp_push_register,
5233ece92f85SJason Jin /* 0x54 */ x86emuOp_push_register,
5234ece92f85SJason Jin /* 0x55 */ x86emuOp_push_register,
5235ece92f85SJason Jin /* 0x56 */ x86emuOp_push_register,
5236ece92f85SJason Jin /* 0x57 */ x86emuOp_push_register,
5237ece92f85SJason Jin
5238ece92f85SJason Jin /* 0x58 */ x86emuOp_pop_register,
5239ece92f85SJason Jin /* 0x59 */ x86emuOp_pop_register,
5240ece92f85SJason Jin /* 0x5a */ x86emuOp_pop_register,
5241ece92f85SJason Jin /* 0x5b */ x86emuOp_pop_register,
5242ece92f85SJason Jin /* 0x5c */ x86emuOp_pop_register,
5243ece92f85SJason Jin /* 0x5d */ x86emuOp_pop_register,
5244ece92f85SJason Jin /* 0x5e */ x86emuOp_pop_register,
5245ece92f85SJason Jin /* 0x5f */ x86emuOp_pop_register,
5246ece92f85SJason Jin
5247ece92f85SJason Jin /* 0x60 */ x86emuOp_push_all,
5248ece92f85SJason Jin /* 0x61 */ x86emuOp_pop_all,
5249ece92f85SJason Jin /* 0x62 */ x86emuOp_illegal_op, /* bound */
5250ece92f85SJason Jin /* 0x63 */ x86emuOp_illegal_op, /* arpl */
5251ece92f85SJason Jin /* 0x64 */ x86emuOp_segovr_FS,
5252ece92f85SJason Jin /* 0x65 */ x86emuOp_segovr_GS,
5253ece92f85SJason Jin /* 0x66 */ x86emuOp_prefix_data,
5254ece92f85SJason Jin /* 0x67 */ x86emuOp_prefix_addr,
5255ece92f85SJason Jin
5256ece92f85SJason Jin /* 0x68 */ x86emuOp_push_word_IMM,
5257ece92f85SJason Jin /* 0x69 */ x86emuOp_imul_word_IMM,
5258ece92f85SJason Jin /* 0x6a */ x86emuOp_push_byte_IMM,
5259ece92f85SJason Jin /* 0x6b */ x86emuOp_imul_byte_IMM,
5260ece92f85SJason Jin /* 0x6c */ x86emuOp_ins_byte,
5261ece92f85SJason Jin /* 0x6d */ x86emuOp_ins_word,
5262ece92f85SJason Jin /* 0x6e */ x86emuOp_outs_byte,
5263ece92f85SJason Jin /* 0x6f */ x86emuOp_outs_word,
5264ece92f85SJason Jin
5265ece92f85SJason Jin /* 0x70 */ x86emuOp_jump_near_cond,
5266ece92f85SJason Jin /* 0x71 */ x86emuOp_jump_near_cond,
5267ece92f85SJason Jin /* 0x72 */ x86emuOp_jump_near_cond,
5268ece92f85SJason Jin /* 0x73 */ x86emuOp_jump_near_cond,
5269ece92f85SJason Jin /* 0x74 */ x86emuOp_jump_near_cond,
5270ece92f85SJason Jin /* 0x75 */ x86emuOp_jump_near_cond,
5271ece92f85SJason Jin /* 0x76 */ x86emuOp_jump_near_cond,
5272ece92f85SJason Jin /* 0x77 */ x86emuOp_jump_near_cond,
5273ece92f85SJason Jin
5274ece92f85SJason Jin /* 0x78 */ x86emuOp_jump_near_cond,
5275ece92f85SJason Jin /* 0x79 */ x86emuOp_jump_near_cond,
5276ece92f85SJason Jin /* 0x7a */ x86emuOp_jump_near_cond,
5277ece92f85SJason Jin /* 0x7b */ x86emuOp_jump_near_cond,
5278ece92f85SJason Jin /* 0x7c */ x86emuOp_jump_near_cond,
5279ece92f85SJason Jin /* 0x7d */ x86emuOp_jump_near_cond,
5280ece92f85SJason Jin /* 0x7e */ x86emuOp_jump_near_cond,
5281ece92f85SJason Jin /* 0x7f */ x86emuOp_jump_near_cond,
5282ece92f85SJason Jin
5283ece92f85SJason Jin /* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
5284ece92f85SJason Jin /* 0x81 */ x86emuOp_opc81_word_RM_IMM,
5285ece92f85SJason Jin /* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
5286ece92f85SJason Jin /* 0x83 */ x86emuOp_opc83_word_RM_IMM,
5287ece92f85SJason Jin /* 0x84 */ x86emuOp_test_byte_RM_R,
5288ece92f85SJason Jin /* 0x85 */ x86emuOp_test_word_RM_R,
5289ece92f85SJason Jin /* 0x86 */ x86emuOp_xchg_byte_RM_R,
5290ece92f85SJason Jin /* 0x87 */ x86emuOp_xchg_word_RM_R,
5291ece92f85SJason Jin
5292ece92f85SJason Jin /* 0x88 */ x86emuOp_mov_byte_RM_R,
5293ece92f85SJason Jin /* 0x89 */ x86emuOp_mov_word_RM_R,
5294ece92f85SJason Jin /* 0x8a */ x86emuOp_mov_byte_R_RM,
5295ece92f85SJason Jin /* 0x8b */ x86emuOp_mov_word_R_RM,
5296ece92f85SJason Jin /* 0x8c */ x86emuOp_mov_word_RM_SR,
5297ece92f85SJason Jin /* 0x8d */ x86emuOp_lea_word_R_M,
5298ece92f85SJason Jin /* 0x8e */ x86emuOp_mov_word_SR_RM,
5299ece92f85SJason Jin /* 0x8f */ x86emuOp_pop_RM,
5300ece92f85SJason Jin
5301ece92f85SJason Jin /* 0x90 */ x86emuOp_nop,
5302ece92f85SJason Jin /* 0x91 */ x86emuOp_xchg_word_AX_register,
5303ece92f85SJason Jin /* 0x92 */ x86emuOp_xchg_word_AX_register,
5304ece92f85SJason Jin /* 0x93 */ x86emuOp_xchg_word_AX_register,
5305ece92f85SJason Jin /* 0x94 */ x86emuOp_xchg_word_AX_register,
5306ece92f85SJason Jin /* 0x95 */ x86emuOp_xchg_word_AX_register,
5307ece92f85SJason Jin /* 0x96 */ x86emuOp_xchg_word_AX_register,
5308ece92f85SJason Jin /* 0x97 */ x86emuOp_xchg_word_AX_register,
5309ece92f85SJason Jin
5310ece92f85SJason Jin /* 0x98 */ x86emuOp_cbw,
5311ece92f85SJason Jin /* 0x99 */ x86emuOp_cwd,
5312ece92f85SJason Jin /* 0x9a */ x86emuOp_call_far_IMM,
5313ece92f85SJason Jin /* 0x9b */ x86emuOp_wait,
5314ece92f85SJason Jin /* 0x9c */ x86emuOp_pushf_word,
5315ece92f85SJason Jin /* 0x9d */ x86emuOp_popf_word,
5316ece92f85SJason Jin /* 0x9e */ x86emuOp_sahf,
5317ece92f85SJason Jin /* 0x9f */ x86emuOp_lahf,
5318ece92f85SJason Jin
5319ece92f85SJason Jin /* 0xa0 */ x86emuOp_mov_AL_M_IMM,
5320ece92f85SJason Jin /* 0xa1 */ x86emuOp_mov_AX_M_IMM,
5321ece92f85SJason Jin /* 0xa2 */ x86emuOp_mov_M_AL_IMM,
5322ece92f85SJason Jin /* 0xa3 */ x86emuOp_mov_M_AX_IMM,
5323ece92f85SJason Jin /* 0xa4 */ x86emuOp_movs_byte,
5324ece92f85SJason Jin /* 0xa5 */ x86emuOp_movs_word,
5325ece92f85SJason Jin /* 0xa6 */ x86emuOp_cmps_byte,
5326ece92f85SJason Jin /* 0xa7 */ x86emuOp_cmps_word,
5327ece92f85SJason Jin /* 0xa8 */ x86emuOp_test_AL_IMM,
5328ece92f85SJason Jin /* 0xa9 */ x86emuOp_test_AX_IMM,
5329ece92f85SJason Jin /* 0xaa */ x86emuOp_stos_byte,
5330ece92f85SJason Jin /* 0xab */ x86emuOp_stos_word,
5331ece92f85SJason Jin /* 0xac */ x86emuOp_lods_byte,
5332ece92f85SJason Jin /* 0xad */ x86emuOp_lods_word,
5333ece92f85SJason Jin /* 0xac */ x86emuOp_scas_byte,
5334ece92f85SJason Jin /* 0xad */ x86emuOp_scas_word,
5335ece92f85SJason Jin
5336ece92f85SJason Jin /* 0xb0 */ x86emuOp_mov_byte_register_IMM,
5337ece92f85SJason Jin /* 0xb1 */ x86emuOp_mov_byte_register_IMM,
5338ece92f85SJason Jin /* 0xb2 */ x86emuOp_mov_byte_register_IMM,
5339ece92f85SJason Jin /* 0xb3 */ x86emuOp_mov_byte_register_IMM,
5340ece92f85SJason Jin /* 0xb4 */ x86emuOp_mov_byte_register_IMM,
5341ece92f85SJason Jin /* 0xb5 */ x86emuOp_mov_byte_register_IMM,
5342ece92f85SJason Jin /* 0xb6 */ x86emuOp_mov_byte_register_IMM,
5343ece92f85SJason Jin /* 0xb7 */ x86emuOp_mov_byte_register_IMM,
5344ece92f85SJason Jin
5345ece92f85SJason Jin /* 0xb8 */ x86emuOp_mov_word_register_IMM,
5346ece92f85SJason Jin /* 0xb9 */ x86emuOp_mov_word_register_IMM,
5347ece92f85SJason Jin /* 0xba */ x86emuOp_mov_word_register_IMM,
5348ece92f85SJason Jin /* 0xbb */ x86emuOp_mov_word_register_IMM,
5349ece92f85SJason Jin /* 0xbc */ x86emuOp_mov_word_register_IMM,
5350ece92f85SJason Jin /* 0xbd */ x86emuOp_mov_word_register_IMM,
5351ece92f85SJason Jin /* 0xbe */ x86emuOp_mov_word_register_IMM,
5352ece92f85SJason Jin /* 0xbf */ x86emuOp_mov_word_register_IMM,
5353ece92f85SJason Jin
5354ece92f85SJason Jin /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
5355ece92f85SJason Jin /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
5356ece92f85SJason Jin /* 0xc2 */ x86emuOp_ret_near_IMM,
5357ece92f85SJason Jin /* 0xc3 */ x86emuOp_ret_near,
5358ece92f85SJason Jin /* 0xc4 */ x86emuOp_les_R_IMM,
5359ece92f85SJason Jin /* 0xc5 */ x86emuOp_lds_R_IMM,
5360ece92f85SJason Jin /* 0xc6 */ x86emuOp_mov_byte_RM_IMM,
5361ece92f85SJason Jin /* 0xc7 */ x86emuOp_mov_word_RM_IMM,
5362ece92f85SJason Jin /* 0xc8 */ x86emuOp_enter,
5363ece92f85SJason Jin /* 0xc9 */ x86emuOp_leave,
5364ece92f85SJason Jin /* 0xca */ x86emuOp_ret_far_IMM,
5365ece92f85SJason Jin /* 0xcb */ x86emuOp_ret_far,
5366ece92f85SJason Jin /* 0xcc */ x86emuOp_int3,
5367ece92f85SJason Jin /* 0xcd */ x86emuOp_int_IMM,
5368ece92f85SJason Jin /* 0xce */ x86emuOp_into,
5369ece92f85SJason Jin /* 0xcf */ x86emuOp_iret,
5370ece92f85SJason Jin
5371ece92f85SJason Jin /* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
5372ece92f85SJason Jin /* 0xd1 */ x86emuOp_opcD1_word_RM_1,
5373ece92f85SJason Jin /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
5374ece92f85SJason Jin /* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
5375ece92f85SJason Jin /* 0xd4 */ x86emuOp_aam,
5376ece92f85SJason Jin /* 0xd5 */ x86emuOp_aad,
5377ece92f85SJason Jin /* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */
5378ece92f85SJason Jin /* 0xd7 */ x86emuOp_xlat,
5379ece92f85SJason Jin /* 0xd8 */ NULL, /*x86emuOp_esc_coprocess_d8,*/
5380ece92f85SJason Jin /* 0xd9 */ NULL, /*x86emuOp_esc_coprocess_d9,*/
5381ece92f85SJason Jin /* 0xda */ NULL, /*x86emuOp_esc_coprocess_da,*/
5382ece92f85SJason Jin /* 0xdb */ NULL, /*x86emuOp_esc_coprocess_db,*/
5383ece92f85SJason Jin /* 0xdc */ NULL, /*x86emuOp_esc_coprocess_dc,*/
5384ece92f85SJason Jin /* 0xdd */ NULL, /*x86emuOp_esc_coprocess_dd,*/
5385ece92f85SJason Jin /* 0xde */ NULL, /*x86emuOp_esc_coprocess_de,*/
5386ece92f85SJason Jin /* 0xdf */ NULL, /*x86emuOp_esc_coprocess_df,*/
5387ece92f85SJason Jin
5388ece92f85SJason Jin /* 0xe0 */ x86emuOp_loopne,
5389ece92f85SJason Jin /* 0xe1 */ x86emuOp_loope,
5390ece92f85SJason Jin /* 0xe2 */ x86emuOp_loop,
5391ece92f85SJason Jin /* 0xe3 */ x86emuOp_jcxz,
5392ece92f85SJason Jin /* 0xe4 */ x86emuOp_in_byte_AL_IMM,
5393ece92f85SJason Jin /* 0xe5 */ x86emuOp_in_word_AX_IMM,
5394ece92f85SJason Jin /* 0xe6 */ x86emuOp_out_byte_IMM_AL,
5395ece92f85SJason Jin /* 0xe7 */ x86emuOp_out_word_IMM_AX,
5396ece92f85SJason Jin
5397ece92f85SJason Jin /* 0xe8 */ x86emuOp_call_near_IMM,
5398ece92f85SJason Jin /* 0xe9 */ x86emuOp_jump_near_IMM,
5399ece92f85SJason Jin /* 0xea */ x86emuOp_jump_far_IMM,
5400ece92f85SJason Jin /* 0xeb */ x86emuOp_jump_byte_IMM,
5401ece92f85SJason Jin /* 0xec */ x86emuOp_in_byte_AL_DX,
5402ece92f85SJason Jin /* 0xed */ x86emuOp_in_word_AX_DX,
5403ece92f85SJason Jin /* 0xee */ x86emuOp_out_byte_DX_AL,
5404ece92f85SJason Jin /* 0xef */ x86emuOp_out_word_DX_AX,
5405ece92f85SJason Jin
5406ece92f85SJason Jin /* 0xf0 */ x86emuOp_lock,
5407ece92f85SJason Jin /* 0xf1 */ x86emuOp_illegal_op,
5408ece92f85SJason Jin /* 0xf2 */ x86emuOp_repne,
5409ece92f85SJason Jin /* 0xf3 */ x86emuOp_repe,
5410ece92f85SJason Jin /* 0xf4 */ x86emuOp_halt,
5411ece92f85SJason Jin /* 0xf5 */ x86emuOp_cmc,
5412ece92f85SJason Jin /* 0xf6 */ x86emuOp_opcF6_byte_RM,
5413ece92f85SJason Jin /* 0xf7 */ x86emuOp_opcF7_word_RM,
5414ece92f85SJason Jin
5415ece92f85SJason Jin /* 0xf8 */ x86emuOp_clc,
5416ece92f85SJason Jin /* 0xf9 */ x86emuOp_stc,
5417ece92f85SJason Jin /* 0xfa */ x86emuOp_cli,
5418ece92f85SJason Jin /* 0xfb */ x86emuOp_sti,
5419ece92f85SJason Jin /* 0xfc */ x86emuOp_cld,
5420ece92f85SJason Jin /* 0xfd */ x86emuOp_std,
5421ece92f85SJason Jin /* 0xfe */ x86emuOp_opcFE_byte_RM,
5422ece92f85SJason Jin /* 0xff */ x86emuOp_opcFF_word_RM,
5423ece92f85SJason Jin };
5424