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