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