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