blob: 937bf4ce0732b8f683db0bce5b078081e6aef71d [file] [log] [blame]
Jason Jina63ce952007-07-06 08:34:56 +08001/****************************************************************************
2*
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02003* Realmode X86 Emulator Library
Jason Jina63ce952007-07-06 08:34:56 +08004*
Kumar Gala6a6d9482009-07-28 21:49:52 -05005* Copyright (C) 2007 Freescale Semiconductor, Inc.
Jason Jina63ce952007-07-06 08:34:56 +08006* Jason Jin <Jason.jin@freescale.com>
7*
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02008* Copyright (C) 1991-2004 SciTech Software, Inc.
9* Copyright (C) David Mosberger-Tang
10* Copyright (C) 1999 Egbert Eich
Jason Jina63ce952007-07-06 08:34:56 +080011*
12* ========================================================================
13*
14* Permission to use, copy, modify, distribute, and sell this software and
15* its documentation for any purpose is hereby granted without fee,
16* provided that the above copyright notice appear in all copies and that
17* both that copyright notice and this permission notice appear in
18* supporting documentation, and that the name of the authors not be used
19* in advertising or publicity pertaining to distribution of the software
Wolfgang Denk96bb2e02007-08-06 02:17:36 +020020* without specific, written prior permission. The authors makes no
Jason Jina63ce952007-07-06 08:34:56 +080021* representations about the suitability of this software for any purpose.
22* It is provided "as is" without express or implied warranty.
23*
24* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
25* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
26* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
27* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
28* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
29* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
30* PERFORMANCE OF THIS SOFTWARE.
31*
32* ========================================================================
33*
Wolfgang Denk96bb2e02007-08-06 02:17:36 +020034* Language: ANSI C
35* Environment: Any
36* Developer: Kendall Bennett
Jason Jina63ce952007-07-06 08:34:56 +080037*
Wolfgang Denk96bb2e02007-08-06 02:17:36 +020038* Description: This file includes subroutines to implement the decoding
39* and emulation of all the x86 extended two-byte processor
40* instructions.
Jason Jina63ce952007-07-06 08:34:56 +080041*
Jason Jina63ce952007-07-06 08:34:56 +080042****************************************************************************/
43
Michal Simekc73a4772007-08-16 10:46:28 +020044#include <common.h>
Michal Simek952d8612007-08-15 21:15:05 +020045#include "x86emu/x86emui.h"
46
Jason Jina63ce952007-07-06 08:34:56 +080047/*----------------------------- Implementation ----------------------------*/
48
49/****************************************************************************
50PARAMETERS:
51op1 - Instruction op code
52
53REMARKS:
54Handles illegal opcodes.
55****************************************************************************/
56void x86emuOp2_illegal_op(
57 u8 op2)
58{
59 START_OF_INSTR();
60 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
61 TRACE_REGS();
62 printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
Wolfgang Denk96bb2e02007-08-06 02:17:36 +020063 M.x86.R_CS, M.x86.R_IP-2,op2);
Jason Jina63ce952007-07-06 08:34:56 +080064 HALT_SYS();
65 END_OF_INSTR();
66}
67
68#define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
69
70/****************************************************************************
71REMARKS:
72Handles opcode 0x0f,0x80-0x8F
73****************************************************************************/
74int x86emu_check_jump_condition(u8 op)
75{
76 switch (op) {
77 case 0x0:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +020078 DECODE_PRINTF("JO\t");
79 return ACCESS_FLAG(F_OF);
Jason Jina63ce952007-07-06 08:34:56 +080080 case 0x1:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +020081 DECODE_PRINTF("JNO\t");
82 return !ACCESS_FLAG(F_OF);
83 break;
Jason Jina63ce952007-07-06 08:34:56 +080084 case 0x2:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +020085 DECODE_PRINTF("JB\t");
86 return ACCESS_FLAG(F_CF);
87 break;
Jason Jina63ce952007-07-06 08:34:56 +080088 case 0x3:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +020089 DECODE_PRINTF("JNB\t");
90 return !ACCESS_FLAG(F_CF);
91 break;
Jason Jina63ce952007-07-06 08:34:56 +080092 case 0x4:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +020093 DECODE_PRINTF("JZ\t");
94 return ACCESS_FLAG(F_ZF);
95 break;
Jason Jina63ce952007-07-06 08:34:56 +080096 case 0x5:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +020097 DECODE_PRINTF("JNZ\t");
98 return !ACCESS_FLAG(F_ZF);
99 break;
Jason Jina63ce952007-07-06 08:34:56 +0800100 case 0x6:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200101 DECODE_PRINTF("JBE\t");
102 return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
103 break;
Jason Jina63ce952007-07-06 08:34:56 +0800104 case 0x7:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200105 DECODE_PRINTF("JNBE\t");
106 return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
107 break;
Jason Jina63ce952007-07-06 08:34:56 +0800108 case 0x8:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200109 DECODE_PRINTF("JS\t");
110 return ACCESS_FLAG(F_SF);
111 break;
Jason Jina63ce952007-07-06 08:34:56 +0800112 case 0x9:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200113 DECODE_PRINTF("JNS\t");
114 return !ACCESS_FLAG(F_SF);
115 break;
Jason Jina63ce952007-07-06 08:34:56 +0800116 case 0xa:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200117 DECODE_PRINTF("JP\t");
118 return ACCESS_FLAG(F_PF);
119 break;
Jason Jina63ce952007-07-06 08:34:56 +0800120 case 0xb:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200121 DECODE_PRINTF("JNP\t");
122 return !ACCESS_FLAG(F_PF);
123 break;
Jason Jina63ce952007-07-06 08:34:56 +0800124 case 0xc:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200125 DECODE_PRINTF("JL\t");
126 return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
127 break;
Jason Jina63ce952007-07-06 08:34:56 +0800128 case 0xd:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200129 DECODE_PRINTF("JNL\t");
130 return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
131 break;
Jason Jina63ce952007-07-06 08:34:56 +0800132 case 0xe:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200133 DECODE_PRINTF("JLE\t");
134 return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
135 ACCESS_FLAG(F_ZF));
136 break;
Jason Jina63ce952007-07-06 08:34:56 +0800137 default:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200138 DECODE_PRINTF("JNLE\t");
139 return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
140 ACCESS_FLAG(F_ZF));
Jason Jina63ce952007-07-06 08:34:56 +0800141 }
142}
143
144void x86emuOp2_long_jump(u8 op2)
145{
146 s32 target;
147 int cond;
148
149 /* conditional jump to word offset. */
150 START_OF_INSTR();
151 cond = x86emu_check_jump_condition(op2 & 0xF);
152 target = (s16) fetch_word_imm();
153 target += (s16) M.x86.R_IP;
154 DECODE_PRINTF2("%04x\n", target);
155 TRACE_AND_STEP();
156 if (cond)
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200157 M.x86.R_IP = (u16)target;
Jason Jina63ce952007-07-06 08:34:56 +0800158 DECODE_CLEAR_SEGOVR();
159 END_OF_INSTR();
160}
161
162/****************************************************************************
163REMARKS:
164Handles opcode 0x0f,0x90-0x9F
165****************************************************************************/
166void x86emuOp2_set_byte(u8 op2)
167{
168 int mod, rl, rh;
169 uint destoffset;
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200170 u8 *destreg;
Jason Jina63ce952007-07-06 08:34:56 +0800171 char *name = 0;
172 int cond = 0;
173
174 START_OF_INSTR();
175 switch (op2) {
176 case 0x90:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200177 name = "SETO\t";
178 cond = ACCESS_FLAG(F_OF);
179 break;
Jason Jina63ce952007-07-06 08:34:56 +0800180 case 0x91:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200181 name = "SETNO\t";
182 cond = !ACCESS_FLAG(F_OF);
183 break;
Jason Jina63ce952007-07-06 08:34:56 +0800184 case 0x92:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200185 name = "SETB\t";
186 cond = ACCESS_FLAG(F_CF);
187 break;
Jason Jina63ce952007-07-06 08:34:56 +0800188 case 0x93:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200189 name = "SETNB\t";
190 cond = !ACCESS_FLAG(F_CF);
191 break;
Jason Jina63ce952007-07-06 08:34:56 +0800192 case 0x94:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200193 name = "SETZ\t";
194 cond = ACCESS_FLAG(F_ZF);
195 break;
Jason Jina63ce952007-07-06 08:34:56 +0800196 case 0x95:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200197 name = "SETNZ\t";
198 cond = !ACCESS_FLAG(F_ZF);
199 break;
Jason Jina63ce952007-07-06 08:34:56 +0800200 case 0x96:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200201 name = "SETBE\t";
202 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
203 break;
Jason Jina63ce952007-07-06 08:34:56 +0800204 case 0x97:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200205 name = "SETNBE\t";
206 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
207 break;
Jason Jina63ce952007-07-06 08:34:56 +0800208 case 0x98:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200209 name = "SETS\t";
210 cond = ACCESS_FLAG(F_SF);
211 break;
Jason Jina63ce952007-07-06 08:34:56 +0800212 case 0x99:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200213 name = "SETNS\t";
214 cond = !ACCESS_FLAG(F_SF);
215 break;
Jason Jina63ce952007-07-06 08:34:56 +0800216 case 0x9a:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200217 name = "SETP\t";
218 cond = ACCESS_FLAG(F_PF);
219 break;
Jason Jina63ce952007-07-06 08:34:56 +0800220 case 0x9b:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200221 name = "SETNP\t";
222 cond = !ACCESS_FLAG(F_PF);
223 break;
Jason Jina63ce952007-07-06 08:34:56 +0800224 case 0x9c:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200225 name = "SETL\t";
226 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
227 break;
Jason Jina63ce952007-07-06 08:34:56 +0800228 case 0x9d:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200229 name = "SETNL\t";
230 cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
231 break;
Jason Jina63ce952007-07-06 08:34:56 +0800232 case 0x9e:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200233 name = "SETLE\t";
234 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
235 ACCESS_FLAG(F_ZF));
236 break;
Jason Jina63ce952007-07-06 08:34:56 +0800237 case 0x9f:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200238 name = "SETNLE\t";
239 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
240 ACCESS_FLAG(F_ZF));
241 break;
Jason Jina63ce952007-07-06 08:34:56 +0800242 }
243 DECODE_PRINTF(name);
244 FETCH_DECODE_MODRM(mod, rh, rl);
245 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200246 destoffset = decode_rmXX_address(mod, rl);
247 TRACE_AND_STEP();
248 store_data_byte(destoffset, cond ? 0x01 : 0x00);
249 } else { /* register to register */
250 destreg = DECODE_RM_BYTE_REGISTER(rl);
251 TRACE_AND_STEP();
252 *destreg = cond ? 0x01 : 0x00;
Jason Jina63ce952007-07-06 08:34:56 +0800253 }
254 DECODE_CLEAR_SEGOVR();
255 END_OF_INSTR();
256}
257
258/****************************************************************************
259REMARKS:
260Handles opcode 0x0f,0xa0
261****************************************************************************/
262void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
263{
264 START_OF_INSTR();
265 DECODE_PRINTF("PUSH\tFS\n");
266 TRACE_AND_STEP();
267 push_word(M.x86.R_FS);
268 DECODE_CLEAR_SEGOVR();
269 END_OF_INSTR();
270}
271
272/****************************************************************************
273REMARKS:
274Handles opcode 0x0f,0xa1
275****************************************************************************/
276void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
277{
278 START_OF_INSTR();
279 DECODE_PRINTF("POP\tFS\n");
280 TRACE_AND_STEP();
281 M.x86.R_FS = pop_word();
282 DECODE_CLEAR_SEGOVR();
283 END_OF_INSTR();
284}
285
286/****************************************************************************
287REMARKS:
288Handles opcode 0x0f,0xa3
289****************************************************************************/
290void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
291{
292 int mod, rl, rh;
293 uint srcoffset;
294 int bit,disp;
295
296 START_OF_INSTR();
297 DECODE_PRINTF("BT\t");
298 FETCH_DECODE_MODRM(mod, rh, rl);
299 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200300 srcoffset = decode_rmXX_address(mod, rl);
301 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
302 u32 srcval;
303 u32 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800304
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200305 DECODE_PRINTF(",");
306 shiftreg = DECODE_RM_LONG_REGISTER(rh);
307 TRACE_AND_STEP();
308 bit = *shiftreg & 0x1F;
309 disp = (s16)*shiftreg >> 5;
310 srcval = fetch_data_long(srcoffset+disp);
311 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
312 } else {
313 u16 srcval;
314 u16 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800315
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200316 DECODE_PRINTF(",");
317 shiftreg = DECODE_RM_WORD_REGISTER(rh);
318 TRACE_AND_STEP();
319 bit = *shiftreg & 0xF;
320 disp = (s16)*shiftreg >> 4;
321 srcval = fetch_data_word(srcoffset+disp);
322 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
323 }
324 } else { /* register to register */
325 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
326 u32 *srcreg,*shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800327
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200328 srcreg = DECODE_RM_LONG_REGISTER(rl);
329 DECODE_PRINTF(",");
330 shiftreg = DECODE_RM_LONG_REGISTER(rh);
331 TRACE_AND_STEP();
332 bit = *shiftreg & 0x1F;
333 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
334 } else {
335 u16 *srcreg,*shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800336
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200337 srcreg = DECODE_RM_WORD_REGISTER(rl);
338 DECODE_PRINTF(",");
339 shiftreg = DECODE_RM_WORD_REGISTER(rh);
340 TRACE_AND_STEP();
341 bit = *shiftreg & 0xF;
342 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
343 }
Jason Jina63ce952007-07-06 08:34:56 +0800344 }
345 DECODE_CLEAR_SEGOVR();
346 END_OF_INSTR();
347}
348
349/****************************************************************************
350REMARKS:
351Handles opcode 0x0f,0xa4
352****************************************************************************/
353void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
354{
355 int mod, rl, rh;
356 uint destoffset;
357 u8 shift;
358
359 START_OF_INSTR();
360 DECODE_PRINTF("SHLD\t");
361 FETCH_DECODE_MODRM(mod, rh, rl);
362 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200363 destoffset = decode_rmXX_address(mod, rl);
364 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
365 u32 destval;
366 u32 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800367
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200368 DECODE_PRINTF(",");
369 shiftreg = DECODE_RM_LONG_REGISTER(rh);
370 DECODE_PRINTF(",");
371 shift = fetch_byte_imm();
372 DECODE_PRINTF2("%d\n", shift);
373 TRACE_AND_STEP();
374 destval = fetch_data_long(destoffset);
375 destval = shld_long(destval,*shiftreg,shift);
376 store_data_long(destoffset, destval);
377 } else {
378 u16 destval;
379 u16 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800380
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200381 DECODE_PRINTF(",");
382 shiftreg = DECODE_RM_WORD_REGISTER(rh);
383 DECODE_PRINTF(",");
384 shift = fetch_byte_imm();
385 DECODE_PRINTF2("%d\n", shift);
386 TRACE_AND_STEP();
387 destval = fetch_data_word(destoffset);
388 destval = shld_word(destval,*shiftreg,shift);
389 store_data_word(destoffset, destval);
390 }
391 } else { /* register to register */
392 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
393 u32 *destreg,*shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800394
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200395 destreg = DECODE_RM_LONG_REGISTER(rl);
396 DECODE_PRINTF(",");
397 shiftreg = DECODE_RM_LONG_REGISTER(rh);
398 DECODE_PRINTF(",");
399 shift = fetch_byte_imm();
400 DECODE_PRINTF2("%d\n", shift);
401 TRACE_AND_STEP();
402 *destreg = shld_long(*destreg,*shiftreg,shift);
403 } else {
404 u16 *destreg,*shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800405
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200406 destreg = DECODE_RM_WORD_REGISTER(rl);
407 DECODE_PRINTF(",");
408 shiftreg = DECODE_RM_WORD_REGISTER(rh);
409 DECODE_PRINTF(",");
410 shift = fetch_byte_imm();
411 DECODE_PRINTF2("%d\n", shift);
412 TRACE_AND_STEP();
413 *destreg = shld_word(*destreg,*shiftreg,shift);
414 }
Jason Jina63ce952007-07-06 08:34:56 +0800415 }
416 DECODE_CLEAR_SEGOVR();
417 END_OF_INSTR();
418}
419
420/****************************************************************************
421REMARKS:
422Handles opcode 0x0f,0xa5
423****************************************************************************/
424void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
425{
426 int mod, rl, rh;
427 uint destoffset;
428
429 START_OF_INSTR();
430 DECODE_PRINTF("SHLD\t");
431 FETCH_DECODE_MODRM(mod, rh, rl);
432 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200433 destoffset = decode_rmXX_address(mod, rl);
434 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
435 u32 destval;
436 u32 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800437
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200438 DECODE_PRINTF(",");
439 shiftreg = DECODE_RM_LONG_REGISTER(rh);
440 DECODE_PRINTF(",CL\n");
441 TRACE_AND_STEP();
442 destval = fetch_data_long(destoffset);
443 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
444 store_data_long(destoffset, destval);
445 } else {
446 u16 destval;
447 u16 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800448
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200449 DECODE_PRINTF(",");
450 shiftreg = DECODE_RM_WORD_REGISTER(rh);
451 DECODE_PRINTF(",CL\n");
452 TRACE_AND_STEP();
453 destval = fetch_data_word(destoffset);
454 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
455 store_data_word(destoffset, destval);
456 }
457 } else { /* register to register */
458 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
459 u32 *destreg,*shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800460
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200461 destreg = DECODE_RM_LONG_REGISTER(rl);
462 DECODE_PRINTF(",");
463 shiftreg = DECODE_RM_LONG_REGISTER(rh);
464 DECODE_PRINTF(",CL\n");
465 TRACE_AND_STEP();
466 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
467 } else {
468 u16 *destreg,*shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800469
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200470 destreg = DECODE_RM_WORD_REGISTER(rl);
471 DECODE_PRINTF(",");
472 shiftreg = DECODE_RM_WORD_REGISTER(rh);
473 DECODE_PRINTF(",CL\n");
474 TRACE_AND_STEP();
475 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
476 }
Jason Jina63ce952007-07-06 08:34:56 +0800477 }
478 DECODE_CLEAR_SEGOVR();
479 END_OF_INSTR();
480}
481
482/****************************************************************************
483REMARKS:
484Handles opcode 0x0f,0xa8
485****************************************************************************/
486void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
487{
488 START_OF_INSTR();
489 DECODE_PRINTF("PUSH\tGS\n");
490 TRACE_AND_STEP();
491 push_word(M.x86.R_GS);
492 DECODE_CLEAR_SEGOVR();
493 END_OF_INSTR();
494}
495
496/****************************************************************************
497REMARKS:
498Handles opcode 0x0f,0xa9
499****************************************************************************/
500void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
501{
502 START_OF_INSTR();
503 DECODE_PRINTF("POP\tGS\n");
504 TRACE_AND_STEP();
505 M.x86.R_GS = pop_word();
506 DECODE_CLEAR_SEGOVR();
507 END_OF_INSTR();
508}
509
510/****************************************************************************
511REMARKS:
512Handles opcode 0x0f,0xaa
513****************************************************************************/
514void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
515{
516 int mod, rl, rh;
517 uint srcoffset;
518 int bit,disp;
519
520 START_OF_INSTR();
521 DECODE_PRINTF("BTS\t");
522 FETCH_DECODE_MODRM(mod, rh, rl);
523 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200524 srcoffset = decode_rmXX_address(mod, rl);
525 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
526 u32 srcval,mask;
527 u32 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800528
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200529 DECODE_PRINTF(",");
530 shiftreg = DECODE_RM_LONG_REGISTER(rh);
531 TRACE_AND_STEP();
532 bit = *shiftreg & 0x1F;
533 disp = (s16)*shiftreg >> 5;
534 srcval = fetch_data_long(srcoffset+disp);
535 mask = (0x1 << bit);
536 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
537 store_data_long(srcoffset+disp, srcval | mask);
538 } else {
539 u16 srcval,mask;
540 u16 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800541
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200542 DECODE_PRINTF(",");
543 shiftreg = DECODE_RM_WORD_REGISTER(rh);
544 TRACE_AND_STEP();
545 bit = *shiftreg & 0xF;
546 disp = (s16)*shiftreg >> 4;
547 srcval = fetch_data_word(srcoffset+disp);
548 mask = (u16)(0x1 << bit);
549 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
550 store_data_word(srcoffset+disp, srcval | mask);
551 }
552 } else { /* register to register */
553 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
554 u32 *srcreg,*shiftreg;
555 u32 mask;
Jason Jina63ce952007-07-06 08:34:56 +0800556
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200557 srcreg = DECODE_RM_LONG_REGISTER(rl);
558 DECODE_PRINTF(",");
559 shiftreg = DECODE_RM_LONG_REGISTER(rh);
560 TRACE_AND_STEP();
561 bit = *shiftreg & 0x1F;
562 mask = (0x1 << bit);
563 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
564 *srcreg |= mask;
565 } else {
566 u16 *srcreg,*shiftreg;
567 u16 mask;
Jason Jina63ce952007-07-06 08:34:56 +0800568
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200569 srcreg = DECODE_RM_WORD_REGISTER(rl);
570 DECODE_PRINTF(",");
571 shiftreg = DECODE_RM_WORD_REGISTER(rh);
572 TRACE_AND_STEP();
573 bit = *shiftreg & 0xF;
574 mask = (u16)(0x1 << bit);
575 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
576 *srcreg |= mask;
577 }
Jason Jina63ce952007-07-06 08:34:56 +0800578 }
579 DECODE_CLEAR_SEGOVR();
580 END_OF_INSTR();
581}
582
583/****************************************************************************
584REMARKS:
585Handles opcode 0x0f,0xac
586****************************************************************************/
587void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
588{
589 int mod, rl, rh;
590 uint destoffset;
591 u8 shift;
592
593 START_OF_INSTR();
594 DECODE_PRINTF("SHLD\t");
595 FETCH_DECODE_MODRM(mod, rh, rl);
596 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200597 destoffset = decode_rmXX_address(mod, rl);
598 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
599 u32 destval;
600 u32 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800601
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200602 DECODE_PRINTF(",");
603 shiftreg = DECODE_RM_LONG_REGISTER(rh);
604 DECODE_PRINTF(",");
605 shift = fetch_byte_imm();
606 DECODE_PRINTF2("%d\n", shift);
607 TRACE_AND_STEP();
608 destval = fetch_data_long(destoffset);
609 destval = shrd_long(destval,*shiftreg,shift);
610 store_data_long(destoffset, destval);
611 } else {
612 u16 destval;
613 u16 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800614
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200615 DECODE_PRINTF(",");
616 shiftreg = DECODE_RM_WORD_REGISTER(rh);
617 DECODE_PRINTF(",");
618 shift = fetch_byte_imm();
619 DECODE_PRINTF2("%d\n", shift);
620 TRACE_AND_STEP();
621 destval = fetch_data_word(destoffset);
622 destval = shrd_word(destval,*shiftreg,shift);
623 store_data_word(destoffset, destval);
624 }
625 } else { /* register to register */
626 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
627 u32 *destreg,*shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800628
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200629 destreg = DECODE_RM_LONG_REGISTER(rl);
630 DECODE_PRINTF(",");
631 shiftreg = DECODE_RM_LONG_REGISTER(rh);
632 DECODE_PRINTF(",");
633 shift = fetch_byte_imm();
634 DECODE_PRINTF2("%d\n", shift);
635 TRACE_AND_STEP();
636 *destreg = shrd_long(*destreg,*shiftreg,shift);
637 } else {
638 u16 *destreg,*shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800639
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200640 destreg = DECODE_RM_WORD_REGISTER(rl);
641 DECODE_PRINTF(",");
642 shiftreg = DECODE_RM_WORD_REGISTER(rh);
643 DECODE_PRINTF(",");
644 shift = fetch_byte_imm();
645 DECODE_PRINTF2("%d\n", shift);
646 TRACE_AND_STEP();
647 *destreg = shrd_word(*destreg,*shiftreg,shift);
648 }
Jason Jina63ce952007-07-06 08:34:56 +0800649 }
650 DECODE_CLEAR_SEGOVR();
651 END_OF_INSTR();
652}
653
654/****************************************************************************
655REMARKS:
656Handles opcode 0x0f,0xad
657****************************************************************************/
658void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
659{
660 int mod, rl, rh;
661 uint destoffset;
662
663 START_OF_INSTR();
664 DECODE_PRINTF("SHLD\t");
665 FETCH_DECODE_MODRM(mod, rh, rl);
666 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200667 destoffset = decode_rmXX_address(mod, rl);
668 DECODE_PRINTF(",");
669 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
670 u32 destval;
671 u32 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800672
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200673 shiftreg = DECODE_RM_LONG_REGISTER(rh);
674 DECODE_PRINTF(",CL\n");
675 TRACE_AND_STEP();
676 destval = fetch_data_long(destoffset);
677 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
678 store_data_long(destoffset, destval);
679 } else {
680 u16 destval;
681 u16 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800682
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200683 shiftreg = DECODE_RM_WORD_REGISTER(rh);
684 DECODE_PRINTF(",CL\n");
685 TRACE_AND_STEP();
686 destval = fetch_data_word(destoffset);
687 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
688 store_data_word(destoffset, destval);
689 }
690 } else { /* register to register */
691 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
692 u32 *destreg,*shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800693
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200694 destreg = DECODE_RM_LONG_REGISTER(rl);
695 DECODE_PRINTF(",");
696 shiftreg = DECODE_RM_LONG_REGISTER(rh);
697 DECODE_PRINTF(",CL\n");
698 TRACE_AND_STEP();
699 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
700 } else {
701 u16 *destreg,*shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800702
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200703 destreg = DECODE_RM_WORD_REGISTER(rl);
704 DECODE_PRINTF(",");
705 shiftreg = DECODE_RM_WORD_REGISTER(rh);
706 DECODE_PRINTF(",CL\n");
707 TRACE_AND_STEP();
708 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
709 }
Jason Jina63ce952007-07-06 08:34:56 +0800710 }
711 DECODE_CLEAR_SEGOVR();
712 END_OF_INSTR();
713}
714
715/****************************************************************************
716REMARKS:
717Handles opcode 0x0f,0xaf
718****************************************************************************/
719void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
720{
721 int mod, rl, rh;
722 uint srcoffset;
723
724 START_OF_INSTR();
725 DECODE_PRINTF("IMUL\t");
726 FETCH_DECODE_MODRM(mod, rh, rl);
727 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200728 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
729 u32 *destreg;
730 u32 srcval;
731 u32 res_lo,res_hi;
Jason Jina63ce952007-07-06 08:34:56 +0800732
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200733 destreg = DECODE_RM_LONG_REGISTER(rh);
734 DECODE_PRINTF(",");
735 srcoffset = decode_rmXX_address(mod, rl);
736 srcval = fetch_data_long(srcoffset);
737 TRACE_AND_STEP();
738 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
739 if (res_hi != 0) {
740 SET_FLAG(F_CF);
741 SET_FLAG(F_OF);
742 } else {
743 CLEAR_FLAG(F_CF);
744 CLEAR_FLAG(F_OF);
745 }
746 *destreg = (u32)res_lo;
747 } else {
748 u16 *destreg;
749 u16 srcval;
750 u32 res;
Jason Jina63ce952007-07-06 08:34:56 +0800751
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200752 destreg = DECODE_RM_WORD_REGISTER(rh);
753 DECODE_PRINTF(",");
754 srcoffset = decode_rmXX_address(mod, rl);
755 srcval = fetch_data_word(srcoffset);
756 TRACE_AND_STEP();
757 res = (s16)*destreg * (s16)srcval;
758 if (res > 0xFFFF) {
759 SET_FLAG(F_CF);
760 SET_FLAG(F_OF);
761 } else {
762 CLEAR_FLAG(F_CF);
763 CLEAR_FLAG(F_OF);
764 }
765 *destreg = (u16)res;
766 }
767 } else { /* register to register */
768 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
769 u32 *destreg,*srcreg;
770 u32 res_lo,res_hi;
Jason Jina63ce952007-07-06 08:34:56 +0800771
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200772 destreg = DECODE_RM_LONG_REGISTER(rh);
773 DECODE_PRINTF(",");
774 srcreg = DECODE_RM_LONG_REGISTER(rl);
775 TRACE_AND_STEP();
776 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
777 if (res_hi != 0) {
778 SET_FLAG(F_CF);
779 SET_FLAG(F_OF);
780 } else {
781 CLEAR_FLAG(F_CF);
782 CLEAR_FLAG(F_OF);
783 }
784 *destreg = (u32)res_lo;
785 } else {
786 u16 *destreg,*srcreg;
787 u32 res;
Jason Jina63ce952007-07-06 08:34:56 +0800788
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200789 destreg = DECODE_RM_WORD_REGISTER(rh);
790 DECODE_PRINTF(",");
791 srcreg = DECODE_RM_WORD_REGISTER(rl);
792 res = (s16)*destreg * (s16)*srcreg;
793 if (res > 0xFFFF) {
794 SET_FLAG(F_CF);
795 SET_FLAG(F_OF);
796 } else {
797 CLEAR_FLAG(F_CF);
798 CLEAR_FLAG(F_OF);
799 }
800 *destreg = (u16)res;
801 }
Jason Jina63ce952007-07-06 08:34:56 +0800802 }
803 DECODE_CLEAR_SEGOVR();
804 END_OF_INSTR();
805}
806
807/****************************************************************************
808REMARKS:
809Handles opcode 0x0f,0xb2
810****************************************************************************/
811void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
812{
813 int mod, rh, rl;
814 u16 *dstreg;
815 uint srcoffset;
816
817 START_OF_INSTR();
818 DECODE_PRINTF("LSS\t");
819 FETCH_DECODE_MODRM(mod, rh, rl);
820 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200821 dstreg = DECODE_RM_WORD_REGISTER(rh);
822 DECODE_PRINTF(",");
823 srcoffset = decode_rmXX_address(mod, rl);
824 DECODE_PRINTF("\n");
825 TRACE_AND_STEP();
826 *dstreg = fetch_data_word(srcoffset);
827 M.x86.R_SS = fetch_data_word(srcoffset + 2);
828 } else { /* register to register */
829 /* UNDEFINED! */
830 TRACE_AND_STEP();
Jason Jina63ce952007-07-06 08:34:56 +0800831 }
832 DECODE_CLEAR_SEGOVR();
833 END_OF_INSTR();
834}
835
836/****************************************************************************
837REMARKS:
838Handles opcode 0x0f,0xb3
839****************************************************************************/
840void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
841{
842 int mod, rl, rh;
843 uint srcoffset;
844 int bit,disp;
845
846 START_OF_INSTR();
847 DECODE_PRINTF("BTR\t");
848 FETCH_DECODE_MODRM(mod, rh, rl);
849 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200850 srcoffset = decode_rmXX_address(mod, rl);
851 DECODE_PRINTF(",");
852 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
853 u32 srcval,mask;
854 u32 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800855
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200856 shiftreg = DECODE_RM_LONG_REGISTER(rh);
857 TRACE_AND_STEP();
858 bit = *shiftreg & 0x1F;
859 disp = (s16)*shiftreg >> 5;
860 srcval = fetch_data_long(srcoffset+disp);
861 mask = (0x1 << bit);
862 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
863 store_data_long(srcoffset+disp, srcval & ~mask);
864 } else {
865 u16 srcval,mask;
866 u16 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +0800867
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200868 shiftreg = DECODE_RM_WORD_REGISTER(rh);
869 TRACE_AND_STEP();
870 bit = *shiftreg & 0xF;
871 disp = (s16)*shiftreg >> 4;
872 srcval = fetch_data_word(srcoffset+disp);
873 mask = (u16)(0x1 << bit);
874 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
875 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
876 }
877 } else { /* register to register */
878 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
879 u32 *srcreg,*shiftreg;
880 u32 mask;
Jason Jina63ce952007-07-06 08:34:56 +0800881
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200882 srcreg = DECODE_RM_LONG_REGISTER(rl);
883 DECODE_PRINTF(",");
884 shiftreg = DECODE_RM_LONG_REGISTER(rh);
885 TRACE_AND_STEP();
886 bit = *shiftreg & 0x1F;
887 mask = (0x1 << bit);
888 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
889 *srcreg &= ~mask;
890 } else {
891 u16 *srcreg,*shiftreg;
892 u16 mask;
Jason Jina63ce952007-07-06 08:34:56 +0800893
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200894 srcreg = DECODE_RM_WORD_REGISTER(rl);
895 DECODE_PRINTF(",");
896 shiftreg = DECODE_RM_WORD_REGISTER(rh);
897 TRACE_AND_STEP();
898 bit = *shiftreg & 0xF;
899 mask = (u16)(0x1 << bit);
900 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
901 *srcreg &= ~mask;
902 }
Jason Jina63ce952007-07-06 08:34:56 +0800903 }
904 DECODE_CLEAR_SEGOVR();
905 END_OF_INSTR();
906}
907
908/****************************************************************************
909REMARKS:
910Handles opcode 0x0f,0xb4
911****************************************************************************/
912void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
913{
914 int mod, rh, rl;
915 u16 *dstreg;
916 uint srcoffset;
917
918 START_OF_INSTR();
919 DECODE_PRINTF("LFS\t");
920 FETCH_DECODE_MODRM(mod, rh, rl);
921 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200922 dstreg = DECODE_RM_WORD_REGISTER(rh);
923 DECODE_PRINTF(",");
924 srcoffset = decode_rmXX_address(mod, rl);
925 DECODE_PRINTF("\n");
926 TRACE_AND_STEP();
927 *dstreg = fetch_data_word(srcoffset);
928 M.x86.R_FS = fetch_data_word(srcoffset + 2);
929 } else { /* register to register */
930 /* UNDEFINED! */
931 TRACE_AND_STEP();
Jason Jina63ce952007-07-06 08:34:56 +0800932 }
933 DECODE_CLEAR_SEGOVR();
934 END_OF_INSTR();
935}
936
937/****************************************************************************
938REMARKS:
939Handles opcode 0x0f,0xb5
940****************************************************************************/
941void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
942{
943 int mod, rh, rl;
944 u16 *dstreg;
945 uint srcoffset;
946
947 START_OF_INSTR();
948 DECODE_PRINTF("LGS\t");
949 FETCH_DECODE_MODRM(mod, rh, rl);
950 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200951 dstreg = DECODE_RM_WORD_REGISTER(rh);
952 DECODE_PRINTF(",");
953 srcoffset = decode_rmXX_address(mod, rl);
954 DECODE_PRINTF("\n");
955 TRACE_AND_STEP();
956 *dstreg = fetch_data_word(srcoffset);
957 M.x86.R_GS = fetch_data_word(srcoffset + 2);
958 } else { /* register to register */
959 /* UNDEFINED! */
960 TRACE_AND_STEP();
Jason Jina63ce952007-07-06 08:34:56 +0800961 }
962 DECODE_CLEAR_SEGOVR();
963 END_OF_INSTR();
964}
965
966/****************************************************************************
967REMARKS:
968Handles opcode 0x0f,0xb6
969****************************************************************************/
970void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
971{
972 int mod, rl, rh;
973 uint srcoffset;
974
975 START_OF_INSTR();
976 DECODE_PRINTF("MOVZX\t");
977 FETCH_DECODE_MODRM(mod, rh, rl);
978 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200979 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
980 u32 *destreg;
981 u32 srcval;
Jason Jina63ce952007-07-06 08:34:56 +0800982
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200983 destreg = DECODE_RM_LONG_REGISTER(rh);
984 DECODE_PRINTF(",");
985 srcoffset = decode_rmXX_address(mod, rl);
986 srcval = fetch_data_byte(srcoffset);
987 DECODE_PRINTF("\n");
988 TRACE_AND_STEP();
989 *destreg = srcval;
990 } else {
991 u16 *destreg;
992 u16 srcval;
Jason Jina63ce952007-07-06 08:34:56 +0800993
Wolfgang Denk96bb2e02007-08-06 02:17:36 +0200994 destreg = DECODE_RM_WORD_REGISTER(rh);
995 DECODE_PRINTF(",");
996 srcoffset = decode_rmXX_address(mod, rl);
997 srcval = fetch_data_byte(srcoffset);
998 DECODE_PRINTF("\n");
999 TRACE_AND_STEP();
1000 *destreg = srcval;
1001 }
1002 } else { /* register to register */
1003 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1004 u32 *destreg;
1005 u8 *srcreg;
Jason Jina63ce952007-07-06 08:34:56 +08001006
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001007 destreg = DECODE_RM_LONG_REGISTER(rh);
1008 DECODE_PRINTF(",");
1009 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1010 DECODE_PRINTF("\n");
1011 TRACE_AND_STEP();
1012 *destreg = *srcreg;
1013 } else {
1014 u16 *destreg;
1015 u8 *srcreg;
Jason Jina63ce952007-07-06 08:34:56 +08001016
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001017 destreg = DECODE_RM_WORD_REGISTER(rh);
1018 DECODE_PRINTF(",");
1019 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1020 DECODE_PRINTF("\n");
1021 TRACE_AND_STEP();
1022 *destreg = *srcreg;
1023 }
Jason Jina63ce952007-07-06 08:34:56 +08001024 }
1025 DECODE_CLEAR_SEGOVR();
1026 END_OF_INSTR();
1027}
1028
1029/****************************************************************************
1030REMARKS:
1031Handles opcode 0x0f,0xb7
1032****************************************************************************/
1033void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1034{
1035 int mod, rl, rh;
1036 uint srcoffset;
1037 u32 *destreg;
1038 u32 srcval;
1039 u16 *srcreg;
1040
1041 START_OF_INSTR();
1042 DECODE_PRINTF("MOVZX\t");
1043 FETCH_DECODE_MODRM(mod, rh, rl);
1044 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001045 destreg = DECODE_RM_LONG_REGISTER(rh);
1046 DECODE_PRINTF(",");
1047 srcoffset = decode_rmXX_address(mod, rl);
1048 srcval = fetch_data_word(srcoffset);
1049 DECODE_PRINTF("\n");
1050 TRACE_AND_STEP();
1051 *destreg = srcval;
1052 } else { /* register to register */
1053 destreg = DECODE_RM_LONG_REGISTER(rh);
1054 DECODE_PRINTF(",");
1055 srcreg = DECODE_RM_WORD_REGISTER(rl);
1056 DECODE_PRINTF("\n");
1057 TRACE_AND_STEP();
1058 *destreg = *srcreg;
Jason Jina63ce952007-07-06 08:34:56 +08001059 }
1060 DECODE_CLEAR_SEGOVR();
1061 END_OF_INSTR();
1062}
1063
1064/****************************************************************************
1065REMARKS:
1066Handles opcode 0x0f,0xba
1067****************************************************************************/
1068void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1069{
1070 int mod, rl, rh;
1071 uint srcoffset;
1072 u8 shift;
1073 int bit;
1074
1075 START_OF_INSTR();
1076 FETCH_DECODE_MODRM(mod, rh, rl);
1077 switch (rh) {
1078 case 4:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001079 DECODE_PRINTF("BT\t");
1080 break;
Jason Jina63ce952007-07-06 08:34:56 +08001081 case 5:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001082 DECODE_PRINTF("BTS\t");
1083 break;
Jason Jina63ce952007-07-06 08:34:56 +08001084 case 6:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001085 DECODE_PRINTF("BTR\t");
1086 break;
Jason Jina63ce952007-07-06 08:34:56 +08001087 case 7:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001088 DECODE_PRINTF("BTC\t");
1089 break;
Jason Jina63ce952007-07-06 08:34:56 +08001090 default:
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001091 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1092 TRACE_REGS();
1093 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1094 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1095 HALT_SYS();
Jason Jina63ce952007-07-06 08:34:56 +08001096 }
1097 if (mod < 3) {
1098
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001099 srcoffset = decode_rmXX_address(mod, rl);
1100 shift = fetch_byte_imm();
1101 DECODE_PRINTF2(",%d\n", shift);
1102 TRACE_AND_STEP();
Jason Jina63ce952007-07-06 08:34:56 +08001103
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001104 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1105 u32 srcval, mask;
Jason Jina63ce952007-07-06 08:34:56 +08001106
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001107 bit = shift & 0x1F;
1108 srcval = fetch_data_long(srcoffset);
1109 mask = (0x1 << bit);
1110 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1111 switch (rh) {
1112 case 5:
1113 store_data_long(srcoffset, srcval | mask);
1114 break;
1115 case 6:
1116 store_data_long(srcoffset, srcval & ~mask);
1117 break;
1118 case 7:
1119 store_data_long(srcoffset, srcval ^ mask);
1120 break;
1121 default:
1122 break;
1123 }
1124 } else {
1125 u16 srcval, mask;
Jason Jina63ce952007-07-06 08:34:56 +08001126
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001127 bit = shift & 0xF;
1128 srcval = fetch_data_word(srcoffset);
1129 mask = (0x1 << bit);
1130 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1131 switch (rh) {
1132 case 5:
1133 store_data_word(srcoffset, srcval | mask);
1134 break;
1135 case 6:
1136 store_data_word(srcoffset, srcval & ~mask);
1137 break;
1138 case 7:
1139 store_data_word(srcoffset, srcval ^ mask);
1140 break;
1141 default:
1142 break;
1143 }
1144 }
1145 } else { /* register to register */
1146 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1147 u32 *srcreg;
1148 u32 mask;
Jason Jina63ce952007-07-06 08:34:56 +08001149
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001150 srcreg = DECODE_RM_LONG_REGISTER(rl);
1151 shift = fetch_byte_imm();
1152 DECODE_PRINTF2(",%d\n", shift);
1153 TRACE_AND_STEP();
1154 bit = shift & 0x1F;
1155 mask = (0x1 << bit);
1156 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1157 switch (rh) {
1158 case 5:
1159 *srcreg |= mask;
1160 break;
1161 case 6:
1162 *srcreg &= ~mask;
1163 break;
1164 case 7:
1165 *srcreg ^= mask;
1166 break;
1167 default:
1168 break;
1169 }
1170 } else {
1171 u16 *srcreg;
1172 u16 mask;
Jason Jina63ce952007-07-06 08:34:56 +08001173
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001174 srcreg = DECODE_RM_WORD_REGISTER(rl);
1175 shift = fetch_byte_imm();
1176 DECODE_PRINTF2(",%d\n", shift);
1177 TRACE_AND_STEP();
1178 bit = shift & 0xF;
1179 mask = (0x1 << bit);
1180 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1181 switch (rh) {
1182 case 5:
1183 *srcreg |= mask;
1184 break;
1185 case 6:
1186 *srcreg &= ~mask;
1187 break;
1188 case 7:
1189 *srcreg ^= mask;
1190 break;
1191 default:
1192 break;
1193 }
1194 }
Jason Jina63ce952007-07-06 08:34:56 +08001195 }
1196 DECODE_CLEAR_SEGOVR();
1197 END_OF_INSTR();
1198}
1199
1200/****************************************************************************
1201REMARKS:
1202Handles opcode 0x0f,0xbb
1203****************************************************************************/
1204void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
1205{
1206 int mod, rl, rh;
1207 uint srcoffset;
1208 int bit,disp;
1209
1210 START_OF_INSTR();
1211 DECODE_PRINTF("BTC\t");
1212 FETCH_DECODE_MODRM(mod, rh, rl);
1213 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001214 srcoffset = decode_rmXX_address(mod, rl);
1215 DECODE_PRINTF(",");
1216 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1217 u32 srcval,mask;
1218 u32 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +08001219
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001220 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1221 TRACE_AND_STEP();
1222 bit = *shiftreg & 0x1F;
1223 disp = (s16)*shiftreg >> 5;
1224 srcval = fetch_data_long(srcoffset+disp);
1225 mask = (0x1 << bit);
1226 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1227 store_data_long(srcoffset+disp, srcval ^ mask);
1228 } else {
1229 u16 srcval,mask;
1230 u16 *shiftreg;
Jason Jina63ce952007-07-06 08:34:56 +08001231
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001232 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1233 TRACE_AND_STEP();
1234 bit = *shiftreg & 0xF;
1235 disp = (s16)*shiftreg >> 4;
1236 srcval = fetch_data_word(srcoffset+disp);
1237 mask = (u16)(0x1 << bit);
1238 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1239 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
1240 }
1241 } else { /* register to register */
1242 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1243 u32 *srcreg,*shiftreg;
1244 u32 mask;
Jason Jina63ce952007-07-06 08:34:56 +08001245
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001246 srcreg = DECODE_RM_LONG_REGISTER(rl);
1247 DECODE_PRINTF(",");
1248 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1249 TRACE_AND_STEP();
1250 bit = *shiftreg & 0x1F;
1251 mask = (0x1 << bit);
1252 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1253 *srcreg ^= mask;
1254 } else {
1255 u16 *srcreg,*shiftreg;
1256 u16 mask;
Jason Jina63ce952007-07-06 08:34:56 +08001257
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001258 srcreg = DECODE_RM_WORD_REGISTER(rl);
1259 DECODE_PRINTF(",");
1260 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1261 TRACE_AND_STEP();
1262 bit = *shiftreg & 0xF;
1263 mask = (u16)(0x1 << bit);
1264 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1265 *srcreg ^= mask;
1266 }
Jason Jina63ce952007-07-06 08:34:56 +08001267 }
1268 DECODE_CLEAR_SEGOVR();
1269 END_OF_INSTR();
1270}
1271
1272/****************************************************************************
1273REMARKS:
1274Handles opcode 0x0f,0xbc
1275****************************************************************************/
1276void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
1277{
1278 int mod, rl, rh;
1279 uint srcoffset;
1280
1281 START_OF_INSTR();
1282 DECODE_PRINTF("BSF\n");
1283 FETCH_DECODE_MODRM(mod, rh, rl);
1284 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001285 srcoffset = decode_rmXX_address(mod, rl);
1286 DECODE_PRINTF(",");
1287 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1288 u32 srcval, *dstreg;
Jason Jina63ce952007-07-06 08:34:56 +08001289
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001290 dstreg = DECODE_RM_LONG_REGISTER(rh);
1291 TRACE_AND_STEP();
1292 srcval = fetch_data_long(srcoffset);
1293 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1294 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1295 if ((srcval >> *dstreg) & 1) break;
1296 } else {
1297 u16 srcval, *dstreg;
Jason Jina63ce952007-07-06 08:34:56 +08001298
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001299 dstreg = DECODE_RM_WORD_REGISTER(rh);
1300 TRACE_AND_STEP();
1301 srcval = fetch_data_word(srcoffset);
1302 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1303 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1304 if ((srcval >> *dstreg) & 1) break;
1305 }
1306 } else { /* register to register */
1307 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1308 u32 *srcreg, *dstreg;
Jason Jina63ce952007-07-06 08:34:56 +08001309
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001310 srcreg = DECODE_RM_LONG_REGISTER(rl);
1311 DECODE_PRINTF(",");
1312 dstreg = DECODE_RM_LONG_REGISTER(rh);
1313 TRACE_AND_STEP();
1314 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1315 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1316 if ((*srcreg >> *dstreg) & 1) break;
1317 } else {
1318 u16 *srcreg, *dstreg;
Jason Jina63ce952007-07-06 08:34:56 +08001319
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001320 srcreg = DECODE_RM_WORD_REGISTER(rl);
1321 DECODE_PRINTF(",");
1322 dstreg = DECODE_RM_WORD_REGISTER(rh);
1323 TRACE_AND_STEP();
1324 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1325 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1326 if ((*srcreg >> *dstreg) & 1) break;
1327 }
Jason Jina63ce952007-07-06 08:34:56 +08001328 }
1329 DECODE_CLEAR_SEGOVR();
1330 END_OF_INSTR();
1331}
1332
1333/****************************************************************************
1334REMARKS:
1335Handles opcode 0x0f,0xbd
1336****************************************************************************/
1337void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
1338{
1339 int mod, rl, rh;
1340 uint srcoffset;
1341
1342 START_OF_INSTR();
1343 DECODE_PRINTF("BSF\n");
1344 FETCH_DECODE_MODRM(mod, rh, rl);
1345 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001346 srcoffset = decode_rmXX_address(mod, rl);
1347 DECODE_PRINTF(",");
1348 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1349 u32 srcval, *dstreg;
Jason Jina63ce952007-07-06 08:34:56 +08001350
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001351 dstreg = DECODE_RM_LONG_REGISTER(rh);
1352 TRACE_AND_STEP();
1353 srcval = fetch_data_long(srcoffset);
1354 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1355 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1356 if ((srcval >> *dstreg) & 1) break;
1357 } else {
1358 u16 srcval, *dstreg;
Jason Jina63ce952007-07-06 08:34:56 +08001359
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001360 dstreg = DECODE_RM_WORD_REGISTER(rh);
1361 TRACE_AND_STEP();
1362 srcval = fetch_data_word(srcoffset);
1363 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1364 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1365 if ((srcval >> *dstreg) & 1) break;
1366 }
1367 } else { /* register to register */
1368 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1369 u32 *srcreg, *dstreg;
Jason Jina63ce952007-07-06 08:34:56 +08001370
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001371 srcreg = DECODE_RM_LONG_REGISTER(rl);
1372 DECODE_PRINTF(",");
1373 dstreg = DECODE_RM_LONG_REGISTER(rh);
1374 TRACE_AND_STEP();
1375 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1376 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1377 if ((*srcreg >> *dstreg) & 1) break;
1378 } else {
1379 u16 *srcreg, *dstreg;
Jason Jina63ce952007-07-06 08:34:56 +08001380
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001381 srcreg = DECODE_RM_WORD_REGISTER(rl);
1382 DECODE_PRINTF(",");
1383 dstreg = DECODE_RM_WORD_REGISTER(rh);
1384 TRACE_AND_STEP();
1385 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1386 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1387 if ((*srcreg >> *dstreg) & 1) break;
1388 }
Jason Jina63ce952007-07-06 08:34:56 +08001389 }
1390 DECODE_CLEAR_SEGOVR();
1391 END_OF_INSTR();
1392}
1393
1394/****************************************************************************
1395REMARKS:
1396Handles opcode 0x0f,0xbe
1397****************************************************************************/
1398void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1399{
1400 int mod, rl, rh;
1401 uint srcoffset;
1402
1403 START_OF_INSTR();
1404 DECODE_PRINTF("MOVSX\t");
1405 FETCH_DECODE_MODRM(mod, rh, rl);
1406 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001407 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1408 u32 *destreg;
1409 u32 srcval;
Jason Jina63ce952007-07-06 08:34:56 +08001410
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001411 destreg = DECODE_RM_LONG_REGISTER(rh);
1412 DECODE_PRINTF(",");
1413 srcoffset = decode_rmXX_address(mod, rl);
1414 srcval = (s32)((s8)fetch_data_byte(srcoffset));
1415 DECODE_PRINTF("\n");
1416 TRACE_AND_STEP();
1417 *destreg = srcval;
1418 } else {
1419 u16 *destreg;
1420 u16 srcval;
Jason Jina63ce952007-07-06 08:34:56 +08001421
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001422 destreg = DECODE_RM_WORD_REGISTER(rh);
1423 DECODE_PRINTF(",");
1424 srcoffset = decode_rmXX_address(mod, rl);
1425 srcval = (s16)((s8)fetch_data_byte(srcoffset));
1426 DECODE_PRINTF("\n");
1427 TRACE_AND_STEP();
1428 *destreg = srcval;
1429 }
1430 } else { /* register to register */
1431 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1432 u32 *destreg;
1433 u8 *srcreg;
Jason Jina63ce952007-07-06 08:34:56 +08001434
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001435 destreg = DECODE_RM_LONG_REGISTER(rh);
1436 DECODE_PRINTF(",");
1437 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1438 DECODE_PRINTF("\n");
1439 TRACE_AND_STEP();
1440 *destreg = (s32)((s8)*srcreg);
1441 } else {
1442 u16 *destreg;
1443 u8 *srcreg;
Jason Jina63ce952007-07-06 08:34:56 +08001444
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001445 destreg = DECODE_RM_WORD_REGISTER(rh);
1446 DECODE_PRINTF(",");
1447 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1448 DECODE_PRINTF("\n");
1449 TRACE_AND_STEP();
1450 *destreg = (s16)((s8)*srcreg);
1451 }
Jason Jina63ce952007-07-06 08:34:56 +08001452 }
1453 DECODE_CLEAR_SEGOVR();
1454 END_OF_INSTR();
1455}
1456
1457/****************************************************************************
1458REMARKS:
1459Handles opcode 0x0f,0xbf
1460****************************************************************************/
1461void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
1462{
1463 int mod, rl, rh;
1464 uint srcoffset;
1465 u32 *destreg;
1466 u32 srcval;
1467 u16 *srcreg;
1468
1469 START_OF_INSTR();
1470 DECODE_PRINTF("MOVSX\t");
1471 FETCH_DECODE_MODRM(mod, rh, rl);
1472 if (mod < 3) {
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001473 destreg = DECODE_RM_LONG_REGISTER(rh);
1474 DECODE_PRINTF(",");
1475 srcoffset = decode_rmXX_address(mod, rl);
1476 srcval = (s32)((s16)fetch_data_word(srcoffset));
1477 DECODE_PRINTF("\n");
1478 TRACE_AND_STEP();
1479 *destreg = srcval;
1480 } else { /* register to register */
1481 destreg = DECODE_RM_LONG_REGISTER(rh);
1482 DECODE_PRINTF(",");
1483 srcreg = DECODE_RM_WORD_REGISTER(rl);
1484 DECODE_PRINTF("\n");
1485 TRACE_AND_STEP();
1486 *destreg = (s32)((s16)*srcreg);
Jason Jina63ce952007-07-06 08:34:56 +08001487 }
1488 DECODE_CLEAR_SEGOVR();
1489 END_OF_INSTR();
1490}
1491
1492/***************************************************************************
1493 * Double byte operation code table:
1494 **************************************************************************/
Ed Swarthout1cffcde2008-10-09 01:27:18 -05001495void (*x86emu_optab2[256])(u8) =
Jason Jina63ce952007-07-06 08:34:56 +08001496{
1497/* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
1498/* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001499/* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
1500/* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
Jason Jina63ce952007-07-06 08:34:56 +08001501/* 0x04 */ x86emuOp2_illegal_op,
1502/* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001503/* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
Jason Jina63ce952007-07-06 08:34:56 +08001504/* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
Wolfgang Denk96bb2e02007-08-06 02:17:36 +02001505/* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */
Jason Jina63ce952007-07-06 08:34:56 +08001506/* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */
1507/* 0x0a */ x86emuOp2_illegal_op,
1508/* 0x0b */ x86emuOp2_illegal_op,
1509/* 0x0c */ x86emuOp2_illegal_op,
1510/* 0x0d */ x86emuOp2_illegal_op,
1511/* 0x0e */ x86emuOp2_illegal_op,
1512/* 0x0f */ x86emuOp2_illegal_op,
1513
1514/* 0x10 */ x86emuOp2_illegal_op,
1515/* 0x11 */ x86emuOp2_illegal_op,
1516/* 0x12 */ x86emuOp2_illegal_op,
1517/* 0x13 */ x86emuOp2_illegal_op,
1518/* 0x14 */ x86emuOp2_illegal_op,
1519/* 0x15 */ x86emuOp2_illegal_op,
1520/* 0x16 */ x86emuOp2_illegal_op,
1521/* 0x17 */ x86emuOp2_illegal_op,
1522/* 0x18 */ x86emuOp2_illegal_op,
1523/* 0x19 */ x86emuOp2_illegal_op,
1524/* 0x1a */ x86emuOp2_illegal_op,
1525/* 0x1b */ x86emuOp2_illegal_op,
1526/* 0x1c */ x86emuOp2_illegal_op,
1527/* 0x1d */ x86emuOp2_illegal_op,
1528/* 0x1e */ x86emuOp2_illegal_op,
1529/* 0x1f */ x86emuOp2_illegal_op,
1530
1531/* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
1532/* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
1533/* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
1534/* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
1535/* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
1536/* 0x25 */ x86emuOp2_illegal_op,
1537/* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
1538/* 0x27 */ x86emuOp2_illegal_op,
1539/* 0x28 */ x86emuOp2_illegal_op,
1540/* 0x29 */ x86emuOp2_illegal_op,
1541/* 0x2a */ x86emuOp2_illegal_op,
1542/* 0x2b */ x86emuOp2_illegal_op,
1543/* 0x2c */ x86emuOp2_illegal_op,
1544/* 0x2d */ x86emuOp2_illegal_op,
1545/* 0x2e */ x86emuOp2_illegal_op,
1546/* 0x2f */ x86emuOp2_illegal_op,
1547
1548/* 0x30 */ x86emuOp2_illegal_op,
1549/* 0x31 */ x86emuOp2_illegal_op,
1550/* 0x32 */ x86emuOp2_illegal_op,
1551/* 0x33 */ x86emuOp2_illegal_op,
1552/* 0x34 */ x86emuOp2_illegal_op,
1553/* 0x35 */ x86emuOp2_illegal_op,
1554/* 0x36 */ x86emuOp2_illegal_op,
1555/* 0x37 */ x86emuOp2_illegal_op,
1556/* 0x38 */ x86emuOp2_illegal_op,
1557/* 0x39 */ x86emuOp2_illegal_op,
1558/* 0x3a */ x86emuOp2_illegal_op,
1559/* 0x3b */ x86emuOp2_illegal_op,
1560/* 0x3c */ x86emuOp2_illegal_op,
1561/* 0x3d */ x86emuOp2_illegal_op,
1562/* 0x3e */ x86emuOp2_illegal_op,
1563/* 0x3f */ x86emuOp2_illegal_op,
1564
1565/* 0x40 */ x86emuOp2_illegal_op,
1566/* 0x41 */ x86emuOp2_illegal_op,
1567/* 0x42 */ x86emuOp2_illegal_op,
1568/* 0x43 */ x86emuOp2_illegal_op,
1569/* 0x44 */ x86emuOp2_illegal_op,
1570/* 0x45 */ x86emuOp2_illegal_op,
1571/* 0x46 */ x86emuOp2_illegal_op,
1572/* 0x47 */ x86emuOp2_illegal_op,
1573/* 0x48 */ x86emuOp2_illegal_op,
1574/* 0x49 */ x86emuOp2_illegal_op,
1575/* 0x4a */ x86emuOp2_illegal_op,
1576/* 0x4b */ x86emuOp2_illegal_op,
1577/* 0x4c */ x86emuOp2_illegal_op,
1578/* 0x4d */ x86emuOp2_illegal_op,
1579/* 0x4e */ x86emuOp2_illegal_op,
1580/* 0x4f */ x86emuOp2_illegal_op,
1581
1582/* 0x50 */ x86emuOp2_illegal_op,
1583/* 0x51 */ x86emuOp2_illegal_op,
1584/* 0x52 */ x86emuOp2_illegal_op,
1585/* 0x53 */ x86emuOp2_illegal_op,
1586/* 0x54 */ x86emuOp2_illegal_op,
1587/* 0x55 */ x86emuOp2_illegal_op,
1588/* 0x56 */ x86emuOp2_illegal_op,
1589/* 0x57 */ x86emuOp2_illegal_op,
1590/* 0x58 */ x86emuOp2_illegal_op,
1591/* 0x59 */ x86emuOp2_illegal_op,
1592/* 0x5a */ x86emuOp2_illegal_op,
1593/* 0x5b */ x86emuOp2_illegal_op,
1594/* 0x5c */ x86emuOp2_illegal_op,
1595/* 0x5d */ x86emuOp2_illegal_op,
1596/* 0x5e */ x86emuOp2_illegal_op,
1597/* 0x5f */ x86emuOp2_illegal_op,
1598
1599/* 0x60 */ x86emuOp2_illegal_op,
1600/* 0x61 */ x86emuOp2_illegal_op,
1601/* 0x62 */ x86emuOp2_illegal_op,
1602/* 0x63 */ x86emuOp2_illegal_op,
1603/* 0x64 */ x86emuOp2_illegal_op,
1604/* 0x65 */ x86emuOp2_illegal_op,
1605/* 0x66 */ x86emuOp2_illegal_op,
1606/* 0x67 */ x86emuOp2_illegal_op,
1607/* 0x68 */ x86emuOp2_illegal_op,
1608/* 0x69 */ x86emuOp2_illegal_op,
1609/* 0x6a */ x86emuOp2_illegal_op,
1610/* 0x6b */ x86emuOp2_illegal_op,
1611/* 0x6c */ x86emuOp2_illegal_op,
1612/* 0x6d */ x86emuOp2_illegal_op,
1613/* 0x6e */ x86emuOp2_illegal_op,
1614/* 0x6f */ x86emuOp2_illegal_op,
1615
1616/* 0x70 */ x86emuOp2_illegal_op,
1617/* 0x71 */ x86emuOp2_illegal_op,
1618/* 0x72 */ x86emuOp2_illegal_op,
1619/* 0x73 */ x86emuOp2_illegal_op,
1620/* 0x74 */ x86emuOp2_illegal_op,
1621/* 0x75 */ x86emuOp2_illegal_op,
1622/* 0x76 */ x86emuOp2_illegal_op,
1623/* 0x77 */ x86emuOp2_illegal_op,
1624/* 0x78 */ x86emuOp2_illegal_op,
1625/* 0x79 */ x86emuOp2_illegal_op,
1626/* 0x7a */ x86emuOp2_illegal_op,
1627/* 0x7b */ x86emuOp2_illegal_op,
1628/* 0x7c */ x86emuOp2_illegal_op,
1629/* 0x7d */ x86emuOp2_illegal_op,
1630/* 0x7e */ x86emuOp2_illegal_op,
1631/* 0x7f */ x86emuOp2_illegal_op,
1632
1633/* 0x80 */ x86emuOp2_long_jump,
1634/* 0x81 */ x86emuOp2_long_jump,
1635/* 0x82 */ x86emuOp2_long_jump,
1636/* 0x83 */ x86emuOp2_long_jump,
1637/* 0x84 */ x86emuOp2_long_jump,
1638/* 0x85 */ x86emuOp2_long_jump,
1639/* 0x86 */ x86emuOp2_long_jump,
1640/* 0x87 */ x86emuOp2_long_jump,
1641/* 0x88 */ x86emuOp2_long_jump,
1642/* 0x89 */ x86emuOp2_long_jump,
1643/* 0x8a */ x86emuOp2_long_jump,
1644/* 0x8b */ x86emuOp2_long_jump,
1645/* 0x8c */ x86emuOp2_long_jump,
1646/* 0x8d */ x86emuOp2_long_jump,
1647/* 0x8e */ x86emuOp2_long_jump,
1648/* 0x8f */ x86emuOp2_long_jump,
1649
1650/* 0x90 */ x86emuOp2_set_byte,
1651/* 0x91 */ x86emuOp2_set_byte,
1652/* 0x92 */ x86emuOp2_set_byte,
1653/* 0x93 */ x86emuOp2_set_byte,
1654/* 0x94 */ x86emuOp2_set_byte,
1655/* 0x95 */ x86emuOp2_set_byte,
1656/* 0x96 */ x86emuOp2_set_byte,
1657/* 0x97 */ x86emuOp2_set_byte,
1658/* 0x98 */ x86emuOp2_set_byte,
1659/* 0x99 */ x86emuOp2_set_byte,
1660/* 0x9a */ x86emuOp2_set_byte,
1661/* 0x9b */ x86emuOp2_set_byte,
1662/* 0x9c */ x86emuOp2_set_byte,
1663/* 0x9d */ x86emuOp2_set_byte,
1664/* 0x9e */ x86emuOp2_set_byte,
1665/* 0x9f */ x86emuOp2_set_byte,
1666
1667/* 0xa0 */ x86emuOp2_push_FS,
1668/* 0xa1 */ x86emuOp2_pop_FS,
1669/* 0xa2 */ x86emuOp2_illegal_op,
1670/* 0xa3 */ x86emuOp2_bt_R,
1671/* 0xa4 */ x86emuOp2_shld_IMM,
1672/* 0xa5 */ x86emuOp2_shld_CL,
1673/* 0xa6 */ x86emuOp2_illegal_op,
1674/* 0xa7 */ x86emuOp2_illegal_op,
1675/* 0xa8 */ x86emuOp2_push_GS,
1676/* 0xa9 */ x86emuOp2_pop_GS,
1677/* 0xaa */ x86emuOp2_illegal_op,
1678/* 0xab */ x86emuOp2_bt_R,
1679/* 0xac */ x86emuOp2_shrd_IMM,
1680/* 0xad */ x86emuOp2_shrd_CL,
1681/* 0xae */ x86emuOp2_illegal_op,
1682/* 0xaf */ x86emuOp2_imul_R_RM,
1683
1684/* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1685/* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1686/* 0xb2 */ x86emuOp2_lss_R_IMM,
1687/* 0xb3 */ x86emuOp2_btr_R,
1688/* 0xb4 */ x86emuOp2_lfs_R_IMM,
1689/* 0xb5 */ x86emuOp2_lgs_R_IMM,
1690/* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
1691/* 0xb7 */ x86emuOp2_movzx_word_R_RM,
1692/* 0xb8 */ x86emuOp2_illegal_op,
1693/* 0xb9 */ x86emuOp2_illegal_op,
1694/* 0xba */ x86emuOp2_btX_I,
1695/* 0xbb */ x86emuOp2_btc_R,
1696/* 0xbc */ x86emuOp2_bsf,
1697/* 0xbd */ x86emuOp2_bsr,
1698/* 0xbe */ x86emuOp2_movsx_byte_R_RM,
1699/* 0xbf */ x86emuOp2_movsx_word_R_RM,
1700
1701/* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
1702/* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
1703/* 0xc2 */ x86emuOp2_illegal_op,
1704/* 0xc3 */ x86emuOp2_illegal_op,
1705/* 0xc4 */ x86emuOp2_illegal_op,
1706/* 0xc5 */ x86emuOp2_illegal_op,
1707/* 0xc6 */ x86emuOp2_illegal_op,
1708/* 0xc7 */ x86emuOp2_illegal_op,
1709/* 0xc8 */ x86emuOp2_illegal_op, /* TODO: bswap */
1710/* 0xc9 */ x86emuOp2_illegal_op, /* TODO: bswap */
1711/* 0xca */ x86emuOp2_illegal_op, /* TODO: bswap */
1712/* 0xcb */ x86emuOp2_illegal_op, /* TODO: bswap */
1713/* 0xcc */ x86emuOp2_illegal_op, /* TODO: bswap */
1714/* 0xcd */ x86emuOp2_illegal_op, /* TODO: bswap */
1715/* 0xce */ x86emuOp2_illegal_op, /* TODO: bswap */
1716/* 0xcf */ x86emuOp2_illegal_op, /* TODO: bswap */
1717
1718/* 0xd0 */ x86emuOp2_illegal_op,
1719/* 0xd1 */ x86emuOp2_illegal_op,
1720/* 0xd2 */ x86emuOp2_illegal_op,
1721/* 0xd3 */ x86emuOp2_illegal_op,
1722/* 0xd4 */ x86emuOp2_illegal_op,
1723/* 0xd5 */ x86emuOp2_illegal_op,
1724/* 0xd6 */ x86emuOp2_illegal_op,
1725/* 0xd7 */ x86emuOp2_illegal_op,
1726/* 0xd8 */ x86emuOp2_illegal_op,
1727/* 0xd9 */ x86emuOp2_illegal_op,
1728/* 0xda */ x86emuOp2_illegal_op,
1729/* 0xdb */ x86emuOp2_illegal_op,
1730/* 0xdc */ x86emuOp2_illegal_op,
1731/* 0xdd */ x86emuOp2_illegal_op,
1732/* 0xde */ x86emuOp2_illegal_op,
1733/* 0xdf */ x86emuOp2_illegal_op,
1734
1735/* 0xe0 */ x86emuOp2_illegal_op,
1736/* 0xe1 */ x86emuOp2_illegal_op,
1737/* 0xe2 */ x86emuOp2_illegal_op,
1738/* 0xe3 */ x86emuOp2_illegal_op,
1739/* 0xe4 */ x86emuOp2_illegal_op,
1740/* 0xe5 */ x86emuOp2_illegal_op,
1741/* 0xe6 */ x86emuOp2_illegal_op,
1742/* 0xe7 */ x86emuOp2_illegal_op,
1743/* 0xe8 */ x86emuOp2_illegal_op,
1744/* 0xe9 */ x86emuOp2_illegal_op,
1745/* 0xea */ x86emuOp2_illegal_op,
1746/* 0xeb */ x86emuOp2_illegal_op,
1747/* 0xec */ x86emuOp2_illegal_op,
1748/* 0xed */ x86emuOp2_illegal_op,
1749/* 0xee */ x86emuOp2_illegal_op,
1750/* 0xef */ x86emuOp2_illegal_op,
1751
1752/* 0xf0 */ x86emuOp2_illegal_op,
1753/* 0xf1 */ x86emuOp2_illegal_op,
1754/* 0xf2 */ x86emuOp2_illegal_op,
1755/* 0xf3 */ x86emuOp2_illegal_op,
1756/* 0xf4 */ x86emuOp2_illegal_op,
1757/* 0xf5 */ x86emuOp2_illegal_op,
1758/* 0xf6 */ x86emuOp2_illegal_op,
1759/* 0xf7 */ x86emuOp2_illegal_op,
1760/* 0xf8 */ x86emuOp2_illegal_op,
1761/* 0xf9 */ x86emuOp2_illegal_op,
1762/* 0xfa */ x86emuOp2_illegal_op,
1763/* 0xfb */ x86emuOp2_illegal_op,
1764/* 0xfc */ x86emuOp2_illegal_op,
1765/* 0xfd */ x86emuOp2_illegal_op,
1766/* 0xfe */ x86emuOp2_illegal_op,
1767/* 0xff */ x86emuOp2_illegal_op,
1768};