1ece92f85SJason Jin /****************************************************************************
2ece92f85SJason Jin *
3ece92f85SJason Jin * Realmode X86 Emulator Library
4ece92f85SJason Jin *
54c2e3da8SKumar Gala * Copyright (C) 2007 Freescale Semiconductor, Inc.
6ece92f85SJason Jin * Jason Jin <Jason.jin@freescale.com>
7ece92f85SJason Jin *
8ece92f85SJason Jin * Copyright (C) 1991-2004 SciTech Software, Inc.
9ece92f85SJason Jin * Copyright (C) David Mosberger-Tang
10ece92f85SJason Jin * Copyright (C) 1999 Egbert Eich
11ece92f85SJason Jin *
12ece92f85SJason Jin * ========================================================================
13ece92f85SJason Jin *
14ece92f85SJason Jin * Permission to use, copy, modify, distribute, and sell this software and
15ece92f85SJason Jin * its documentation for any purpose is hereby granted without fee,
16ece92f85SJason Jin * provided that the above copyright notice appear in all copies and that
17ece92f85SJason Jin * both that copyright notice and this permission notice appear in
18ece92f85SJason Jin * supporting documentation, and that the name of the authors not be used
19ece92f85SJason Jin * in advertising or publicity pertaining to distribution of the software
20ece92f85SJason Jin * without specific, written prior permission. The authors makes no
21ece92f85SJason Jin * representations about the suitability of this software for any purpose.
22ece92f85SJason Jin * It is provided "as is" without express or implied warranty.
23ece92f85SJason Jin *
24ece92f85SJason Jin * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
25ece92f85SJason Jin * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
26ece92f85SJason Jin * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
27ece92f85SJason Jin * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
28ece92f85SJason Jin * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
29ece92f85SJason Jin * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
30ece92f85SJason Jin * PERFORMANCE OF THIS SOFTWARE.
31ece92f85SJason Jin *
32ece92f85SJason Jin * ========================================================================
33ece92f85SJason Jin *
34ece92f85SJason Jin * Language: ANSI C
35ece92f85SJason Jin * Environment: Any
36ece92f85SJason Jin * Developer: Kendall Bennett
37ece92f85SJason Jin *
38ece92f85SJason Jin * Description: This file includes subroutines to implement the decoding
39ece92f85SJason Jin * and emulation of all the x86 extended two-byte processor
40ece92f85SJason Jin * instructions.
41ece92f85SJason Jin *
42ece92f85SJason Jin ****************************************************************************/
43ece92f85SJason Jin
4478cff50eSMichal Simek #include <common.h>
45d90a5b1eSKumar Gala #include <linux/compiler.h>
465b4de930SMichal Simek #include "x86emu/x86emui.h"
475b4de930SMichal Simek
48ece92f85SJason Jin /*----------------------------- Implementation ----------------------------*/
49ece92f85SJason Jin
50ece92f85SJason Jin /****************************************************************************
51ece92f85SJason Jin PARAMETERS:
52ece92f85SJason Jin op1 - Instruction op code
53ece92f85SJason Jin
54ece92f85SJason Jin REMARKS:
55ece92f85SJason Jin Handles illegal opcodes.
56ece92f85SJason Jin ****************************************************************************/
x86emuOp2_illegal_op(u8 op2)57ece92f85SJason Jin void x86emuOp2_illegal_op(
58ece92f85SJason Jin u8 op2)
59ece92f85SJason Jin {
60ece92f85SJason Jin START_OF_INSTR();
61*8c6ec412SSimon Glass ERR_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
62ece92f85SJason Jin TRACE_REGS();
63ece92f85SJason Jin printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
64ece92f85SJason Jin M.x86.R_CS, M.x86.R_IP-2,op2);
65ece92f85SJason Jin HALT_SYS();
66ece92f85SJason Jin END_OF_INSTR();
67ece92f85SJason Jin }
68ece92f85SJason Jin
69ece92f85SJason Jin #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
70ece92f85SJason Jin
71ece92f85SJason Jin /****************************************************************************
72ece92f85SJason Jin REMARKS:
73ece92f85SJason Jin Handles opcode 0x0f,0x80-0x8F
74ece92f85SJason Jin ****************************************************************************/
x86emu_check_jump_condition(u8 op)75ece92f85SJason Jin int x86emu_check_jump_condition(u8 op)
76ece92f85SJason Jin {
77ece92f85SJason Jin switch (op) {
78ece92f85SJason Jin case 0x0:
79ece92f85SJason Jin DECODE_PRINTF("JO\t");
80ece92f85SJason Jin return ACCESS_FLAG(F_OF);
81ece92f85SJason Jin case 0x1:
82ece92f85SJason Jin DECODE_PRINTF("JNO\t");
83ece92f85SJason Jin return !ACCESS_FLAG(F_OF);
84ece92f85SJason Jin break;
85ece92f85SJason Jin case 0x2:
86ece92f85SJason Jin DECODE_PRINTF("JB\t");
87ece92f85SJason Jin return ACCESS_FLAG(F_CF);
88ece92f85SJason Jin break;
89ece92f85SJason Jin case 0x3:
90ece92f85SJason Jin DECODE_PRINTF("JNB\t");
91ece92f85SJason Jin return !ACCESS_FLAG(F_CF);
92ece92f85SJason Jin break;
93ece92f85SJason Jin case 0x4:
94ece92f85SJason Jin DECODE_PRINTF("JZ\t");
95ece92f85SJason Jin return ACCESS_FLAG(F_ZF);
96ece92f85SJason Jin break;
97ece92f85SJason Jin case 0x5:
98ece92f85SJason Jin DECODE_PRINTF("JNZ\t");
99ece92f85SJason Jin return !ACCESS_FLAG(F_ZF);
100ece92f85SJason Jin break;
101ece92f85SJason Jin case 0x6:
102ece92f85SJason Jin DECODE_PRINTF("JBE\t");
103ece92f85SJason Jin return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
104ece92f85SJason Jin break;
105ece92f85SJason Jin case 0x7:
106ece92f85SJason Jin DECODE_PRINTF("JNBE\t");
107ece92f85SJason Jin return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
108ece92f85SJason Jin break;
109ece92f85SJason Jin case 0x8:
110ece92f85SJason Jin DECODE_PRINTF("JS\t");
111ece92f85SJason Jin return ACCESS_FLAG(F_SF);
112ece92f85SJason Jin break;
113ece92f85SJason Jin case 0x9:
114ece92f85SJason Jin DECODE_PRINTF("JNS\t");
115ece92f85SJason Jin return !ACCESS_FLAG(F_SF);
116ece92f85SJason Jin break;
117ece92f85SJason Jin case 0xa:
118ece92f85SJason Jin DECODE_PRINTF("JP\t");
119ece92f85SJason Jin return ACCESS_FLAG(F_PF);
120ece92f85SJason Jin break;
121ece92f85SJason Jin case 0xb:
122ece92f85SJason Jin DECODE_PRINTF("JNP\t");
123ece92f85SJason Jin return !ACCESS_FLAG(F_PF);
124ece92f85SJason Jin break;
125ece92f85SJason Jin case 0xc:
126ece92f85SJason Jin DECODE_PRINTF("JL\t");
127ece92f85SJason Jin return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
128ece92f85SJason Jin break;
129ece92f85SJason Jin case 0xd:
130ece92f85SJason Jin DECODE_PRINTF("JNL\t");
131ece92f85SJason Jin return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
132ece92f85SJason Jin break;
133ece92f85SJason Jin case 0xe:
134ece92f85SJason Jin DECODE_PRINTF("JLE\t");
135ece92f85SJason Jin return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
136ece92f85SJason Jin ACCESS_FLAG(F_ZF));
137ece92f85SJason Jin break;
138ece92f85SJason Jin default:
139ece92f85SJason Jin DECODE_PRINTF("JNLE\t");
140ece92f85SJason Jin return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
141ece92f85SJason Jin ACCESS_FLAG(F_ZF));
142ece92f85SJason Jin }
143ece92f85SJason Jin }
144ece92f85SJason Jin
x86emuOp2_long_jump(u8 op2)145ece92f85SJason Jin void x86emuOp2_long_jump(u8 op2)
146ece92f85SJason Jin {
147ece92f85SJason Jin s32 target;
148ece92f85SJason Jin int cond;
149ece92f85SJason Jin
150ece92f85SJason Jin /* conditional jump to word offset. */
151ece92f85SJason Jin START_OF_INSTR();
152ece92f85SJason Jin cond = x86emu_check_jump_condition(op2 & 0xF);
153ece92f85SJason Jin target = (s16) fetch_word_imm();
154ece92f85SJason Jin target += (s16) M.x86.R_IP;
155ece92f85SJason Jin DECODE_PRINTF2("%04x\n", target);
156ece92f85SJason Jin TRACE_AND_STEP();
157ece92f85SJason Jin if (cond)
158ece92f85SJason Jin M.x86.R_IP = (u16)target;
159ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
160ece92f85SJason Jin END_OF_INSTR();
161ece92f85SJason Jin }
162ece92f85SJason Jin
163ece92f85SJason Jin /****************************************************************************
164ece92f85SJason Jin REMARKS:
165ece92f85SJason Jin Handles opcode 0x0f,0x90-0x9F
166ece92f85SJason Jin ****************************************************************************/
x86emuOp2_set_byte(u8 op2)167ece92f85SJason Jin void x86emuOp2_set_byte(u8 op2)
168ece92f85SJason Jin {
169ece92f85SJason Jin int mod, rl, rh;
170ece92f85SJason Jin uint destoffset;
171ece92f85SJason Jin u8 *destreg;
172d90a5b1eSKumar Gala __maybe_unused char *name = 0;
173ece92f85SJason Jin int cond = 0;
174ece92f85SJason Jin
175ece92f85SJason Jin START_OF_INSTR();
176ece92f85SJason Jin switch (op2) {
177ece92f85SJason Jin case 0x90:
178ece92f85SJason Jin name = "SETO\t";
179ece92f85SJason Jin cond = ACCESS_FLAG(F_OF);
180ece92f85SJason Jin break;
181ece92f85SJason Jin case 0x91:
182ece92f85SJason Jin name = "SETNO\t";
183ece92f85SJason Jin cond = !ACCESS_FLAG(F_OF);
184ece92f85SJason Jin break;
185ece92f85SJason Jin case 0x92:
186ece92f85SJason Jin name = "SETB\t";
187ece92f85SJason Jin cond = ACCESS_FLAG(F_CF);
188ece92f85SJason Jin break;
189ece92f85SJason Jin case 0x93:
190ece92f85SJason Jin name = "SETNB\t";
191ece92f85SJason Jin cond = !ACCESS_FLAG(F_CF);
192ece92f85SJason Jin break;
193ece92f85SJason Jin case 0x94:
194ece92f85SJason Jin name = "SETZ\t";
195ece92f85SJason Jin cond = ACCESS_FLAG(F_ZF);
196ece92f85SJason Jin break;
197ece92f85SJason Jin case 0x95:
198ece92f85SJason Jin name = "SETNZ\t";
199ece92f85SJason Jin cond = !ACCESS_FLAG(F_ZF);
200ece92f85SJason Jin break;
201ece92f85SJason Jin case 0x96:
202ece92f85SJason Jin name = "SETBE\t";
203ece92f85SJason Jin cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
204ece92f85SJason Jin break;
205ece92f85SJason Jin case 0x97:
206ece92f85SJason Jin name = "SETNBE\t";
207ece92f85SJason Jin cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
208ece92f85SJason Jin break;
209ece92f85SJason Jin case 0x98:
210ece92f85SJason Jin name = "SETS\t";
211ece92f85SJason Jin cond = ACCESS_FLAG(F_SF);
212ece92f85SJason Jin break;
213ece92f85SJason Jin case 0x99:
214ece92f85SJason Jin name = "SETNS\t";
215ece92f85SJason Jin cond = !ACCESS_FLAG(F_SF);
216ece92f85SJason Jin break;
217ece92f85SJason Jin case 0x9a:
218ece92f85SJason Jin name = "SETP\t";
219ece92f85SJason Jin cond = ACCESS_FLAG(F_PF);
220ece92f85SJason Jin break;
221ece92f85SJason Jin case 0x9b:
222ece92f85SJason Jin name = "SETNP\t";
223ece92f85SJason Jin cond = !ACCESS_FLAG(F_PF);
224ece92f85SJason Jin break;
225ece92f85SJason Jin case 0x9c:
226ece92f85SJason Jin name = "SETL\t";
227ece92f85SJason Jin cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
228ece92f85SJason Jin break;
229ece92f85SJason Jin case 0x9d:
230ece92f85SJason Jin name = "SETNL\t";
231ece92f85SJason Jin cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
232ece92f85SJason Jin break;
233ece92f85SJason Jin case 0x9e:
234ece92f85SJason Jin name = "SETLE\t";
235ece92f85SJason Jin cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
236ece92f85SJason Jin ACCESS_FLAG(F_ZF));
237ece92f85SJason Jin break;
238ece92f85SJason Jin case 0x9f:
239ece92f85SJason Jin name = "SETNLE\t";
240ece92f85SJason Jin cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
241ece92f85SJason Jin ACCESS_FLAG(F_ZF));
242ece92f85SJason Jin break;
243ece92f85SJason Jin }
244ece92f85SJason Jin DECODE_PRINTF(name);
245ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
246ece92f85SJason Jin if (mod < 3) {
247ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
248ece92f85SJason Jin TRACE_AND_STEP();
249ece92f85SJason Jin store_data_byte(destoffset, cond ? 0x01 : 0x00);
250ece92f85SJason Jin } else { /* register to register */
251ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl);
252ece92f85SJason Jin TRACE_AND_STEP();
253ece92f85SJason Jin *destreg = cond ? 0x01 : 0x00;
254ece92f85SJason Jin }
255ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
256ece92f85SJason Jin END_OF_INSTR();
257ece92f85SJason Jin }
258ece92f85SJason Jin
259ece92f85SJason Jin /****************************************************************************
260ece92f85SJason Jin REMARKS:
261ece92f85SJason Jin Handles opcode 0x0f,0xa0
262ece92f85SJason Jin ****************************************************************************/
x86emuOp2_push_FS(u8 X86EMU_UNUSED (op2))263ece92f85SJason Jin void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
264ece92f85SJason Jin {
265ece92f85SJason Jin START_OF_INSTR();
266ece92f85SJason Jin DECODE_PRINTF("PUSH\tFS\n");
267ece92f85SJason Jin TRACE_AND_STEP();
268ece92f85SJason Jin push_word(M.x86.R_FS);
269ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
270ece92f85SJason Jin END_OF_INSTR();
271ece92f85SJason Jin }
272ece92f85SJason Jin
273ece92f85SJason Jin /****************************************************************************
274ece92f85SJason Jin REMARKS:
275ece92f85SJason Jin Handles opcode 0x0f,0xa1
276ece92f85SJason Jin ****************************************************************************/
x86emuOp2_pop_FS(u8 X86EMU_UNUSED (op2))277ece92f85SJason Jin void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
278ece92f85SJason Jin {
279ece92f85SJason Jin START_OF_INSTR();
280ece92f85SJason Jin DECODE_PRINTF("POP\tFS\n");
281ece92f85SJason Jin TRACE_AND_STEP();
282ece92f85SJason Jin M.x86.R_FS = pop_word();
283ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
284ece92f85SJason Jin END_OF_INSTR();
285ece92f85SJason Jin }
286ece92f85SJason Jin
287ece92f85SJason Jin /****************************************************************************
288ece92f85SJason Jin REMARKS:
289ece92f85SJason Jin Handles opcode 0x0f,0xa3
290ece92f85SJason Jin ****************************************************************************/
x86emuOp2_bt_R(u8 X86EMU_UNUSED (op2))291ece92f85SJason Jin void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
292ece92f85SJason Jin {
293ece92f85SJason Jin int mod, rl, rh;
294ece92f85SJason Jin uint srcoffset;
295ece92f85SJason Jin int bit,disp;
296ece92f85SJason Jin
297ece92f85SJason Jin START_OF_INSTR();
298ece92f85SJason Jin DECODE_PRINTF("BT\t");
299ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
300ece92f85SJason Jin if (mod < 3) {
301ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
302ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
303ece92f85SJason Jin u32 srcval;
304ece92f85SJason Jin u32 *shiftreg;
305ece92f85SJason Jin
306ece92f85SJason Jin DECODE_PRINTF(",");
307ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
308ece92f85SJason Jin TRACE_AND_STEP();
309ece92f85SJason Jin bit = *shiftreg & 0x1F;
310ece92f85SJason Jin disp = (s16)*shiftreg >> 5;
311ece92f85SJason Jin srcval = fetch_data_long(srcoffset+disp);
312ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
313ece92f85SJason Jin } else {
314ece92f85SJason Jin u16 srcval;
315ece92f85SJason Jin u16 *shiftreg;
316ece92f85SJason Jin
317ece92f85SJason Jin DECODE_PRINTF(",");
318ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
319ece92f85SJason Jin TRACE_AND_STEP();
320ece92f85SJason Jin bit = *shiftreg & 0xF;
321ece92f85SJason Jin disp = (s16)*shiftreg >> 4;
322ece92f85SJason Jin srcval = fetch_data_word(srcoffset+disp);
323ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
324ece92f85SJason Jin }
325ece92f85SJason Jin } else { /* register to register */
326ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
327ece92f85SJason Jin u32 *srcreg,*shiftreg;
328ece92f85SJason Jin
329ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
330ece92f85SJason Jin DECODE_PRINTF(",");
331ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
332ece92f85SJason Jin TRACE_AND_STEP();
333ece92f85SJason Jin bit = *shiftreg & 0x1F;
334ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
335ece92f85SJason Jin } else {
336ece92f85SJason Jin u16 *srcreg,*shiftreg;
337ece92f85SJason Jin
338ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
339ece92f85SJason Jin DECODE_PRINTF(",");
340ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
341ece92f85SJason Jin TRACE_AND_STEP();
342ece92f85SJason Jin bit = *shiftreg & 0xF;
343ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
344ece92f85SJason Jin }
345ece92f85SJason Jin }
346ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
347ece92f85SJason Jin END_OF_INSTR();
348ece92f85SJason Jin }
349ece92f85SJason Jin
350ece92f85SJason Jin /****************************************************************************
351ece92f85SJason Jin REMARKS:
352ece92f85SJason Jin Handles opcode 0x0f,0xa4
353ece92f85SJason Jin ****************************************************************************/
x86emuOp2_shld_IMM(u8 X86EMU_UNUSED (op2))354ece92f85SJason Jin void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
355ece92f85SJason Jin {
356ece92f85SJason Jin int mod, rl, rh;
357ece92f85SJason Jin uint destoffset;
358ece92f85SJason Jin u8 shift;
359ece92f85SJason Jin
360ece92f85SJason Jin START_OF_INSTR();
361ece92f85SJason Jin DECODE_PRINTF("SHLD\t");
362ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
363ece92f85SJason Jin if (mod < 3) {
364ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
365ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
366ece92f85SJason Jin u32 destval;
367ece92f85SJason Jin u32 *shiftreg;
368ece92f85SJason Jin
369ece92f85SJason Jin DECODE_PRINTF(",");
370ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
371ece92f85SJason Jin DECODE_PRINTF(",");
372ece92f85SJason Jin shift = fetch_byte_imm();
373ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift);
374ece92f85SJason Jin TRACE_AND_STEP();
375ece92f85SJason Jin destval = fetch_data_long(destoffset);
376ece92f85SJason Jin destval = shld_long(destval,*shiftreg,shift);
377ece92f85SJason Jin store_data_long(destoffset, destval);
378ece92f85SJason Jin } else {
379ece92f85SJason Jin u16 destval;
380ece92f85SJason Jin u16 *shiftreg;
381ece92f85SJason Jin
382ece92f85SJason Jin DECODE_PRINTF(",");
383ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
384ece92f85SJason Jin DECODE_PRINTF(",");
385ece92f85SJason Jin shift = fetch_byte_imm();
386ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift);
387ece92f85SJason Jin TRACE_AND_STEP();
388ece92f85SJason Jin destval = fetch_data_word(destoffset);
389ece92f85SJason Jin destval = shld_word(destval,*shiftreg,shift);
390ece92f85SJason Jin store_data_word(destoffset, destval);
391ece92f85SJason Jin }
392ece92f85SJason Jin } else { /* register to register */
393ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
394ece92f85SJason Jin u32 *destreg,*shiftreg;
395ece92f85SJason Jin
396ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
397ece92f85SJason Jin DECODE_PRINTF(",");
398ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
399ece92f85SJason Jin DECODE_PRINTF(",");
400ece92f85SJason Jin shift = fetch_byte_imm();
401ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift);
402ece92f85SJason Jin TRACE_AND_STEP();
403ece92f85SJason Jin *destreg = shld_long(*destreg,*shiftreg,shift);
404ece92f85SJason Jin } else {
405ece92f85SJason Jin u16 *destreg,*shiftreg;
406ece92f85SJason Jin
407ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
408ece92f85SJason Jin DECODE_PRINTF(",");
409ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
410ece92f85SJason Jin DECODE_PRINTF(",");
411ece92f85SJason Jin shift = fetch_byte_imm();
412ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift);
413ece92f85SJason Jin TRACE_AND_STEP();
414ece92f85SJason Jin *destreg = shld_word(*destreg,*shiftreg,shift);
415ece92f85SJason Jin }
416ece92f85SJason Jin }
417ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
418ece92f85SJason Jin END_OF_INSTR();
419ece92f85SJason Jin }
420ece92f85SJason Jin
421ece92f85SJason Jin /****************************************************************************
422ece92f85SJason Jin REMARKS:
423ece92f85SJason Jin Handles opcode 0x0f,0xa5
424ece92f85SJason Jin ****************************************************************************/
x86emuOp2_shld_CL(u8 X86EMU_UNUSED (op2))425ece92f85SJason Jin void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
426ece92f85SJason Jin {
427ece92f85SJason Jin int mod, rl, rh;
428ece92f85SJason Jin uint destoffset;
429ece92f85SJason Jin
430ece92f85SJason Jin START_OF_INSTR();
431ece92f85SJason Jin DECODE_PRINTF("SHLD\t");
432ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
433ece92f85SJason Jin if (mod < 3) {
434ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
435ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
436ece92f85SJason Jin u32 destval;
437ece92f85SJason Jin u32 *shiftreg;
438ece92f85SJason Jin
439ece92f85SJason Jin DECODE_PRINTF(",");
440ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
441ece92f85SJason Jin DECODE_PRINTF(",CL\n");
442ece92f85SJason Jin TRACE_AND_STEP();
443ece92f85SJason Jin destval = fetch_data_long(destoffset);
444ece92f85SJason Jin destval = shld_long(destval,*shiftreg,M.x86.R_CL);
445ece92f85SJason Jin store_data_long(destoffset, destval);
446ece92f85SJason Jin } else {
447ece92f85SJason Jin u16 destval;
448ece92f85SJason Jin u16 *shiftreg;
449ece92f85SJason Jin
450ece92f85SJason Jin DECODE_PRINTF(",");
451ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
452ece92f85SJason Jin DECODE_PRINTF(",CL\n");
453ece92f85SJason Jin TRACE_AND_STEP();
454ece92f85SJason Jin destval = fetch_data_word(destoffset);
455ece92f85SJason Jin destval = shld_word(destval,*shiftreg,M.x86.R_CL);
456ece92f85SJason Jin store_data_word(destoffset, destval);
457ece92f85SJason Jin }
458ece92f85SJason Jin } else { /* register to register */
459ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
460ece92f85SJason Jin u32 *destreg,*shiftreg;
461ece92f85SJason Jin
462ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
463ece92f85SJason Jin DECODE_PRINTF(",");
464ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
465ece92f85SJason Jin DECODE_PRINTF(",CL\n");
466ece92f85SJason Jin TRACE_AND_STEP();
467ece92f85SJason Jin *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
468ece92f85SJason Jin } else {
469ece92f85SJason Jin u16 *destreg,*shiftreg;
470ece92f85SJason Jin
471ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
472ece92f85SJason Jin DECODE_PRINTF(",");
473ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
474ece92f85SJason Jin DECODE_PRINTF(",CL\n");
475ece92f85SJason Jin TRACE_AND_STEP();
476ece92f85SJason Jin *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
477ece92f85SJason Jin }
478ece92f85SJason Jin }
479ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
480ece92f85SJason Jin END_OF_INSTR();
481ece92f85SJason Jin }
482ece92f85SJason Jin
483ece92f85SJason Jin /****************************************************************************
484ece92f85SJason Jin REMARKS:
485ece92f85SJason Jin Handles opcode 0x0f,0xa8
486ece92f85SJason Jin ****************************************************************************/
x86emuOp2_push_GS(u8 X86EMU_UNUSED (op2))487ece92f85SJason Jin void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
488ece92f85SJason Jin {
489ece92f85SJason Jin START_OF_INSTR();
490ece92f85SJason Jin DECODE_PRINTF("PUSH\tGS\n");
491ece92f85SJason Jin TRACE_AND_STEP();
492ece92f85SJason Jin push_word(M.x86.R_GS);
493ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
494ece92f85SJason Jin END_OF_INSTR();
495ece92f85SJason Jin }
496ece92f85SJason Jin
497ece92f85SJason Jin /****************************************************************************
498ece92f85SJason Jin REMARKS:
499ece92f85SJason Jin Handles opcode 0x0f,0xa9
500ece92f85SJason Jin ****************************************************************************/
x86emuOp2_pop_GS(u8 X86EMU_UNUSED (op2))501ece92f85SJason Jin void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
502ece92f85SJason Jin {
503ece92f85SJason Jin START_OF_INSTR();
504ece92f85SJason Jin DECODE_PRINTF("POP\tGS\n");
505ece92f85SJason Jin TRACE_AND_STEP();
506ece92f85SJason Jin M.x86.R_GS = pop_word();
507ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
508ece92f85SJason Jin END_OF_INSTR();
509ece92f85SJason Jin }
510ece92f85SJason Jin
511ece92f85SJason Jin /****************************************************************************
512ece92f85SJason Jin REMARKS:
513ece92f85SJason Jin Handles opcode 0x0f,0xaa
514ece92f85SJason Jin ****************************************************************************/
x86emuOp2_bts_R(u8 X86EMU_UNUSED (op2))515ece92f85SJason Jin void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
516ece92f85SJason Jin {
517ece92f85SJason Jin int mod, rl, rh;
518ece92f85SJason Jin uint srcoffset;
519ece92f85SJason Jin int bit,disp;
520ece92f85SJason Jin
521ece92f85SJason Jin START_OF_INSTR();
522ece92f85SJason Jin DECODE_PRINTF("BTS\t");
523ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
524ece92f85SJason Jin if (mod < 3) {
525ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
526ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
527ece92f85SJason Jin u32 srcval,mask;
528ece92f85SJason Jin u32 *shiftreg;
529ece92f85SJason Jin
530ece92f85SJason Jin DECODE_PRINTF(",");
531ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
532ece92f85SJason Jin TRACE_AND_STEP();
533ece92f85SJason Jin bit = *shiftreg & 0x1F;
534ece92f85SJason Jin disp = (s16)*shiftreg >> 5;
535ece92f85SJason Jin srcval = fetch_data_long(srcoffset+disp);
536ece92f85SJason Jin mask = (0x1 << bit);
537ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
538ece92f85SJason Jin store_data_long(srcoffset+disp, srcval | mask);
539ece92f85SJason Jin } else {
540ece92f85SJason Jin u16 srcval,mask;
541ece92f85SJason Jin u16 *shiftreg;
542ece92f85SJason Jin
543ece92f85SJason Jin DECODE_PRINTF(",");
544ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
545ece92f85SJason Jin TRACE_AND_STEP();
546ece92f85SJason Jin bit = *shiftreg & 0xF;
547ece92f85SJason Jin disp = (s16)*shiftreg >> 4;
548ece92f85SJason Jin srcval = fetch_data_word(srcoffset+disp);
549ece92f85SJason Jin mask = (u16)(0x1 << bit);
550ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
551ece92f85SJason Jin store_data_word(srcoffset+disp, srcval | mask);
552ece92f85SJason Jin }
553ece92f85SJason Jin } else { /* register to register */
554ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
555ece92f85SJason Jin u32 *srcreg,*shiftreg;
556ece92f85SJason Jin u32 mask;
557ece92f85SJason Jin
558ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
559ece92f85SJason Jin DECODE_PRINTF(",");
560ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
561ece92f85SJason Jin TRACE_AND_STEP();
562ece92f85SJason Jin bit = *shiftreg & 0x1F;
563ece92f85SJason Jin mask = (0x1 << bit);
564ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
565ece92f85SJason Jin *srcreg |= mask;
566ece92f85SJason Jin } else {
567ece92f85SJason Jin u16 *srcreg,*shiftreg;
568ece92f85SJason Jin u16 mask;
569ece92f85SJason Jin
570ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
571ece92f85SJason Jin DECODE_PRINTF(",");
572ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
573ece92f85SJason Jin TRACE_AND_STEP();
574ece92f85SJason Jin bit = *shiftreg & 0xF;
575ece92f85SJason Jin mask = (u16)(0x1 << bit);
576ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
577ece92f85SJason Jin *srcreg |= mask;
578ece92f85SJason Jin }
579ece92f85SJason Jin }
580ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
581ece92f85SJason Jin END_OF_INSTR();
582ece92f85SJason Jin }
583ece92f85SJason Jin
584ece92f85SJason Jin /****************************************************************************
585ece92f85SJason Jin REMARKS:
586ece92f85SJason Jin Handles opcode 0x0f,0xac
587ece92f85SJason Jin ****************************************************************************/
x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED (op2))588ece92f85SJason Jin void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
589ece92f85SJason Jin {
590ece92f85SJason Jin int mod, rl, rh;
591ece92f85SJason Jin uint destoffset;
592ece92f85SJason Jin u8 shift;
593ece92f85SJason Jin
594ece92f85SJason Jin START_OF_INSTR();
595ece92f85SJason Jin DECODE_PRINTF("SHLD\t");
596ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
597ece92f85SJason Jin if (mod < 3) {
598ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
599ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
600ece92f85SJason Jin u32 destval;
601ece92f85SJason Jin u32 *shiftreg;
602ece92f85SJason Jin
603ece92f85SJason Jin DECODE_PRINTF(",");
604ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
605ece92f85SJason Jin DECODE_PRINTF(",");
606ece92f85SJason Jin shift = fetch_byte_imm();
607ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift);
608ece92f85SJason Jin TRACE_AND_STEP();
609ece92f85SJason Jin destval = fetch_data_long(destoffset);
610ece92f85SJason Jin destval = shrd_long(destval,*shiftreg,shift);
611ece92f85SJason Jin store_data_long(destoffset, destval);
612ece92f85SJason Jin } else {
613ece92f85SJason Jin u16 destval;
614ece92f85SJason Jin u16 *shiftreg;
615ece92f85SJason Jin
616ece92f85SJason Jin DECODE_PRINTF(",");
617ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
618ece92f85SJason Jin DECODE_PRINTF(",");
619ece92f85SJason Jin shift = fetch_byte_imm();
620ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift);
621ece92f85SJason Jin TRACE_AND_STEP();
622ece92f85SJason Jin destval = fetch_data_word(destoffset);
623ece92f85SJason Jin destval = shrd_word(destval,*shiftreg,shift);
624ece92f85SJason Jin store_data_word(destoffset, destval);
625ece92f85SJason Jin }
626ece92f85SJason Jin } else { /* register to register */
627ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
628ece92f85SJason Jin u32 *destreg,*shiftreg;
629ece92f85SJason Jin
630ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
631ece92f85SJason Jin DECODE_PRINTF(",");
632ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
633ece92f85SJason Jin DECODE_PRINTF(",");
634ece92f85SJason Jin shift = fetch_byte_imm();
635ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift);
636ece92f85SJason Jin TRACE_AND_STEP();
637ece92f85SJason Jin *destreg = shrd_long(*destreg,*shiftreg,shift);
638ece92f85SJason Jin } else {
639ece92f85SJason Jin u16 *destreg,*shiftreg;
640ece92f85SJason Jin
641ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
642ece92f85SJason Jin DECODE_PRINTF(",");
643ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
644ece92f85SJason Jin DECODE_PRINTF(",");
645ece92f85SJason Jin shift = fetch_byte_imm();
646ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift);
647ece92f85SJason Jin TRACE_AND_STEP();
648ece92f85SJason Jin *destreg = shrd_word(*destreg,*shiftreg,shift);
649ece92f85SJason Jin }
650ece92f85SJason Jin }
651ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
652ece92f85SJason Jin END_OF_INSTR();
653ece92f85SJason Jin }
654ece92f85SJason Jin
655ece92f85SJason Jin /****************************************************************************
656ece92f85SJason Jin REMARKS:
657ece92f85SJason Jin Handles opcode 0x0f,0xad
658ece92f85SJason Jin ****************************************************************************/
x86emuOp2_shrd_CL(u8 X86EMU_UNUSED (op2))659ece92f85SJason Jin void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
660ece92f85SJason Jin {
661ece92f85SJason Jin int mod, rl, rh;
662ece92f85SJason Jin uint destoffset;
663ece92f85SJason Jin
664ece92f85SJason Jin START_OF_INSTR();
665ece92f85SJason Jin DECODE_PRINTF("SHLD\t");
666ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
667ece92f85SJason Jin if (mod < 3) {
668ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl);
669ece92f85SJason Jin DECODE_PRINTF(",");
670ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
671ece92f85SJason Jin u32 destval;
672ece92f85SJason Jin u32 *shiftreg;
673ece92f85SJason Jin
674ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
675ece92f85SJason Jin DECODE_PRINTF(",CL\n");
676ece92f85SJason Jin TRACE_AND_STEP();
677ece92f85SJason Jin destval = fetch_data_long(destoffset);
678ece92f85SJason Jin destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
679ece92f85SJason Jin store_data_long(destoffset, destval);
680ece92f85SJason Jin } else {
681ece92f85SJason Jin u16 destval;
682ece92f85SJason Jin u16 *shiftreg;
683ece92f85SJason Jin
684ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
685ece92f85SJason Jin DECODE_PRINTF(",CL\n");
686ece92f85SJason Jin TRACE_AND_STEP();
687ece92f85SJason Jin destval = fetch_data_word(destoffset);
688ece92f85SJason Jin destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
689ece92f85SJason Jin store_data_word(destoffset, destval);
690ece92f85SJason Jin }
691ece92f85SJason Jin } else { /* register to register */
692ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
693ece92f85SJason Jin u32 *destreg,*shiftreg;
694ece92f85SJason Jin
695ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl);
696ece92f85SJason Jin DECODE_PRINTF(",");
697ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
698ece92f85SJason Jin DECODE_PRINTF(",CL\n");
699ece92f85SJason Jin TRACE_AND_STEP();
700ece92f85SJason Jin *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
701ece92f85SJason Jin } else {
702ece92f85SJason Jin u16 *destreg,*shiftreg;
703ece92f85SJason Jin
704ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl);
705ece92f85SJason Jin DECODE_PRINTF(",");
706ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
707ece92f85SJason Jin DECODE_PRINTF(",CL\n");
708ece92f85SJason Jin TRACE_AND_STEP();
709ece92f85SJason Jin *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
710ece92f85SJason Jin }
711ece92f85SJason Jin }
712ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
713ece92f85SJason Jin END_OF_INSTR();
714ece92f85SJason Jin }
715ece92f85SJason Jin
716ece92f85SJason Jin /****************************************************************************
717ece92f85SJason Jin REMARKS:
718ece92f85SJason Jin Handles opcode 0x0f,0xaf
719ece92f85SJason Jin ****************************************************************************/
x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED (op2))720ece92f85SJason Jin void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
721ece92f85SJason Jin {
722ece92f85SJason Jin int mod, rl, rh;
723ece92f85SJason Jin uint srcoffset;
724ece92f85SJason Jin
725ece92f85SJason Jin START_OF_INSTR();
726ece92f85SJason Jin DECODE_PRINTF("IMUL\t");
727ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
728ece92f85SJason Jin if (mod < 3) {
729ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
730ece92f85SJason Jin u32 *destreg;
731ece92f85SJason Jin u32 srcval;
732ece92f85SJason Jin u32 res_lo,res_hi;
733ece92f85SJason Jin
734ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
735ece92f85SJason Jin DECODE_PRINTF(",");
736ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
737ece92f85SJason Jin srcval = fetch_data_long(srcoffset);
738ece92f85SJason Jin TRACE_AND_STEP();
739ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
740ece92f85SJason Jin if (res_hi != 0) {
741ece92f85SJason Jin SET_FLAG(F_CF);
742ece92f85SJason Jin SET_FLAG(F_OF);
743ece92f85SJason Jin } else {
744ece92f85SJason Jin CLEAR_FLAG(F_CF);
745ece92f85SJason Jin CLEAR_FLAG(F_OF);
746ece92f85SJason Jin }
747ece92f85SJason Jin *destreg = (u32)res_lo;
748ece92f85SJason Jin } else {
749ece92f85SJason Jin u16 *destreg;
750ece92f85SJason Jin u16 srcval;
751ece92f85SJason Jin u32 res;
752ece92f85SJason Jin
753ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
754ece92f85SJason Jin DECODE_PRINTF(",");
755ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
756ece92f85SJason Jin srcval = fetch_data_word(srcoffset);
757ece92f85SJason Jin TRACE_AND_STEP();
758ece92f85SJason Jin res = (s16)*destreg * (s16)srcval;
759ece92f85SJason Jin if (res > 0xFFFF) {
760ece92f85SJason Jin SET_FLAG(F_CF);
761ece92f85SJason Jin SET_FLAG(F_OF);
762ece92f85SJason Jin } else {
763ece92f85SJason Jin CLEAR_FLAG(F_CF);
764ece92f85SJason Jin CLEAR_FLAG(F_OF);
765ece92f85SJason Jin }
766ece92f85SJason Jin *destreg = (u16)res;
767ece92f85SJason Jin }
768ece92f85SJason Jin } else { /* register to register */
769ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
770ece92f85SJason Jin u32 *destreg,*srcreg;
771ece92f85SJason Jin u32 res_lo,res_hi;
772ece92f85SJason Jin
773ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
774ece92f85SJason Jin DECODE_PRINTF(",");
775ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
776ece92f85SJason Jin TRACE_AND_STEP();
777ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
778ece92f85SJason Jin if (res_hi != 0) {
779ece92f85SJason Jin SET_FLAG(F_CF);
780ece92f85SJason Jin SET_FLAG(F_OF);
781ece92f85SJason Jin } else {
782ece92f85SJason Jin CLEAR_FLAG(F_CF);
783ece92f85SJason Jin CLEAR_FLAG(F_OF);
784ece92f85SJason Jin }
785ece92f85SJason Jin *destreg = (u32)res_lo;
786ece92f85SJason Jin } else {
787ece92f85SJason Jin u16 *destreg,*srcreg;
788ece92f85SJason Jin u32 res;
789ece92f85SJason Jin
790ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
791ece92f85SJason Jin DECODE_PRINTF(",");
792ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
793ece92f85SJason Jin res = (s16)*destreg * (s16)*srcreg;
794ece92f85SJason Jin if (res > 0xFFFF) {
795ece92f85SJason Jin SET_FLAG(F_CF);
796ece92f85SJason Jin SET_FLAG(F_OF);
797ece92f85SJason Jin } else {
798ece92f85SJason Jin CLEAR_FLAG(F_CF);
799ece92f85SJason Jin CLEAR_FLAG(F_OF);
800ece92f85SJason Jin }
801ece92f85SJason Jin *destreg = (u16)res;
802ece92f85SJason Jin }
803ece92f85SJason Jin }
804ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
805ece92f85SJason Jin END_OF_INSTR();
806ece92f85SJason Jin }
807ece92f85SJason Jin
808ece92f85SJason Jin /****************************************************************************
809ece92f85SJason Jin REMARKS:
810ece92f85SJason Jin Handles opcode 0x0f,0xb2
811ece92f85SJason Jin ****************************************************************************/
x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED (op2))812ece92f85SJason Jin void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
813ece92f85SJason Jin {
814ece92f85SJason Jin int mod, rh, rl;
815ece92f85SJason Jin u16 *dstreg;
816ece92f85SJason Jin uint srcoffset;
817ece92f85SJason Jin
818ece92f85SJason Jin START_OF_INSTR();
819ece92f85SJason Jin DECODE_PRINTF("LSS\t");
820ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
821ece92f85SJason Jin if (mod < 3) {
822ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh);
823ece92f85SJason Jin DECODE_PRINTF(",");
824ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
825ece92f85SJason Jin DECODE_PRINTF("\n");
826ece92f85SJason Jin TRACE_AND_STEP();
827ece92f85SJason Jin *dstreg = fetch_data_word(srcoffset);
828ece92f85SJason Jin M.x86.R_SS = fetch_data_word(srcoffset + 2);
829ece92f85SJason Jin } else { /* register to register */
830ece92f85SJason Jin /* UNDEFINED! */
831ece92f85SJason Jin TRACE_AND_STEP();
832ece92f85SJason Jin }
833ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
834ece92f85SJason Jin END_OF_INSTR();
835ece92f85SJason Jin }
836ece92f85SJason Jin
837ece92f85SJason Jin /****************************************************************************
838ece92f85SJason Jin REMARKS:
839ece92f85SJason Jin Handles opcode 0x0f,0xb3
840ece92f85SJason Jin ****************************************************************************/
x86emuOp2_btr_R(u8 X86EMU_UNUSED (op2))841ece92f85SJason Jin void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
842ece92f85SJason Jin {
843ece92f85SJason Jin int mod, rl, rh;
844ece92f85SJason Jin uint srcoffset;
845ece92f85SJason Jin int bit,disp;
846ece92f85SJason Jin
847ece92f85SJason Jin START_OF_INSTR();
848ece92f85SJason Jin DECODE_PRINTF("BTR\t");
849ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
850ece92f85SJason Jin if (mod < 3) {
851ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
852ece92f85SJason Jin DECODE_PRINTF(",");
853ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
854ece92f85SJason Jin u32 srcval,mask;
855ece92f85SJason Jin u32 *shiftreg;
856ece92f85SJason Jin
857ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
858ece92f85SJason Jin TRACE_AND_STEP();
859ece92f85SJason Jin bit = *shiftreg & 0x1F;
860ece92f85SJason Jin disp = (s16)*shiftreg >> 5;
861ece92f85SJason Jin srcval = fetch_data_long(srcoffset+disp);
862ece92f85SJason Jin mask = (0x1 << bit);
863ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
864ece92f85SJason Jin store_data_long(srcoffset+disp, srcval & ~mask);
865ece92f85SJason Jin } else {
866ece92f85SJason Jin u16 srcval,mask;
867ece92f85SJason Jin u16 *shiftreg;
868ece92f85SJason Jin
869ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
870ece92f85SJason Jin TRACE_AND_STEP();
871ece92f85SJason Jin bit = *shiftreg & 0xF;
872ece92f85SJason Jin disp = (s16)*shiftreg >> 4;
873ece92f85SJason Jin srcval = fetch_data_word(srcoffset+disp);
874ece92f85SJason Jin mask = (u16)(0x1 << bit);
875ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
876ece92f85SJason Jin store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
877ece92f85SJason Jin }
878ece92f85SJason Jin } else { /* register to register */
879ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
880ece92f85SJason Jin u32 *srcreg,*shiftreg;
881ece92f85SJason Jin u32 mask;
882ece92f85SJason Jin
883ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
884ece92f85SJason Jin DECODE_PRINTF(",");
885ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
886ece92f85SJason Jin TRACE_AND_STEP();
887ece92f85SJason Jin bit = *shiftreg & 0x1F;
888ece92f85SJason Jin mask = (0x1 << bit);
889ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
890ece92f85SJason Jin *srcreg &= ~mask;
891ece92f85SJason Jin } else {
892ece92f85SJason Jin u16 *srcreg,*shiftreg;
893ece92f85SJason Jin u16 mask;
894ece92f85SJason Jin
895ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
896ece92f85SJason Jin DECODE_PRINTF(",");
897ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
898ece92f85SJason Jin TRACE_AND_STEP();
899ece92f85SJason Jin bit = *shiftreg & 0xF;
900ece92f85SJason Jin mask = (u16)(0x1 << bit);
901ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
902ece92f85SJason Jin *srcreg &= ~mask;
903ece92f85SJason Jin }
904ece92f85SJason Jin }
905ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
906ece92f85SJason Jin END_OF_INSTR();
907ece92f85SJason Jin }
908ece92f85SJason Jin
909ece92f85SJason Jin /****************************************************************************
910ece92f85SJason Jin REMARKS:
911ece92f85SJason Jin Handles opcode 0x0f,0xb4
912ece92f85SJason Jin ****************************************************************************/
x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED (op2))913ece92f85SJason Jin void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
914ece92f85SJason Jin {
915ece92f85SJason Jin int mod, rh, rl;
916ece92f85SJason Jin u16 *dstreg;
917ece92f85SJason Jin uint srcoffset;
918ece92f85SJason Jin
919ece92f85SJason Jin START_OF_INSTR();
920ece92f85SJason Jin DECODE_PRINTF("LFS\t");
921ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
922ece92f85SJason Jin if (mod < 3) {
923ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh);
924ece92f85SJason Jin DECODE_PRINTF(",");
925ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
926ece92f85SJason Jin DECODE_PRINTF("\n");
927ece92f85SJason Jin TRACE_AND_STEP();
928ece92f85SJason Jin *dstreg = fetch_data_word(srcoffset);
929ece92f85SJason Jin M.x86.R_FS = fetch_data_word(srcoffset + 2);
930ece92f85SJason Jin } else { /* register to register */
931ece92f85SJason Jin /* UNDEFINED! */
932ece92f85SJason Jin TRACE_AND_STEP();
933ece92f85SJason Jin }
934ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
935ece92f85SJason Jin END_OF_INSTR();
936ece92f85SJason Jin }
937ece92f85SJason Jin
938ece92f85SJason Jin /****************************************************************************
939ece92f85SJason Jin REMARKS:
940ece92f85SJason Jin Handles opcode 0x0f,0xb5
941ece92f85SJason Jin ****************************************************************************/
x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED (op2))942ece92f85SJason Jin void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
943ece92f85SJason Jin {
944ece92f85SJason Jin int mod, rh, rl;
945ece92f85SJason Jin u16 *dstreg;
946ece92f85SJason Jin uint srcoffset;
947ece92f85SJason Jin
948ece92f85SJason Jin START_OF_INSTR();
949ece92f85SJason Jin DECODE_PRINTF("LGS\t");
950ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
951ece92f85SJason Jin if (mod < 3) {
952ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh);
953ece92f85SJason Jin DECODE_PRINTF(",");
954ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
955ece92f85SJason Jin DECODE_PRINTF("\n");
956ece92f85SJason Jin TRACE_AND_STEP();
957ece92f85SJason Jin *dstreg = fetch_data_word(srcoffset);
958ece92f85SJason Jin M.x86.R_GS = fetch_data_word(srcoffset + 2);
959ece92f85SJason Jin } else { /* register to register */
960ece92f85SJason Jin /* UNDEFINED! */
961ece92f85SJason Jin TRACE_AND_STEP();
962ece92f85SJason Jin }
963ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
964ece92f85SJason Jin END_OF_INSTR();
965ece92f85SJason Jin }
966ece92f85SJason Jin
967ece92f85SJason Jin /****************************************************************************
968ece92f85SJason Jin REMARKS:
969ece92f85SJason Jin Handles opcode 0x0f,0xb6
970ece92f85SJason Jin ****************************************************************************/
x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED (op2))971ece92f85SJason Jin void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
972ece92f85SJason Jin {
973ece92f85SJason Jin int mod, rl, rh;
974ece92f85SJason Jin uint srcoffset;
975ece92f85SJason Jin
976ece92f85SJason Jin START_OF_INSTR();
977ece92f85SJason Jin DECODE_PRINTF("MOVZX\t");
978ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
979ece92f85SJason Jin if (mod < 3) {
980ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
981ece92f85SJason Jin u32 *destreg;
982ece92f85SJason Jin u32 srcval;
983ece92f85SJason Jin
984ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
985ece92f85SJason Jin DECODE_PRINTF(",");
986ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
987ece92f85SJason Jin srcval = fetch_data_byte(srcoffset);
988ece92f85SJason Jin DECODE_PRINTF("\n");
989ece92f85SJason Jin TRACE_AND_STEP();
990ece92f85SJason Jin *destreg = srcval;
991ece92f85SJason Jin } else {
992ece92f85SJason Jin u16 *destreg;
993ece92f85SJason Jin u16 srcval;
994ece92f85SJason Jin
995ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
996ece92f85SJason Jin DECODE_PRINTF(",");
997ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
998ece92f85SJason Jin srcval = fetch_data_byte(srcoffset);
999ece92f85SJason Jin DECODE_PRINTF("\n");
1000ece92f85SJason Jin TRACE_AND_STEP();
1001ece92f85SJason Jin *destreg = srcval;
1002ece92f85SJason Jin }
1003ece92f85SJason Jin } else { /* register to register */
1004ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1005ece92f85SJason Jin u32 *destreg;
1006ece92f85SJason Jin u8 *srcreg;
1007ece92f85SJason Jin
1008ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1009ece92f85SJason Jin DECODE_PRINTF(",");
1010ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl);
1011ece92f85SJason Jin DECODE_PRINTF("\n");
1012ece92f85SJason Jin TRACE_AND_STEP();
1013ece92f85SJason Jin *destreg = *srcreg;
1014ece92f85SJason Jin } else {
1015ece92f85SJason Jin u16 *destreg;
1016ece92f85SJason Jin u8 *srcreg;
1017ece92f85SJason Jin
1018ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
1019ece92f85SJason Jin DECODE_PRINTF(",");
1020ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl);
1021ece92f85SJason Jin DECODE_PRINTF("\n");
1022ece92f85SJason Jin TRACE_AND_STEP();
1023ece92f85SJason Jin *destreg = *srcreg;
1024ece92f85SJason Jin }
1025ece92f85SJason Jin }
1026ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1027ece92f85SJason Jin END_OF_INSTR();
1028ece92f85SJason Jin }
1029ece92f85SJason Jin
1030ece92f85SJason Jin /****************************************************************************
1031ece92f85SJason Jin REMARKS:
1032ece92f85SJason Jin Handles opcode 0x0f,0xb7
1033ece92f85SJason Jin ****************************************************************************/
x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED (op2))1034ece92f85SJason Jin void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1035ece92f85SJason Jin {
1036ece92f85SJason Jin int mod, rl, rh;
1037ece92f85SJason Jin uint srcoffset;
1038ece92f85SJason Jin u32 *destreg;
1039ece92f85SJason Jin u32 srcval;
1040ece92f85SJason Jin u16 *srcreg;
1041ece92f85SJason Jin
1042ece92f85SJason Jin START_OF_INSTR();
1043ece92f85SJason Jin DECODE_PRINTF("MOVZX\t");
1044ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1045ece92f85SJason Jin if (mod < 3) {
1046ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1047ece92f85SJason Jin DECODE_PRINTF(",");
1048ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1049ece92f85SJason Jin srcval = fetch_data_word(srcoffset);
1050ece92f85SJason Jin DECODE_PRINTF("\n");
1051ece92f85SJason Jin TRACE_AND_STEP();
1052ece92f85SJason Jin *destreg = srcval;
1053ece92f85SJason Jin } else { /* register to register */
1054ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1055ece92f85SJason Jin DECODE_PRINTF(",");
1056ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
1057ece92f85SJason Jin DECODE_PRINTF("\n");
1058ece92f85SJason Jin TRACE_AND_STEP();
1059ece92f85SJason Jin *destreg = *srcreg;
1060ece92f85SJason Jin }
1061ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1062ece92f85SJason Jin END_OF_INSTR();
1063ece92f85SJason Jin }
1064ece92f85SJason Jin
1065ece92f85SJason Jin /****************************************************************************
1066ece92f85SJason Jin REMARKS:
1067ece92f85SJason Jin Handles opcode 0x0f,0xba
1068ece92f85SJason Jin ****************************************************************************/
x86emuOp2_btX_I(u8 X86EMU_UNUSED (op2))1069ece92f85SJason Jin void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1070ece92f85SJason Jin {
1071ece92f85SJason Jin int mod, rl, rh;
1072ece92f85SJason Jin uint srcoffset;
1073ece92f85SJason Jin u8 shift;
1074ece92f85SJason Jin int bit;
1075ece92f85SJason Jin
1076ece92f85SJason Jin START_OF_INSTR();
1077ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1078ece92f85SJason Jin switch (rh) {
1079ece92f85SJason Jin case 4:
1080ece92f85SJason Jin DECODE_PRINTF("BT\t");
1081ece92f85SJason Jin break;
1082ece92f85SJason Jin case 5:
1083ece92f85SJason Jin DECODE_PRINTF("BTS\t");
1084ece92f85SJason Jin break;
1085ece92f85SJason Jin case 6:
1086ece92f85SJason Jin DECODE_PRINTF("BTR\t");
1087ece92f85SJason Jin break;
1088ece92f85SJason Jin case 7:
1089ece92f85SJason Jin DECODE_PRINTF("BTC\t");
1090ece92f85SJason Jin break;
1091ece92f85SJason Jin default:
1092*8c6ec412SSimon Glass ERR_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1093ece92f85SJason Jin TRACE_REGS();
1094ece92f85SJason Jin printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1095ece92f85SJason Jin M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1096ece92f85SJason Jin HALT_SYS();
1097ece92f85SJason Jin }
1098ece92f85SJason Jin if (mod < 3) {
1099ece92f85SJason Jin
1100ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1101ece92f85SJason Jin shift = fetch_byte_imm();
1102ece92f85SJason Jin DECODE_PRINTF2(",%d\n", shift);
1103ece92f85SJason Jin TRACE_AND_STEP();
1104ece92f85SJason Jin
1105ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1106ece92f85SJason Jin u32 srcval, mask;
1107ece92f85SJason Jin
1108ece92f85SJason Jin bit = shift & 0x1F;
1109ece92f85SJason Jin srcval = fetch_data_long(srcoffset);
1110ece92f85SJason Jin mask = (0x1 << bit);
1111ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1112ece92f85SJason Jin switch (rh) {
1113ece92f85SJason Jin case 5:
1114ece92f85SJason Jin store_data_long(srcoffset, srcval | mask);
1115ece92f85SJason Jin break;
1116ece92f85SJason Jin case 6:
1117ece92f85SJason Jin store_data_long(srcoffset, srcval & ~mask);
1118ece92f85SJason Jin break;
1119ece92f85SJason Jin case 7:
1120ece92f85SJason Jin store_data_long(srcoffset, srcval ^ mask);
1121ece92f85SJason Jin break;
1122ece92f85SJason Jin default:
1123ece92f85SJason Jin break;
1124ece92f85SJason Jin }
1125ece92f85SJason Jin } else {
1126ece92f85SJason Jin u16 srcval, mask;
1127ece92f85SJason Jin
1128ece92f85SJason Jin bit = shift & 0xF;
1129ece92f85SJason Jin srcval = fetch_data_word(srcoffset);
1130ece92f85SJason Jin mask = (0x1 << bit);
1131ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1132ece92f85SJason Jin switch (rh) {
1133ece92f85SJason Jin case 5:
1134ece92f85SJason Jin store_data_word(srcoffset, srcval | mask);
1135ece92f85SJason Jin break;
1136ece92f85SJason Jin case 6:
1137ece92f85SJason Jin store_data_word(srcoffset, srcval & ~mask);
1138ece92f85SJason Jin break;
1139ece92f85SJason Jin case 7:
1140ece92f85SJason Jin store_data_word(srcoffset, srcval ^ mask);
1141ece92f85SJason Jin break;
1142ece92f85SJason Jin default:
1143ece92f85SJason Jin break;
1144ece92f85SJason Jin }
1145ece92f85SJason Jin }
1146ece92f85SJason Jin } else { /* register to register */
1147ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1148ece92f85SJason Jin u32 *srcreg;
1149ece92f85SJason Jin u32 mask;
1150ece92f85SJason Jin
1151ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
1152ece92f85SJason Jin shift = fetch_byte_imm();
1153ece92f85SJason Jin DECODE_PRINTF2(",%d\n", shift);
1154ece92f85SJason Jin TRACE_AND_STEP();
1155ece92f85SJason Jin bit = shift & 0x1F;
1156ece92f85SJason Jin mask = (0x1 << bit);
1157ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1158ece92f85SJason Jin switch (rh) {
1159ece92f85SJason Jin case 5:
1160ece92f85SJason Jin *srcreg |= mask;
1161ece92f85SJason Jin break;
1162ece92f85SJason Jin case 6:
1163ece92f85SJason Jin *srcreg &= ~mask;
1164ece92f85SJason Jin break;
1165ece92f85SJason Jin case 7:
1166ece92f85SJason Jin *srcreg ^= mask;
1167ece92f85SJason Jin break;
1168ece92f85SJason Jin default:
1169ece92f85SJason Jin break;
1170ece92f85SJason Jin }
1171ece92f85SJason Jin } else {
1172ece92f85SJason Jin u16 *srcreg;
1173ece92f85SJason Jin u16 mask;
1174ece92f85SJason Jin
1175ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
1176ece92f85SJason Jin shift = fetch_byte_imm();
1177ece92f85SJason Jin DECODE_PRINTF2(",%d\n", shift);
1178ece92f85SJason Jin TRACE_AND_STEP();
1179ece92f85SJason Jin bit = shift & 0xF;
1180ece92f85SJason Jin mask = (0x1 << bit);
1181ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1182ece92f85SJason Jin switch (rh) {
1183ece92f85SJason Jin case 5:
1184ece92f85SJason Jin *srcreg |= mask;
1185ece92f85SJason Jin break;
1186ece92f85SJason Jin case 6:
1187ece92f85SJason Jin *srcreg &= ~mask;
1188ece92f85SJason Jin break;
1189ece92f85SJason Jin case 7:
1190ece92f85SJason Jin *srcreg ^= mask;
1191ece92f85SJason Jin break;
1192ece92f85SJason Jin default:
1193ece92f85SJason Jin break;
1194ece92f85SJason Jin }
1195ece92f85SJason Jin }
1196ece92f85SJason Jin }
1197ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1198ece92f85SJason Jin END_OF_INSTR();
1199ece92f85SJason Jin }
1200ece92f85SJason Jin
1201ece92f85SJason Jin /****************************************************************************
1202ece92f85SJason Jin REMARKS:
1203ece92f85SJason Jin Handles opcode 0x0f,0xbb
1204ece92f85SJason Jin ****************************************************************************/
x86emuOp2_btc_R(u8 X86EMU_UNUSED (op2))1205ece92f85SJason Jin void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
1206ece92f85SJason Jin {
1207ece92f85SJason Jin int mod, rl, rh;
1208ece92f85SJason Jin uint srcoffset;
1209ece92f85SJason Jin int bit,disp;
1210ece92f85SJason Jin
1211ece92f85SJason Jin START_OF_INSTR();
1212ece92f85SJason Jin DECODE_PRINTF("BTC\t");
1213ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1214ece92f85SJason Jin if (mod < 3) {
1215ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1216ece92f85SJason Jin DECODE_PRINTF(",");
1217ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1218ece92f85SJason Jin u32 srcval,mask;
1219ece92f85SJason Jin u32 *shiftreg;
1220ece92f85SJason Jin
1221ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
1222ece92f85SJason Jin TRACE_AND_STEP();
1223ece92f85SJason Jin bit = *shiftreg & 0x1F;
1224ece92f85SJason Jin disp = (s16)*shiftreg >> 5;
1225ece92f85SJason Jin srcval = fetch_data_long(srcoffset+disp);
1226ece92f85SJason Jin mask = (0x1 << bit);
1227ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1228ece92f85SJason Jin store_data_long(srcoffset+disp, srcval ^ mask);
1229ece92f85SJason Jin } else {
1230ece92f85SJason Jin u16 srcval,mask;
1231ece92f85SJason Jin u16 *shiftreg;
1232ece92f85SJason Jin
1233ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
1234ece92f85SJason Jin TRACE_AND_STEP();
1235ece92f85SJason Jin bit = *shiftreg & 0xF;
1236ece92f85SJason Jin disp = (s16)*shiftreg >> 4;
1237ece92f85SJason Jin srcval = fetch_data_word(srcoffset+disp);
1238ece92f85SJason Jin mask = (u16)(0x1 << bit);
1239ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1240ece92f85SJason Jin store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
1241ece92f85SJason Jin }
1242ece92f85SJason Jin } else { /* register to register */
1243ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1244ece92f85SJason Jin u32 *srcreg,*shiftreg;
1245ece92f85SJason Jin u32 mask;
1246ece92f85SJason Jin
1247ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
1248ece92f85SJason Jin DECODE_PRINTF(",");
1249ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh);
1250ece92f85SJason Jin TRACE_AND_STEP();
1251ece92f85SJason Jin bit = *shiftreg & 0x1F;
1252ece92f85SJason Jin mask = (0x1 << bit);
1253ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1254ece92f85SJason Jin *srcreg ^= mask;
1255ece92f85SJason Jin } else {
1256ece92f85SJason Jin u16 *srcreg,*shiftreg;
1257ece92f85SJason Jin u16 mask;
1258ece92f85SJason Jin
1259ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
1260ece92f85SJason Jin DECODE_PRINTF(",");
1261ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh);
1262ece92f85SJason Jin TRACE_AND_STEP();
1263ece92f85SJason Jin bit = *shiftreg & 0xF;
1264ece92f85SJason Jin mask = (u16)(0x1 << bit);
1265ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1266ece92f85SJason Jin *srcreg ^= mask;
1267ece92f85SJason Jin }
1268ece92f85SJason Jin }
1269ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1270ece92f85SJason Jin END_OF_INSTR();
1271ece92f85SJason Jin }
1272ece92f85SJason Jin
1273ece92f85SJason Jin /****************************************************************************
1274ece92f85SJason Jin REMARKS:
1275ece92f85SJason Jin Handles opcode 0x0f,0xbc
1276ece92f85SJason Jin ****************************************************************************/
x86emuOp2_bsf(u8 X86EMU_UNUSED (op2))1277ece92f85SJason Jin void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
1278ece92f85SJason Jin {
1279ece92f85SJason Jin int mod, rl, rh;
1280ece92f85SJason Jin uint srcoffset;
1281ece92f85SJason Jin
1282ece92f85SJason Jin START_OF_INSTR();
1283ece92f85SJason Jin DECODE_PRINTF("BSF\n");
1284ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1285ece92f85SJason Jin if (mod < 3) {
1286ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1287ece92f85SJason Jin DECODE_PRINTF(",");
1288ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1289ece92f85SJason Jin u32 srcval, *dstreg;
1290ece92f85SJason Jin
1291ece92f85SJason Jin dstreg = DECODE_RM_LONG_REGISTER(rh);
1292ece92f85SJason Jin TRACE_AND_STEP();
1293ece92f85SJason Jin srcval = fetch_data_long(srcoffset);
1294ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1295ece92f85SJason Jin for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1296ece92f85SJason Jin if ((srcval >> *dstreg) & 1) break;
1297ece92f85SJason Jin } else {
1298ece92f85SJason Jin u16 srcval, *dstreg;
1299ece92f85SJason Jin
1300ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh);
1301ece92f85SJason Jin TRACE_AND_STEP();
1302ece92f85SJason Jin srcval = fetch_data_word(srcoffset);
1303ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1304ece92f85SJason Jin for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1305ece92f85SJason Jin if ((srcval >> *dstreg) & 1) break;
1306ece92f85SJason Jin }
1307ece92f85SJason Jin } else { /* register to register */
1308ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1309ece92f85SJason Jin u32 *srcreg, *dstreg;
1310ece92f85SJason Jin
1311ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
1312ece92f85SJason Jin DECODE_PRINTF(",");
1313ece92f85SJason Jin dstreg = DECODE_RM_LONG_REGISTER(rh);
1314ece92f85SJason Jin TRACE_AND_STEP();
1315ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1316ece92f85SJason Jin for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1317ece92f85SJason Jin if ((*srcreg >> *dstreg) & 1) break;
1318ece92f85SJason Jin } else {
1319ece92f85SJason Jin u16 *srcreg, *dstreg;
1320ece92f85SJason Jin
1321ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
1322ece92f85SJason Jin DECODE_PRINTF(",");
1323ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh);
1324ece92f85SJason Jin TRACE_AND_STEP();
1325ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1326ece92f85SJason Jin for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1327ece92f85SJason Jin if ((*srcreg >> *dstreg) & 1) break;
1328ece92f85SJason Jin }
1329ece92f85SJason Jin }
1330ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1331ece92f85SJason Jin END_OF_INSTR();
1332ece92f85SJason Jin }
1333ece92f85SJason Jin
1334ece92f85SJason Jin /****************************************************************************
1335ece92f85SJason Jin REMARKS:
1336ece92f85SJason Jin Handles opcode 0x0f,0xbd
1337ece92f85SJason Jin ****************************************************************************/
x86emuOp2_bsr(u8 X86EMU_UNUSED (op2))1338ece92f85SJason Jin void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
1339ece92f85SJason Jin {
1340ece92f85SJason Jin int mod, rl, rh;
1341ece92f85SJason Jin uint srcoffset;
1342ece92f85SJason Jin
1343ece92f85SJason Jin START_OF_INSTR();
1344ece92f85SJason Jin DECODE_PRINTF("BSF\n");
1345ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1346ece92f85SJason Jin if (mod < 3) {
1347ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1348ece92f85SJason Jin DECODE_PRINTF(",");
1349ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1350ece92f85SJason Jin u32 srcval, *dstreg;
1351ece92f85SJason Jin
1352ece92f85SJason Jin dstreg = DECODE_RM_LONG_REGISTER(rh);
1353ece92f85SJason Jin TRACE_AND_STEP();
1354ece92f85SJason Jin srcval = fetch_data_long(srcoffset);
1355ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1356ece92f85SJason Jin for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1357ece92f85SJason Jin if ((srcval >> *dstreg) & 1) break;
1358ece92f85SJason Jin } else {
1359ece92f85SJason Jin u16 srcval, *dstreg;
1360ece92f85SJason Jin
1361ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh);
1362ece92f85SJason Jin TRACE_AND_STEP();
1363ece92f85SJason Jin srcval = fetch_data_word(srcoffset);
1364ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1365ece92f85SJason Jin for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1366ece92f85SJason Jin if ((srcval >> *dstreg) & 1) break;
1367ece92f85SJason Jin }
1368ece92f85SJason Jin } else { /* register to register */
1369ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1370ece92f85SJason Jin u32 *srcreg, *dstreg;
1371ece92f85SJason Jin
1372ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl);
1373ece92f85SJason Jin DECODE_PRINTF(",");
1374ece92f85SJason Jin dstreg = DECODE_RM_LONG_REGISTER(rh);
1375ece92f85SJason Jin TRACE_AND_STEP();
1376ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1377ece92f85SJason Jin for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1378ece92f85SJason Jin if ((*srcreg >> *dstreg) & 1) break;
1379ece92f85SJason Jin } else {
1380ece92f85SJason Jin u16 *srcreg, *dstreg;
1381ece92f85SJason Jin
1382ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
1383ece92f85SJason Jin DECODE_PRINTF(",");
1384ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh);
1385ece92f85SJason Jin TRACE_AND_STEP();
1386ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1387ece92f85SJason Jin for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1388ece92f85SJason Jin if ((*srcreg >> *dstreg) & 1) break;
1389ece92f85SJason Jin }
1390ece92f85SJason Jin }
1391ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1392ece92f85SJason Jin END_OF_INSTR();
1393ece92f85SJason Jin }
1394ece92f85SJason Jin
1395ece92f85SJason Jin /****************************************************************************
1396ece92f85SJason Jin REMARKS:
1397ece92f85SJason Jin Handles opcode 0x0f,0xbe
1398ece92f85SJason Jin ****************************************************************************/
x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED (op2))1399ece92f85SJason Jin void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1400ece92f85SJason Jin {
1401ece92f85SJason Jin int mod, rl, rh;
1402ece92f85SJason Jin uint srcoffset;
1403ece92f85SJason Jin
1404ece92f85SJason Jin START_OF_INSTR();
1405ece92f85SJason Jin DECODE_PRINTF("MOVSX\t");
1406ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1407ece92f85SJason Jin if (mod < 3) {
1408ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1409ece92f85SJason Jin u32 *destreg;
1410ece92f85SJason Jin u32 srcval;
1411ece92f85SJason Jin
1412ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1413ece92f85SJason Jin DECODE_PRINTF(",");
1414ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1415ece92f85SJason Jin srcval = (s32)((s8)fetch_data_byte(srcoffset));
1416ece92f85SJason Jin DECODE_PRINTF("\n");
1417ece92f85SJason Jin TRACE_AND_STEP();
1418ece92f85SJason Jin *destreg = srcval;
1419ece92f85SJason Jin } else {
1420ece92f85SJason Jin u16 *destreg;
1421ece92f85SJason Jin u16 srcval;
1422ece92f85SJason Jin
1423ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
1424ece92f85SJason Jin DECODE_PRINTF(",");
1425ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1426ece92f85SJason Jin srcval = (s16)((s8)fetch_data_byte(srcoffset));
1427ece92f85SJason Jin DECODE_PRINTF("\n");
1428ece92f85SJason Jin TRACE_AND_STEP();
1429ece92f85SJason Jin *destreg = srcval;
1430ece92f85SJason Jin }
1431ece92f85SJason Jin } else { /* register to register */
1432ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1433ece92f85SJason Jin u32 *destreg;
1434ece92f85SJason Jin u8 *srcreg;
1435ece92f85SJason Jin
1436ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1437ece92f85SJason Jin DECODE_PRINTF(",");
1438ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl);
1439ece92f85SJason Jin DECODE_PRINTF("\n");
1440ece92f85SJason Jin TRACE_AND_STEP();
1441ece92f85SJason Jin *destreg = (s32)((s8)*srcreg);
1442ece92f85SJason Jin } else {
1443ece92f85SJason Jin u16 *destreg;
1444ece92f85SJason Jin u8 *srcreg;
1445ece92f85SJason Jin
1446ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh);
1447ece92f85SJason Jin DECODE_PRINTF(",");
1448ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl);
1449ece92f85SJason Jin DECODE_PRINTF("\n");
1450ece92f85SJason Jin TRACE_AND_STEP();
1451ece92f85SJason Jin *destreg = (s16)((s8)*srcreg);
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 0x0f,0xbf
1461ece92f85SJason Jin ****************************************************************************/
x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED (op2))1462ece92f85SJason Jin void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
1463ece92f85SJason Jin {
1464ece92f85SJason Jin int mod, rl, rh;
1465ece92f85SJason Jin uint srcoffset;
1466ece92f85SJason Jin u32 *destreg;
1467ece92f85SJason Jin u32 srcval;
1468ece92f85SJason Jin u16 *srcreg;
1469ece92f85SJason Jin
1470ece92f85SJason Jin START_OF_INSTR();
1471ece92f85SJason Jin DECODE_PRINTF("MOVSX\t");
1472ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl);
1473ece92f85SJason Jin if (mod < 3) {
1474ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1475ece92f85SJason Jin DECODE_PRINTF(",");
1476ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl);
1477ece92f85SJason Jin srcval = (s32)((s16)fetch_data_word(srcoffset));
1478ece92f85SJason Jin DECODE_PRINTF("\n");
1479ece92f85SJason Jin TRACE_AND_STEP();
1480ece92f85SJason Jin *destreg = srcval;
1481ece92f85SJason Jin } else { /* register to register */
1482ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh);
1483ece92f85SJason Jin DECODE_PRINTF(",");
1484ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl);
1485ece92f85SJason Jin DECODE_PRINTF("\n");
1486ece92f85SJason Jin TRACE_AND_STEP();
1487ece92f85SJason Jin *destreg = (s32)((s16)*srcreg);
1488ece92f85SJason Jin }
1489ece92f85SJason Jin DECODE_CLEAR_SEGOVR();
1490ece92f85SJason Jin END_OF_INSTR();
1491ece92f85SJason Jin }
1492ece92f85SJason Jin
1493ece92f85SJason Jin /***************************************************************************
1494ece92f85SJason Jin * Double byte operation code table:
1495ece92f85SJason Jin **************************************************************************/
1496285870f7SEd Swarthout void (*x86emu_optab2[256])(u8) =
1497ece92f85SJason Jin {
1498ece92f85SJason Jin /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
1499ece92f85SJason Jin /* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */
1500ece92f85SJason Jin /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
1501ece92f85SJason Jin /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
1502ece92f85SJason Jin /* 0x04 */ x86emuOp2_illegal_op,
1503ece92f85SJason Jin /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1504ece92f85SJason Jin /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
1505ece92f85SJason Jin /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1506ece92f85SJason Jin /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */
1507ece92f85SJason Jin /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */
1508ece92f85SJason Jin /* 0x0a */ x86emuOp2_illegal_op,
1509ece92f85SJason Jin /* 0x0b */ x86emuOp2_illegal_op,
1510ece92f85SJason Jin /* 0x0c */ x86emuOp2_illegal_op,
1511ece92f85SJason Jin /* 0x0d */ x86emuOp2_illegal_op,
1512ece92f85SJason Jin /* 0x0e */ x86emuOp2_illegal_op,
1513ece92f85SJason Jin /* 0x0f */ x86emuOp2_illegal_op,
1514ece92f85SJason Jin
1515ece92f85SJason Jin /* 0x10 */ x86emuOp2_illegal_op,
1516ece92f85SJason Jin /* 0x11 */ x86emuOp2_illegal_op,
1517ece92f85SJason Jin /* 0x12 */ x86emuOp2_illegal_op,
1518ece92f85SJason Jin /* 0x13 */ x86emuOp2_illegal_op,
1519ece92f85SJason Jin /* 0x14 */ x86emuOp2_illegal_op,
1520ece92f85SJason Jin /* 0x15 */ x86emuOp2_illegal_op,
1521ece92f85SJason Jin /* 0x16 */ x86emuOp2_illegal_op,
1522ece92f85SJason Jin /* 0x17 */ x86emuOp2_illegal_op,
1523ece92f85SJason Jin /* 0x18 */ x86emuOp2_illegal_op,
1524ece92f85SJason Jin /* 0x19 */ x86emuOp2_illegal_op,
1525ece92f85SJason Jin /* 0x1a */ x86emuOp2_illegal_op,
1526ece92f85SJason Jin /* 0x1b */ x86emuOp2_illegal_op,
1527ece92f85SJason Jin /* 0x1c */ x86emuOp2_illegal_op,
1528ece92f85SJason Jin /* 0x1d */ x86emuOp2_illegal_op,
1529ece92f85SJason Jin /* 0x1e */ x86emuOp2_illegal_op,
1530ece92f85SJason Jin /* 0x1f */ x86emuOp2_illegal_op,
1531ece92f85SJason Jin
1532ece92f85SJason Jin /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
1533ece92f85SJason Jin /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
1534ece92f85SJason Jin /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
1535ece92f85SJason Jin /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
1536ece92f85SJason Jin /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
1537ece92f85SJason Jin /* 0x25 */ x86emuOp2_illegal_op,
1538ece92f85SJason Jin /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
1539ece92f85SJason Jin /* 0x27 */ x86emuOp2_illegal_op,
1540ece92f85SJason Jin /* 0x28 */ x86emuOp2_illegal_op,
1541ece92f85SJason Jin /* 0x29 */ x86emuOp2_illegal_op,
1542ece92f85SJason Jin /* 0x2a */ x86emuOp2_illegal_op,
1543ece92f85SJason Jin /* 0x2b */ x86emuOp2_illegal_op,
1544ece92f85SJason Jin /* 0x2c */ x86emuOp2_illegal_op,
1545ece92f85SJason Jin /* 0x2d */ x86emuOp2_illegal_op,
1546ece92f85SJason Jin /* 0x2e */ x86emuOp2_illegal_op,
1547ece92f85SJason Jin /* 0x2f */ x86emuOp2_illegal_op,
1548ece92f85SJason Jin
1549ece92f85SJason Jin /* 0x30 */ x86emuOp2_illegal_op,
1550ece92f85SJason Jin /* 0x31 */ x86emuOp2_illegal_op,
1551ece92f85SJason Jin /* 0x32 */ x86emuOp2_illegal_op,
1552ece92f85SJason Jin /* 0x33 */ x86emuOp2_illegal_op,
1553ece92f85SJason Jin /* 0x34 */ x86emuOp2_illegal_op,
1554ece92f85SJason Jin /* 0x35 */ x86emuOp2_illegal_op,
1555ece92f85SJason Jin /* 0x36 */ x86emuOp2_illegal_op,
1556ece92f85SJason Jin /* 0x37 */ x86emuOp2_illegal_op,
1557ece92f85SJason Jin /* 0x38 */ x86emuOp2_illegal_op,
1558ece92f85SJason Jin /* 0x39 */ x86emuOp2_illegal_op,
1559ece92f85SJason Jin /* 0x3a */ x86emuOp2_illegal_op,
1560ece92f85SJason Jin /* 0x3b */ x86emuOp2_illegal_op,
1561ece92f85SJason Jin /* 0x3c */ x86emuOp2_illegal_op,
1562ece92f85SJason Jin /* 0x3d */ x86emuOp2_illegal_op,
1563ece92f85SJason Jin /* 0x3e */ x86emuOp2_illegal_op,
1564ece92f85SJason Jin /* 0x3f */ x86emuOp2_illegal_op,
1565ece92f85SJason Jin
1566ece92f85SJason Jin /* 0x40 */ x86emuOp2_illegal_op,
1567ece92f85SJason Jin /* 0x41 */ x86emuOp2_illegal_op,
1568ece92f85SJason Jin /* 0x42 */ x86emuOp2_illegal_op,
1569ece92f85SJason Jin /* 0x43 */ x86emuOp2_illegal_op,
1570ece92f85SJason Jin /* 0x44 */ x86emuOp2_illegal_op,
1571ece92f85SJason Jin /* 0x45 */ x86emuOp2_illegal_op,
1572ece92f85SJason Jin /* 0x46 */ x86emuOp2_illegal_op,
1573ece92f85SJason Jin /* 0x47 */ x86emuOp2_illegal_op,
1574ece92f85SJason Jin /* 0x48 */ x86emuOp2_illegal_op,
1575ece92f85SJason Jin /* 0x49 */ x86emuOp2_illegal_op,
1576ece92f85SJason Jin /* 0x4a */ x86emuOp2_illegal_op,
1577ece92f85SJason Jin /* 0x4b */ x86emuOp2_illegal_op,
1578ece92f85SJason Jin /* 0x4c */ x86emuOp2_illegal_op,
1579ece92f85SJason Jin /* 0x4d */ x86emuOp2_illegal_op,
1580ece92f85SJason Jin /* 0x4e */ x86emuOp2_illegal_op,
1581ece92f85SJason Jin /* 0x4f */ x86emuOp2_illegal_op,
1582ece92f85SJason Jin
1583ece92f85SJason Jin /* 0x50 */ x86emuOp2_illegal_op,
1584ece92f85SJason Jin /* 0x51 */ x86emuOp2_illegal_op,
1585ece92f85SJason Jin /* 0x52 */ x86emuOp2_illegal_op,
1586ece92f85SJason Jin /* 0x53 */ x86emuOp2_illegal_op,
1587ece92f85SJason Jin /* 0x54 */ x86emuOp2_illegal_op,
1588ece92f85SJason Jin /* 0x55 */ x86emuOp2_illegal_op,
1589ece92f85SJason Jin /* 0x56 */ x86emuOp2_illegal_op,
1590ece92f85SJason Jin /* 0x57 */ x86emuOp2_illegal_op,
1591ece92f85SJason Jin /* 0x58 */ x86emuOp2_illegal_op,
1592ece92f85SJason Jin /* 0x59 */ x86emuOp2_illegal_op,
1593ece92f85SJason Jin /* 0x5a */ x86emuOp2_illegal_op,
1594ece92f85SJason Jin /* 0x5b */ x86emuOp2_illegal_op,
1595ece92f85SJason Jin /* 0x5c */ x86emuOp2_illegal_op,
1596ece92f85SJason Jin /* 0x5d */ x86emuOp2_illegal_op,
1597ece92f85SJason Jin /* 0x5e */ x86emuOp2_illegal_op,
1598ece92f85SJason Jin /* 0x5f */ x86emuOp2_illegal_op,
1599ece92f85SJason Jin
1600ece92f85SJason Jin /* 0x60 */ x86emuOp2_illegal_op,
1601ece92f85SJason Jin /* 0x61 */ x86emuOp2_illegal_op,
1602ece92f85SJason Jin /* 0x62 */ x86emuOp2_illegal_op,
1603ece92f85SJason Jin /* 0x63 */ x86emuOp2_illegal_op,
1604ece92f85SJason Jin /* 0x64 */ x86emuOp2_illegal_op,
1605ece92f85SJason Jin /* 0x65 */ x86emuOp2_illegal_op,
1606ece92f85SJason Jin /* 0x66 */ x86emuOp2_illegal_op,
1607ece92f85SJason Jin /* 0x67 */ x86emuOp2_illegal_op,
1608ece92f85SJason Jin /* 0x68 */ x86emuOp2_illegal_op,
1609ece92f85SJason Jin /* 0x69 */ x86emuOp2_illegal_op,
1610ece92f85SJason Jin /* 0x6a */ x86emuOp2_illegal_op,
1611ece92f85SJason Jin /* 0x6b */ x86emuOp2_illegal_op,
1612ece92f85SJason Jin /* 0x6c */ x86emuOp2_illegal_op,
1613ece92f85SJason Jin /* 0x6d */ x86emuOp2_illegal_op,
1614ece92f85SJason Jin /* 0x6e */ x86emuOp2_illegal_op,
1615ece92f85SJason Jin /* 0x6f */ x86emuOp2_illegal_op,
1616ece92f85SJason Jin
1617ece92f85SJason Jin /* 0x70 */ x86emuOp2_illegal_op,
1618ece92f85SJason Jin /* 0x71 */ x86emuOp2_illegal_op,
1619ece92f85SJason Jin /* 0x72 */ x86emuOp2_illegal_op,
1620ece92f85SJason Jin /* 0x73 */ x86emuOp2_illegal_op,
1621ece92f85SJason Jin /* 0x74 */ x86emuOp2_illegal_op,
1622ece92f85SJason Jin /* 0x75 */ x86emuOp2_illegal_op,
1623ece92f85SJason Jin /* 0x76 */ x86emuOp2_illegal_op,
1624ece92f85SJason Jin /* 0x77 */ x86emuOp2_illegal_op,
1625ece92f85SJason Jin /* 0x78 */ x86emuOp2_illegal_op,
1626ece92f85SJason Jin /* 0x79 */ x86emuOp2_illegal_op,
1627ece92f85SJason Jin /* 0x7a */ x86emuOp2_illegal_op,
1628ece92f85SJason Jin /* 0x7b */ x86emuOp2_illegal_op,
1629ece92f85SJason Jin /* 0x7c */ x86emuOp2_illegal_op,
1630ece92f85SJason Jin /* 0x7d */ x86emuOp2_illegal_op,
1631ece92f85SJason Jin /* 0x7e */ x86emuOp2_illegal_op,
1632ece92f85SJason Jin /* 0x7f */ x86emuOp2_illegal_op,
1633ece92f85SJason Jin
1634ece92f85SJason Jin /* 0x80 */ x86emuOp2_long_jump,
1635ece92f85SJason Jin /* 0x81 */ x86emuOp2_long_jump,
1636ece92f85SJason Jin /* 0x82 */ x86emuOp2_long_jump,
1637ece92f85SJason Jin /* 0x83 */ x86emuOp2_long_jump,
1638ece92f85SJason Jin /* 0x84 */ x86emuOp2_long_jump,
1639ece92f85SJason Jin /* 0x85 */ x86emuOp2_long_jump,
1640ece92f85SJason Jin /* 0x86 */ x86emuOp2_long_jump,
1641ece92f85SJason Jin /* 0x87 */ x86emuOp2_long_jump,
1642ece92f85SJason Jin /* 0x88 */ x86emuOp2_long_jump,
1643ece92f85SJason Jin /* 0x89 */ x86emuOp2_long_jump,
1644ece92f85SJason Jin /* 0x8a */ x86emuOp2_long_jump,
1645ece92f85SJason Jin /* 0x8b */ x86emuOp2_long_jump,
1646ece92f85SJason Jin /* 0x8c */ x86emuOp2_long_jump,
1647ece92f85SJason Jin /* 0x8d */ x86emuOp2_long_jump,
1648ece92f85SJason Jin /* 0x8e */ x86emuOp2_long_jump,
1649ece92f85SJason Jin /* 0x8f */ x86emuOp2_long_jump,
1650ece92f85SJason Jin
1651ece92f85SJason Jin /* 0x90 */ x86emuOp2_set_byte,
1652ece92f85SJason Jin /* 0x91 */ x86emuOp2_set_byte,
1653ece92f85SJason Jin /* 0x92 */ x86emuOp2_set_byte,
1654ece92f85SJason Jin /* 0x93 */ x86emuOp2_set_byte,
1655ece92f85SJason Jin /* 0x94 */ x86emuOp2_set_byte,
1656ece92f85SJason Jin /* 0x95 */ x86emuOp2_set_byte,
1657ece92f85SJason Jin /* 0x96 */ x86emuOp2_set_byte,
1658ece92f85SJason Jin /* 0x97 */ x86emuOp2_set_byte,
1659ece92f85SJason Jin /* 0x98 */ x86emuOp2_set_byte,
1660ece92f85SJason Jin /* 0x99 */ x86emuOp2_set_byte,
1661ece92f85SJason Jin /* 0x9a */ x86emuOp2_set_byte,
1662ece92f85SJason Jin /* 0x9b */ x86emuOp2_set_byte,
1663ece92f85SJason Jin /* 0x9c */ x86emuOp2_set_byte,
1664ece92f85SJason Jin /* 0x9d */ x86emuOp2_set_byte,
1665ece92f85SJason Jin /* 0x9e */ x86emuOp2_set_byte,
1666ece92f85SJason Jin /* 0x9f */ x86emuOp2_set_byte,
1667ece92f85SJason Jin
1668ece92f85SJason Jin /* 0xa0 */ x86emuOp2_push_FS,
1669ece92f85SJason Jin /* 0xa1 */ x86emuOp2_pop_FS,
1670ece92f85SJason Jin /* 0xa2 */ x86emuOp2_illegal_op,
1671ece92f85SJason Jin /* 0xa3 */ x86emuOp2_bt_R,
1672ece92f85SJason Jin /* 0xa4 */ x86emuOp2_shld_IMM,
1673ece92f85SJason Jin /* 0xa5 */ x86emuOp2_shld_CL,
1674ece92f85SJason Jin /* 0xa6 */ x86emuOp2_illegal_op,
1675ece92f85SJason Jin /* 0xa7 */ x86emuOp2_illegal_op,
1676ece92f85SJason Jin /* 0xa8 */ x86emuOp2_push_GS,
1677ece92f85SJason Jin /* 0xa9 */ x86emuOp2_pop_GS,
1678ece92f85SJason Jin /* 0xaa */ x86emuOp2_illegal_op,
1679ece92f85SJason Jin /* 0xab */ x86emuOp2_bt_R,
1680ece92f85SJason Jin /* 0xac */ x86emuOp2_shrd_IMM,
1681ece92f85SJason Jin /* 0xad */ x86emuOp2_shrd_CL,
1682ece92f85SJason Jin /* 0xae */ x86emuOp2_illegal_op,
1683ece92f85SJason Jin /* 0xaf */ x86emuOp2_imul_R_RM,
1684ece92f85SJason Jin
1685ece92f85SJason Jin /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1686ece92f85SJason Jin /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1687ece92f85SJason Jin /* 0xb2 */ x86emuOp2_lss_R_IMM,
1688ece92f85SJason Jin /* 0xb3 */ x86emuOp2_btr_R,
1689ece92f85SJason Jin /* 0xb4 */ x86emuOp2_lfs_R_IMM,
1690ece92f85SJason Jin /* 0xb5 */ x86emuOp2_lgs_R_IMM,
1691ece92f85SJason Jin /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
1692ece92f85SJason Jin /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
1693ece92f85SJason Jin /* 0xb8 */ x86emuOp2_illegal_op,
1694ece92f85SJason Jin /* 0xb9 */ x86emuOp2_illegal_op,
1695ece92f85SJason Jin /* 0xba */ x86emuOp2_btX_I,
1696ece92f85SJason Jin /* 0xbb */ x86emuOp2_btc_R,
1697ece92f85SJason Jin /* 0xbc */ x86emuOp2_bsf,
1698ece92f85SJason Jin /* 0xbd */ x86emuOp2_bsr,
1699ece92f85SJason Jin /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
1700ece92f85SJason Jin /* 0xbf */ x86emuOp2_movsx_word_R_RM,
1701ece92f85SJason Jin
1702ece92f85SJason Jin /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
1703ece92f85SJason Jin /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
1704ece92f85SJason Jin /* 0xc2 */ x86emuOp2_illegal_op,
1705ece92f85SJason Jin /* 0xc3 */ x86emuOp2_illegal_op,
1706ece92f85SJason Jin /* 0xc4 */ x86emuOp2_illegal_op,
1707ece92f85SJason Jin /* 0xc5 */ x86emuOp2_illegal_op,
1708ece92f85SJason Jin /* 0xc6 */ x86emuOp2_illegal_op,
1709ece92f85SJason Jin /* 0xc7 */ x86emuOp2_illegal_op,
1710ece92f85SJason Jin /* 0xc8 */ x86emuOp2_illegal_op, /* TODO: bswap */
1711ece92f85SJason Jin /* 0xc9 */ x86emuOp2_illegal_op, /* TODO: bswap */
1712ece92f85SJason Jin /* 0xca */ x86emuOp2_illegal_op, /* TODO: bswap */
1713ece92f85SJason Jin /* 0xcb */ x86emuOp2_illegal_op, /* TODO: bswap */
1714ece92f85SJason Jin /* 0xcc */ x86emuOp2_illegal_op, /* TODO: bswap */
1715ece92f85SJason Jin /* 0xcd */ x86emuOp2_illegal_op, /* TODO: bswap */
1716ece92f85SJason Jin /* 0xce */ x86emuOp2_illegal_op, /* TODO: bswap */
1717ece92f85SJason Jin /* 0xcf */ x86emuOp2_illegal_op, /* TODO: bswap */
1718ece92f85SJason Jin
1719ece92f85SJason Jin /* 0xd0 */ x86emuOp2_illegal_op,
1720ece92f85SJason Jin /* 0xd1 */ x86emuOp2_illegal_op,
1721ece92f85SJason Jin /* 0xd2 */ x86emuOp2_illegal_op,
1722ece92f85SJason Jin /* 0xd3 */ x86emuOp2_illegal_op,
1723ece92f85SJason Jin /* 0xd4 */ x86emuOp2_illegal_op,
1724ece92f85SJason Jin /* 0xd5 */ x86emuOp2_illegal_op,
1725ece92f85SJason Jin /* 0xd6 */ x86emuOp2_illegal_op,
1726ece92f85SJason Jin /* 0xd7 */ x86emuOp2_illegal_op,
1727ece92f85SJason Jin /* 0xd8 */ x86emuOp2_illegal_op,
1728ece92f85SJason Jin /* 0xd9 */ x86emuOp2_illegal_op,
1729ece92f85SJason Jin /* 0xda */ x86emuOp2_illegal_op,
1730ece92f85SJason Jin /* 0xdb */ x86emuOp2_illegal_op,
1731ece92f85SJason Jin /* 0xdc */ x86emuOp2_illegal_op,
1732ece92f85SJason Jin /* 0xdd */ x86emuOp2_illegal_op,
1733ece92f85SJason Jin /* 0xde */ x86emuOp2_illegal_op,
1734ece92f85SJason Jin /* 0xdf */ x86emuOp2_illegal_op,
1735ece92f85SJason Jin
1736ece92f85SJason Jin /* 0xe0 */ x86emuOp2_illegal_op,
1737ece92f85SJason Jin /* 0xe1 */ x86emuOp2_illegal_op,
1738ece92f85SJason Jin /* 0xe2 */ x86emuOp2_illegal_op,
1739ece92f85SJason Jin /* 0xe3 */ x86emuOp2_illegal_op,
1740ece92f85SJason Jin /* 0xe4 */ x86emuOp2_illegal_op,
1741ece92f85SJason Jin /* 0xe5 */ x86emuOp2_illegal_op,
1742ece92f85SJason Jin /* 0xe6 */ x86emuOp2_illegal_op,
1743ece92f85SJason Jin /* 0xe7 */ x86emuOp2_illegal_op,
1744ece92f85SJason Jin /* 0xe8 */ x86emuOp2_illegal_op,
1745ece92f85SJason Jin /* 0xe9 */ x86emuOp2_illegal_op,
1746ece92f85SJason Jin /* 0xea */ x86emuOp2_illegal_op,
1747ece92f85SJason Jin /* 0xeb */ x86emuOp2_illegal_op,
1748ece92f85SJason Jin /* 0xec */ x86emuOp2_illegal_op,
1749ece92f85SJason Jin /* 0xed */ x86emuOp2_illegal_op,
1750ece92f85SJason Jin /* 0xee */ x86emuOp2_illegal_op,
1751ece92f85SJason Jin /* 0xef */ x86emuOp2_illegal_op,
1752ece92f85SJason Jin
1753ece92f85SJason Jin /* 0xf0 */ x86emuOp2_illegal_op,
1754ece92f85SJason Jin /* 0xf1 */ x86emuOp2_illegal_op,
1755ece92f85SJason Jin /* 0xf2 */ x86emuOp2_illegal_op,
1756ece92f85SJason Jin /* 0xf3 */ x86emuOp2_illegal_op,
1757ece92f85SJason Jin /* 0xf4 */ x86emuOp2_illegal_op,
1758ece92f85SJason Jin /* 0xf5 */ x86emuOp2_illegal_op,
1759ece92f85SJason Jin /* 0xf6 */ x86emuOp2_illegal_op,
1760ece92f85SJason Jin /* 0xf7 */ x86emuOp2_illegal_op,
1761ece92f85SJason Jin /* 0xf8 */ x86emuOp2_illegal_op,
1762ece92f85SJason Jin /* 0xf9 */ x86emuOp2_illegal_op,
1763ece92f85SJason Jin /* 0xfa */ x86emuOp2_illegal_op,
1764ece92f85SJason Jin /* 0xfb */ x86emuOp2_illegal_op,
1765ece92f85SJason Jin /* 0xfc */ x86emuOp2_illegal_op,
1766ece92f85SJason Jin /* 0xfd */ x86emuOp2_illegal_op,
1767ece92f85SJason Jin /* 0xfe */ x86emuOp2_illegal_op,
1768ece92f85SJason Jin /* 0xff */ x86emuOp2_illegal_op,
1769ece92f85SJason Jin };
1770