Xeon-SP boards: Factor out OCP VPD `get_cxl_mode()` impl
[coreboot2.git] / src / device / oprom / x86emu / ops2.c
blob6089b1f53b167663b77ba9cda58784e8a3eb0303
1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1991-2004 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation, and that the name of the authors not be used
16 * in advertising or publicity pertaining to distribution of the software
17 * without specific, written prior permission. The authors makes no
18 * representations about the suitability of this software for any purpose.
19 * It is provided "as is" without express or implied warranty.
21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 * PERFORMANCE OF THIS SOFTWARE.
29 * ========================================================================
31 * Language: ANSI C
32 * Environment: Any
33 * Developer: Kendall Bennett
35 * Description: This file includes subroutines to implement the decoding
36 * and emulation of all the x86 extended two-byte processor
37 * instructions.
39 ****************************************************************************/
41 #include "x86emui.h"
43 /*----------------------------- Implementation ----------------------------*/
45 /****************************************************************************
46 PARAMETERS:
47 op1 - Instruction op code
49 REMARKS:
50 Handles illegal opcodes.
51 ****************************************************************************/
52 static void x86emuOp2_illegal_op(u8 op2)
54 START_OF_INSTR();
55 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
56 TRACE_REGS();
57 printf("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
58 M.x86.R_CS, M.x86.R_IP-2, op2);
59 HALT_SYS();
60 END_OF_INSTR();
63 /****************************************************************************
64 * REMARKS:
65 * Handles opcode 0x0f,0x01
66 * ****************************************************************************/
68 static void x86emuOp2_opc_01(u8 op2)
70 int mod, rl, rh;
71 u16 *destreg;
72 uint destoffset;
74 START_OF_INSTR();
75 FETCH_DECODE_MODRM(mod, rh, rl);
77 switch(rh) {
78 case 4: // SMSW (Store Machine Status Word)
79 // Decode the mod byte to find the addressing
80 // Dummy implementation: Always returns 0x10 (initial value as per intel manual volume 3, figure 8-1)
81 #define SMSW_INITIAL_VALUE 0x10
82 DECODE_PRINTF("SMSW\t");
83 switch (mod) {
84 case 0:
85 destoffset = decode_rm00_address(rl);
86 store_data_word(destoffset, SMSW_INITIAL_VALUE);
87 break;
88 case 1:
89 destoffset = decode_rm01_address(rl);
90 store_data_word(destoffset, SMSW_INITIAL_VALUE);
91 break;
92 case 2:
93 destoffset = decode_rm10_address(rl);
94 store_data_word(destoffset, SMSW_INITIAL_VALUE);
95 break;
96 case 3:
97 destreg = DECODE_RM_WORD_REGISTER(rl);
98 *destreg = SMSW_INITIAL_VALUE;
99 break;
101 TRACE_AND_STEP();
102 DECODE_CLEAR_SEGOVR();
103 DECODE_PRINTF("\n");
104 break;
105 default:
106 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE IN 0F 01\n");
107 TRACE_REGS();
108 printf("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
109 M.x86.R_CS, M.x86.R_IP-2, op2);
110 HALT_SYS();
111 break;
114 END_OF_INSTR();
117 /****************************************************************************
118 * REMARKS:
119 * Handles opcode 0x0f,0x08
120 * ****************************************************************************/
121 static void x86emuOp2_invd(u8 op2)
123 START_OF_INSTR();
124 DECODE_PRINTF("INVD\n");
125 TRACE_AND_STEP();
126 DECODE_CLEAR_SEGOVR();
127 END_OF_INSTR();
130 /****************************************************************************
131 * REMARKS:
132 * Handles opcode 0x0f,0x09
133 * ****************************************************************************/
134 static void x86emuOp2_wbinvd(u8 op2)
136 START_OF_INSTR();
137 DECODE_PRINTF("WBINVD\n");
138 TRACE_AND_STEP();
139 DECODE_CLEAR_SEGOVR();
140 END_OF_INSTR();
143 /****************************************************************************
144 * REMARKS:
145 * Handles opcode 0x0f,0x30
146 * ****************************************************************************/
147 static void x86emuOp2_wrmsr(u8 op2)
149 /* dummy implementation, does nothing */
151 START_OF_INSTR();
152 DECODE_PRINTF("WRMSR\n");
153 TRACE_AND_STEP();
154 DECODE_CLEAR_SEGOVR();
155 END_OF_INSTR();
158 /****************************************************************************
159 REMARKS:
160 Handles opcode 0x0f,0x31
161 ****************************************************************************/
162 static void x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
164 #ifdef __HAS_LONG_LONG__
165 static u64 counter = 0;
166 #else
167 static u32 counter = 0;
168 #endif
170 counter += 0x10000;
172 /* read timestamp counter */
174 * Note that instead of actually trying to accurately measure this, we just
175 * increase the counter by a fixed amount every time we hit one of these
176 * instructions. Feel free to come up with a better method.
178 START_OF_INSTR();
179 DECODE_PRINTF("RDTSC\n");
180 TRACE_AND_STEP();
181 #ifdef __HAS_LONG_LONG__
182 M.x86.R_EAX = counter & 0xffffffff;
183 M.x86.R_EDX = counter >> 32;
184 #else
185 M.x86.R_EAX = counter;
186 M.x86.R_EDX = 0;
187 #endif
188 DECODE_CLEAR_SEGOVR();
189 END_OF_INSTR();
192 /****************************************************************************
193 * REMARKS:
194 * Handles opcode 0x0f,0x32
195 * ****************************************************************************/
196 static void x86emuOp2_rdmsr(u8 op2)
198 /* dummy implementation, always return 0 */
200 START_OF_INSTR();
201 DECODE_PRINTF("RDMSR\n");
202 TRACE_AND_STEP();
203 M.x86.R_EDX = 0;
204 M.x86.R_EAX = 0;
205 DECODE_CLEAR_SEGOVR();
206 END_OF_INSTR();
209 #define xorl(a,b) (((a) && !(b)) || (!(a) && (b)))
211 /****************************************************************************
212 REMARKS:
213 Handles opcode 0x0f,0x80-0x8F
214 ****************************************************************************/
215 int x86emu_check_jump_condition(u8 op)
217 switch (op) {
218 case 0x0:
219 DECODE_PRINTF("JO\t");
220 return ACCESS_FLAG(F_OF);
221 case 0x1:
222 DECODE_PRINTF("JNO\t");
223 return !ACCESS_FLAG(F_OF);
224 break;
225 case 0x2:
226 DECODE_PRINTF("JB\t");
227 return ACCESS_FLAG(F_CF);
228 break;
229 case 0x3:
230 DECODE_PRINTF("JNB\t");
231 return !ACCESS_FLAG(F_CF);
232 break;
233 case 0x4:
234 DECODE_PRINTF("JZ\t");
235 return ACCESS_FLAG(F_ZF);
236 break;
237 case 0x5:
238 DECODE_PRINTF("JNZ\t");
239 return !ACCESS_FLAG(F_ZF);
240 break;
241 case 0x6:
242 DECODE_PRINTF("JBE\t");
243 return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
244 break;
245 case 0x7:
246 DECODE_PRINTF("JNBE\t");
247 return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
248 break;
249 case 0x8:
250 DECODE_PRINTF("JS\t");
251 return ACCESS_FLAG(F_SF);
252 break;
253 case 0x9:
254 DECODE_PRINTF("JNS\t");
255 return !ACCESS_FLAG(F_SF);
256 break;
257 case 0xa:
258 DECODE_PRINTF("JP\t");
259 return ACCESS_FLAG(F_PF);
260 break;
261 case 0xb:
262 DECODE_PRINTF("JNP\t");
263 return !ACCESS_FLAG(F_PF);
264 break;
265 case 0xc:
266 DECODE_PRINTF("JL\t");
267 return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
268 break;
269 case 0xd:
270 DECODE_PRINTF("JNL\t");
271 return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
272 break;
273 case 0xe:
274 DECODE_PRINTF("JLE\t");
275 return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
276 ACCESS_FLAG(F_ZF));
277 break;
278 default:
279 DECODE_PRINTF("JNLE\t");
280 return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
281 ACCESS_FLAG(F_ZF));
285 static void x86emuOp2_long_jump(u8 op2)
287 s32 target;
288 int cond;
290 /* conditional jump to word offset. */
291 START_OF_INSTR();
292 cond = x86emu_check_jump_condition(op2 & 0xF);
293 target = (s16) fetch_word_imm();
294 target += (s16) M.x86.R_IP;
295 DECODE_PRINTF2("%04x\n", target);
296 TRACE_AND_STEP();
297 if (cond) {
298 M.x86.R_IP = (u16)target;
299 JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, M.x86.R_IP, " LONG COND ");
301 DECODE_CLEAR_SEGOVR();
302 END_OF_INSTR();
305 /****************************************************************************
306 REMARKS:
307 Handles opcode 0x0f,0xC8-0xCF
308 ****************************************************************************/
309 static s32 x86emu_bswap(s32 reg)
311 // perform the byte swap
312 s32 temp = reg;
313 reg = (temp & 0xFF000000) >> 24 |
314 (temp & 0xFF0000) >> 8 |
315 (temp & 0xFF00) << 8 |
316 (temp & 0xFF) << 24;
317 return reg;
320 static void x86emuOp2_bswap(u8 op2)
322 /* byte swap 32 bit register */
323 START_OF_INSTR();
324 DECODE_PRINTF("BSWAP\t");
325 switch (op2) {
326 case 0xc8:
327 DECODE_PRINTF("EAX\n");
328 M.x86.R_EAX = x86emu_bswap(M.x86.R_EAX);
329 break;
330 case 0xc9:
331 DECODE_PRINTF("ECX\n");
332 M.x86.R_ECX = x86emu_bswap(M.x86.R_ECX);
333 break;
334 case 0xca:
335 DECODE_PRINTF("EDX\n");
336 M.x86.R_EDX = x86emu_bswap(M.x86.R_EDX);
337 break;
338 case 0xcb:
339 DECODE_PRINTF("EBX\n");
340 M.x86.R_EBX = x86emu_bswap(M.x86.R_EBX);
341 break;
342 case 0xcc:
343 DECODE_PRINTF("ESP\n");
344 M.x86.R_ESP = x86emu_bswap(M.x86.R_ESP);
345 break;
346 case 0xcd:
347 DECODE_PRINTF("EBP\n");
348 M.x86.R_EBP = x86emu_bswap(M.x86.R_EBP);
349 break;
350 case 0xce:
351 DECODE_PRINTF("ESI\n");
352 M.x86.R_ESI = x86emu_bswap(M.x86.R_ESI);
353 break;
354 case 0xcf:
355 DECODE_PRINTF("EDI\n");
356 M.x86.R_EDI = x86emu_bswap(M.x86.R_EDI);
357 break;
359 TRACE_AND_STEP();
360 DECODE_CLEAR_SEGOVR();
361 END_OF_INSTR();
364 /****************************************************************************
365 REMARKS:
366 Handles opcode 0x0f,0x90-0x9F
367 ****************************************************************************/
368 static void x86emuOp2_set_byte(u8 op2)
370 int mod, rl, rh;
371 uint destoffset;
372 u8 *destreg;
373 const char *X86EMU_DEBUG_ONLY(name) = NULL;
374 int cond = 0;
376 START_OF_INSTR();
377 switch (op2) {
378 case 0x90:
379 name = "SETO\t";
380 cond = ACCESS_FLAG(F_OF);
381 break;
382 case 0x91:
383 name = "SETNO\t";
384 cond = !ACCESS_FLAG(F_OF);
385 break;
386 case 0x92:
387 name = "SETB\t";
388 cond = ACCESS_FLAG(F_CF);
389 break;
390 case 0x93:
391 name = "SETNB\t";
392 cond = !ACCESS_FLAG(F_CF);
393 break;
394 case 0x94:
395 name = "SETZ\t";
396 cond = ACCESS_FLAG(F_ZF);
397 break;
398 case 0x95:
399 name = "SETNZ\t";
400 cond = !ACCESS_FLAG(F_ZF);
401 break;
402 case 0x96:
403 name = "SETBE\t";
404 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
405 break;
406 case 0x97:
407 name = "SETNBE\t";
408 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
409 break;
410 case 0x98:
411 name = "SETS\t";
412 cond = ACCESS_FLAG(F_SF);
413 break;
414 case 0x99:
415 name = "SETNS\t";
416 cond = !ACCESS_FLAG(F_SF);
417 break;
418 case 0x9a:
419 name = "SETP\t";
420 cond = ACCESS_FLAG(F_PF);
421 break;
422 case 0x9b:
423 name = "SETNP\t";
424 cond = !ACCESS_FLAG(F_PF);
425 break;
426 case 0x9c:
427 name = "SETL\t";
428 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
429 break;
430 case 0x9d:
431 name = "SETNL\t";
432 cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
433 break;
434 case 0x9e:
435 name = "SETLE\t";
436 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
437 ACCESS_FLAG(F_ZF));
438 break;
439 case 0x9f:
440 name = "SETNLE\t";
441 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
442 ACCESS_FLAG(F_ZF));
443 break;
445 DECODE_PRINTF(name);
446 FETCH_DECODE_MODRM(mod, rh, rl);
447 if (mod < 3) {
448 destoffset = decode_rmXX_address(mod, rl);
449 TRACE_AND_STEP();
450 store_data_byte(destoffset, cond ? 0x01 : 0x00);
451 } else { /* register to register */
452 destreg = DECODE_RM_BYTE_REGISTER(rl);
453 TRACE_AND_STEP();
454 *destreg = cond ? 0x01 : 0x00;
456 DECODE_CLEAR_SEGOVR();
457 END_OF_INSTR();
460 /****************************************************************************
461 REMARKS:
462 Handles opcode 0x0f,0xa0
463 ****************************************************************************/
464 static void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
466 START_OF_INSTR();
467 DECODE_PRINTF("PUSH\tFS\n");
468 TRACE_AND_STEP();
469 push_word(M.x86.R_FS);
470 DECODE_CLEAR_SEGOVR();
471 END_OF_INSTR();
474 /****************************************************************************
475 REMARKS:
476 Handles opcode 0x0f,0xa1
477 ****************************************************************************/
478 static void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
480 START_OF_INSTR();
481 DECODE_PRINTF("POP\tFS\n");
482 TRACE_AND_STEP();
483 M.x86.R_FS = pop_word();
484 DECODE_CLEAR_SEGOVR();
485 END_OF_INSTR();
488 /****************************************************************************
489 REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
490 Handles opcode 0x0f,0xa2
491 ****************************************************************************/
492 static void x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
494 START_OF_INSTR();
495 DECODE_PRINTF("CPUID\n");
496 TRACE_AND_STEP();
497 x86emu_cpuid();
498 DECODE_CLEAR_SEGOVR();
499 END_OF_INSTR();
502 /****************************************************************************
503 REMARKS:
504 Handles opcode 0x0f,0xa3
505 ****************************************************************************/
506 static void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
508 int mod, rl, rh;
509 uint srcoffset;
510 int bit,disp;
512 START_OF_INSTR();
513 DECODE_PRINTF("BT\t");
514 FETCH_DECODE_MODRM(mod, rh, rl);
515 if (mod < 3) {
516 srcoffset = decode_rmXX_address(mod, rl);
517 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
518 u32 srcval;
519 u32 *shiftreg;
521 DECODE_PRINTF(",");
522 shiftreg = DECODE_RM_LONG_REGISTER(rh);
523 TRACE_AND_STEP();
524 bit = *shiftreg & 0x1F;
525 disp = (s16)*shiftreg >> 5;
526 srcval = fetch_data_long(srcoffset+disp);
527 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
528 } else {
529 u16 srcval;
530 u16 *shiftreg;
532 DECODE_PRINTF(",");
533 shiftreg = DECODE_RM_WORD_REGISTER(rh);
534 TRACE_AND_STEP();
535 bit = *shiftreg & 0xF;
536 disp = (s16)*shiftreg >> 4;
537 srcval = fetch_data_word(srcoffset+disp);
538 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
540 } else { /* register to register */
541 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
542 u32 *srcreg,*shiftreg;
544 srcreg = DECODE_RM_LONG_REGISTER(rl);
545 DECODE_PRINTF(",");
546 shiftreg = DECODE_RM_LONG_REGISTER(rh);
547 TRACE_AND_STEP();
548 bit = *shiftreg & 0x1F;
549 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
550 } else {
551 u16 *srcreg,*shiftreg;
553 srcreg = DECODE_RM_WORD_REGISTER(rl);
554 DECODE_PRINTF(",");
555 shiftreg = DECODE_RM_WORD_REGISTER(rh);
556 TRACE_AND_STEP();
557 bit = *shiftreg & 0xF;
558 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
561 DECODE_CLEAR_SEGOVR();
562 END_OF_INSTR();
565 /****************************************************************************
566 REMARKS:
567 Handles opcode 0x0f,0xa4
568 ****************************************************************************/
569 static void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
571 int mod, rl, rh;
572 uint destoffset;
573 u8 shift;
575 START_OF_INSTR();
576 DECODE_PRINTF("SHLD\t");
577 FETCH_DECODE_MODRM(mod, rh, rl);
578 if (mod < 3) {
579 destoffset = decode_rmXX_address(mod, rl);
580 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
581 u32 destval;
582 u32 *shiftreg;
584 DECODE_PRINTF(",");
585 shiftreg = DECODE_RM_LONG_REGISTER(rh);
586 DECODE_PRINTF(",");
587 shift = fetch_byte_imm();
588 DECODE_PRINTF2("%d\n", shift);
589 TRACE_AND_STEP();
590 destval = fetch_data_long(destoffset);
591 destval = shld_long(destval,*shiftreg,shift);
592 store_data_long(destoffset, destval);
593 } else {
594 u16 destval;
595 u16 *shiftreg;
597 DECODE_PRINTF(",");
598 shiftreg = DECODE_RM_WORD_REGISTER(rh);
599 DECODE_PRINTF(",");
600 shift = fetch_byte_imm();
601 DECODE_PRINTF2("%d\n", shift);
602 TRACE_AND_STEP();
603 destval = fetch_data_word(destoffset);
604 destval = shld_word(destval,*shiftreg,shift);
605 store_data_word(destoffset, destval);
607 } else { /* register to register */
608 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
609 u32 *destreg,*shiftreg;
611 destreg = DECODE_RM_LONG_REGISTER(rl);
612 DECODE_PRINTF(",");
613 shiftreg = DECODE_RM_LONG_REGISTER(rh);
614 DECODE_PRINTF(",");
615 shift = fetch_byte_imm();
616 DECODE_PRINTF2("%d\n", shift);
617 TRACE_AND_STEP();
618 *destreg = shld_long(*destreg,*shiftreg,shift);
619 } else {
620 u16 *destreg,*shiftreg;
622 destreg = DECODE_RM_WORD_REGISTER(rl);
623 DECODE_PRINTF(",");
624 shiftreg = DECODE_RM_WORD_REGISTER(rh);
625 DECODE_PRINTF(",");
626 shift = fetch_byte_imm();
627 DECODE_PRINTF2("%d\n", shift);
628 TRACE_AND_STEP();
629 *destreg = shld_word(*destreg,*shiftreg,shift);
632 DECODE_CLEAR_SEGOVR();
633 END_OF_INSTR();
636 /****************************************************************************
637 REMARKS:
638 Handles opcode 0x0f,0xa5
639 ****************************************************************************/
640 static void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
642 int mod, rl, rh;
643 uint destoffset;
645 START_OF_INSTR();
646 DECODE_PRINTF("SHLD\t");
647 FETCH_DECODE_MODRM(mod, rh, rl);
648 if (mod < 3) {
649 destoffset = decode_rmXX_address(mod, rl);
650 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
651 u32 destval;
652 u32 *shiftreg;
654 DECODE_PRINTF(",");
655 shiftreg = DECODE_RM_LONG_REGISTER(rh);
656 DECODE_PRINTF(",CL\n");
657 TRACE_AND_STEP();
658 destval = fetch_data_long(destoffset);
659 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
660 store_data_long(destoffset, destval);
661 } else {
662 u16 destval;
663 u16 *shiftreg;
665 DECODE_PRINTF(",");
666 shiftreg = DECODE_RM_WORD_REGISTER(rh);
667 DECODE_PRINTF(",CL\n");
668 TRACE_AND_STEP();
669 destval = fetch_data_word(destoffset);
670 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
671 store_data_word(destoffset, destval);
673 } else { /* register to register */
674 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
675 u32 *destreg,*shiftreg;
677 destreg = DECODE_RM_LONG_REGISTER(rl);
678 DECODE_PRINTF(",");
679 shiftreg = DECODE_RM_LONG_REGISTER(rh);
680 DECODE_PRINTF(",CL\n");
681 TRACE_AND_STEP();
682 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
683 } else {
684 u16 *destreg,*shiftreg;
686 destreg = DECODE_RM_WORD_REGISTER(rl);
687 DECODE_PRINTF(",");
688 shiftreg = DECODE_RM_WORD_REGISTER(rh);
689 DECODE_PRINTF(",CL\n");
690 TRACE_AND_STEP();
691 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
694 DECODE_CLEAR_SEGOVR();
695 END_OF_INSTR();
698 /****************************************************************************
699 REMARKS:
700 Handles opcode 0x0f,0xa8
701 ****************************************************************************/
702 static void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
704 START_OF_INSTR();
705 DECODE_PRINTF("PUSH\tGS\n");
706 TRACE_AND_STEP();
707 push_word(M.x86.R_GS);
708 DECODE_CLEAR_SEGOVR();
709 END_OF_INSTR();
712 /****************************************************************************
713 REMARKS:
714 Handles opcode 0x0f,0xa9
715 ****************************************************************************/
716 static void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
718 START_OF_INSTR();
719 DECODE_PRINTF("POP\tGS\n");
720 TRACE_AND_STEP();
721 M.x86.R_GS = pop_word();
722 DECODE_CLEAR_SEGOVR();
723 END_OF_INSTR();
726 /****************************************************************************
727 REMARKS:
728 Handles opcode 0x0f,0xab
729 ****************************************************************************/
730 static void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
732 int mod, rl, rh;
733 uint srcoffset;
734 int bit,disp;
736 START_OF_INSTR();
737 DECODE_PRINTF("BTS\t");
738 FETCH_DECODE_MODRM(mod, rh, rl);
739 if (mod < 3) {
740 srcoffset = decode_rmXX_address(mod, rl);
741 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
742 u32 srcval,mask;
743 u32 *shiftreg;
745 DECODE_PRINTF(",");
746 shiftreg = DECODE_RM_LONG_REGISTER(rh);
747 TRACE_AND_STEP();
748 bit = *shiftreg & 0x1F;
749 disp = (s16)*shiftreg >> 5;
750 srcval = fetch_data_long(srcoffset+disp);
751 mask = (0x1 << bit);
752 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
753 store_data_long(srcoffset+disp, srcval | mask);
754 } else {
755 u16 srcval,mask;
756 u16 *shiftreg;
758 DECODE_PRINTF(",");
759 shiftreg = DECODE_RM_WORD_REGISTER(rh);
760 TRACE_AND_STEP();
761 bit = *shiftreg & 0xF;
762 disp = (s16)*shiftreg >> 4;
763 srcval = fetch_data_word(srcoffset+disp);
764 mask = (u16)(0x1 << bit);
765 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
766 store_data_word(srcoffset+disp, srcval | mask);
768 } else { /* register to register */
769 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
770 u32 *srcreg,*shiftreg;
771 u32 mask;
773 srcreg = DECODE_RM_LONG_REGISTER(rl);
774 DECODE_PRINTF(",");
775 shiftreg = DECODE_RM_LONG_REGISTER(rh);
776 TRACE_AND_STEP();
777 bit = *shiftreg & 0x1F;
778 mask = (0x1 << bit);
779 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
780 *srcreg |= mask;
781 } else {
782 u16 *srcreg,*shiftreg;
783 u16 mask;
785 srcreg = DECODE_RM_WORD_REGISTER(rl);
786 DECODE_PRINTF(",");
787 shiftreg = DECODE_RM_WORD_REGISTER(rh);
788 TRACE_AND_STEP();
789 bit = *shiftreg & 0xF;
790 mask = (u16)(0x1 << bit);
791 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
792 *srcreg |= mask;
795 DECODE_CLEAR_SEGOVR();
796 END_OF_INSTR();
799 /****************************************************************************
800 REMARKS:
801 Handles opcode 0x0f,0xac
802 ****************************************************************************/
803 static void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
805 int mod, rl, rh;
806 uint destoffset;
807 u8 shift;
809 START_OF_INSTR();
810 DECODE_PRINTF("SHLD\t");
811 FETCH_DECODE_MODRM(mod, rh, rl);
812 if (mod < 3) {
813 destoffset = decode_rmXX_address(mod, rl);
814 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
815 u32 destval;
816 u32 *shiftreg;
818 DECODE_PRINTF(",");
819 shiftreg = DECODE_RM_LONG_REGISTER(rh);
820 DECODE_PRINTF(",");
821 shift = fetch_byte_imm();
822 DECODE_PRINTF2("%d\n", shift);
823 TRACE_AND_STEP();
824 destval = fetch_data_long(destoffset);
825 destval = shrd_long(destval,*shiftreg,shift);
826 store_data_long(destoffset, destval);
827 } else {
828 u16 destval;
829 u16 *shiftreg;
831 DECODE_PRINTF(",");
832 shiftreg = DECODE_RM_WORD_REGISTER(rh);
833 DECODE_PRINTF(",");
834 shift = fetch_byte_imm();
835 DECODE_PRINTF2("%d\n", shift);
836 TRACE_AND_STEP();
837 destval = fetch_data_word(destoffset);
838 destval = shrd_word(destval,*shiftreg,shift);
839 store_data_word(destoffset, destval);
841 } else { /* register to register */
842 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
843 u32 *destreg,*shiftreg;
845 destreg = DECODE_RM_LONG_REGISTER(rl);
846 DECODE_PRINTF(",");
847 shiftreg = DECODE_RM_LONG_REGISTER(rh);
848 DECODE_PRINTF(",");
849 shift = fetch_byte_imm();
850 DECODE_PRINTF2("%d\n", shift);
851 TRACE_AND_STEP();
852 *destreg = shrd_long(*destreg,*shiftreg,shift);
853 } else {
854 u16 *destreg,*shiftreg;
856 destreg = DECODE_RM_WORD_REGISTER(rl);
857 DECODE_PRINTF(",");
858 shiftreg = DECODE_RM_WORD_REGISTER(rh);
859 DECODE_PRINTF(",");
860 shift = fetch_byte_imm();
861 DECODE_PRINTF2("%d\n", shift);
862 TRACE_AND_STEP();
863 *destreg = shrd_word(*destreg,*shiftreg,shift);
866 DECODE_CLEAR_SEGOVR();
867 END_OF_INSTR();
870 /****************************************************************************
871 REMARKS:
872 Handles opcode 0x0f,0xad
873 ****************************************************************************/
874 static void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
876 int mod, rl, rh;
877 uint destoffset;
879 START_OF_INSTR();
880 DECODE_PRINTF("SHLD\t");
881 FETCH_DECODE_MODRM(mod, rh, rl);
882 if (mod < 3) {
883 destoffset = decode_rmXX_address(mod, rl);
884 DECODE_PRINTF(",");
885 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
886 u32 destval;
887 u32 *shiftreg;
889 shiftreg = DECODE_RM_LONG_REGISTER(rh);
890 DECODE_PRINTF(",CL\n");
891 TRACE_AND_STEP();
892 destval = fetch_data_long(destoffset);
893 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
894 store_data_long(destoffset, destval);
895 } else {
896 u16 destval;
897 u16 *shiftreg;
899 shiftreg = DECODE_RM_WORD_REGISTER(rh);
900 DECODE_PRINTF(",CL\n");
901 TRACE_AND_STEP();
902 destval = fetch_data_word(destoffset);
903 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
904 store_data_word(destoffset, destval);
906 } else { /* register to register */
907 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
908 u32 *destreg,*shiftreg;
910 destreg = DECODE_RM_LONG_REGISTER(rl);
911 DECODE_PRINTF(",");
912 shiftreg = DECODE_RM_LONG_REGISTER(rh);
913 DECODE_PRINTF(",CL\n");
914 TRACE_AND_STEP();
915 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
916 } else {
917 u16 *destreg,*shiftreg;
919 destreg = DECODE_RM_WORD_REGISTER(rl);
920 DECODE_PRINTF(",");
921 shiftreg = DECODE_RM_WORD_REGISTER(rh);
922 DECODE_PRINTF(",CL\n");
923 TRACE_AND_STEP();
924 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
927 DECODE_CLEAR_SEGOVR();
928 END_OF_INSTR();
931 /****************************************************************************
932 REMARKS:
933 Handles opcode 0x0f,0xaf
934 ****************************************************************************/
935 static void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
937 int mod, rl, rh;
938 uint srcoffset;
940 START_OF_INSTR();
941 DECODE_PRINTF("IMUL\t");
942 FETCH_DECODE_MODRM(mod, rh, rl);
943 if (mod < 3) {
944 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
945 u32 *destreg;
946 u32 srcval;
947 u32 res_lo,res_hi;
949 destreg = DECODE_RM_LONG_REGISTER(rh);
950 DECODE_PRINTF(",");
951 srcoffset = decode_rmXX_address(mod, rl);
952 srcval = fetch_data_long(srcoffset);
953 TRACE_AND_STEP();
954 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
955 if (res_hi != 0) {
956 SET_FLAG(F_CF);
957 SET_FLAG(F_OF);
958 } else {
959 CLEAR_FLAG(F_CF);
960 CLEAR_FLAG(F_OF);
962 *destreg = (u32)res_lo;
963 } else {
964 u16 *destreg;
965 u16 srcval;
966 u32 res;
968 destreg = DECODE_RM_WORD_REGISTER(rh);
969 DECODE_PRINTF(",");
970 srcoffset = decode_rmXX_address(mod, rl);
971 srcval = fetch_data_word(srcoffset);
972 TRACE_AND_STEP();
973 res = (s16)*destreg * (s16)srcval;
974 if (res > 0xFFFF) {
975 SET_FLAG(F_CF);
976 SET_FLAG(F_OF);
977 } else {
978 CLEAR_FLAG(F_CF);
979 CLEAR_FLAG(F_OF);
981 *destreg = (u16)res;
983 } else { /* register to register */
984 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
985 u32 *destreg,*srcreg;
986 u32 res_lo,res_hi;
988 destreg = DECODE_RM_LONG_REGISTER(rh);
989 DECODE_PRINTF(",");
990 srcreg = DECODE_RM_LONG_REGISTER(rl);
991 TRACE_AND_STEP();
992 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
993 if (res_hi != 0) {
994 SET_FLAG(F_CF);
995 SET_FLAG(F_OF);
996 } else {
997 CLEAR_FLAG(F_CF);
998 CLEAR_FLAG(F_OF);
1000 *destreg = (u32)res_lo;
1001 } else {
1002 u16 *destreg,*srcreg;
1003 u32 res;
1005 destreg = DECODE_RM_WORD_REGISTER(rh);
1006 DECODE_PRINTF(",");
1007 srcreg = DECODE_RM_WORD_REGISTER(rl);
1008 res = (s16)*destreg * (s16)*srcreg;
1009 if (res > 0xFFFF) {
1010 SET_FLAG(F_CF);
1011 SET_FLAG(F_OF);
1012 } else {
1013 CLEAR_FLAG(F_CF);
1014 CLEAR_FLAG(F_OF);
1016 *destreg = (u16)res;
1019 DECODE_CLEAR_SEGOVR();
1020 END_OF_INSTR();
1023 /****************************************************************************
1024 REMARKS:
1025 Handles opcode 0x0f,0xb2
1026 ****************************************************************************/
1027 static void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
1029 int mod, rh, rl;
1030 u16 *dstreg;
1031 uint srcoffset;
1033 START_OF_INSTR();
1034 DECODE_PRINTF("LSS\t");
1035 FETCH_DECODE_MODRM(mod, rh, rl);
1036 if (mod < 3) {
1037 dstreg = DECODE_RM_WORD_REGISTER(rh);
1038 DECODE_PRINTF(",");
1039 srcoffset = decode_rmXX_address(mod, rl);
1040 DECODE_PRINTF("\n");
1041 TRACE_AND_STEP();
1042 *dstreg = fetch_data_word(srcoffset);
1043 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1044 } else { /* register to register */
1045 /* UNDEFINED! */
1046 TRACE_AND_STEP();
1048 DECODE_CLEAR_SEGOVR();
1049 END_OF_INSTR();
1052 /****************************************************************************
1053 REMARKS:
1054 Handles opcode 0x0f,0xb3
1055 ****************************************************************************/
1056 static void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
1058 int mod, rl, rh;
1059 uint srcoffset;
1060 int bit,disp;
1062 START_OF_INSTR();
1063 DECODE_PRINTF("BTR\t");
1064 FETCH_DECODE_MODRM(mod, rh, rl);
1065 if (mod < 3) {
1066 srcoffset = decode_rmXX_address(mod, rl);
1067 DECODE_PRINTF(",");
1068 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1069 u32 srcval,mask;
1070 u32 *shiftreg;
1072 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1073 TRACE_AND_STEP();
1074 bit = *shiftreg & 0x1F;
1075 disp = (s16)*shiftreg >> 5;
1076 srcval = fetch_data_long(srcoffset+disp);
1077 mask = (0x1 << bit);
1078 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1079 store_data_long(srcoffset+disp, srcval & ~mask);
1080 } else {
1081 u16 srcval,mask;
1082 u16 *shiftreg;
1084 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1085 TRACE_AND_STEP();
1086 bit = *shiftreg & 0xF;
1087 disp = (s16)*shiftreg >> 4;
1088 srcval = fetch_data_word(srcoffset+disp);
1089 mask = (u16)(0x1 << bit);
1090 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1091 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1093 } else { /* register to register */
1094 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1095 u32 *srcreg,*shiftreg;
1096 u32 mask;
1098 srcreg = DECODE_RM_LONG_REGISTER(rl);
1099 DECODE_PRINTF(",");
1100 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1101 TRACE_AND_STEP();
1102 bit = *shiftreg & 0x1F;
1103 mask = (0x1 << bit);
1104 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1105 *srcreg &= ~mask;
1106 } else {
1107 u16 *srcreg,*shiftreg;
1108 u16 mask;
1110 srcreg = DECODE_RM_WORD_REGISTER(rl);
1111 DECODE_PRINTF(",");
1112 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1113 TRACE_AND_STEP();
1114 bit = *shiftreg & 0xF;
1115 mask = (u16)(0x1 << bit);
1116 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1117 *srcreg &= ~mask;
1120 DECODE_CLEAR_SEGOVR();
1121 END_OF_INSTR();
1124 /****************************************************************************
1125 REMARKS:
1126 Handles opcode 0x0f,0xb4
1127 ****************************************************************************/
1128 static void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
1130 int mod, rh, rl;
1131 u16 *dstreg;
1132 uint srcoffset;
1134 START_OF_INSTR();
1135 DECODE_PRINTF("LFS\t");
1136 FETCH_DECODE_MODRM(mod, rh, rl);
1137 if (mod < 3) {
1138 dstreg = DECODE_RM_WORD_REGISTER(rh);
1139 DECODE_PRINTF(",");
1140 srcoffset = decode_rmXX_address(mod, rl);
1141 DECODE_PRINTF("\n");
1142 TRACE_AND_STEP();
1143 *dstreg = fetch_data_word(srcoffset);
1144 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1145 } else { /* register to register */
1146 /* UNDEFINED! */
1147 TRACE_AND_STEP();
1149 DECODE_CLEAR_SEGOVR();
1150 END_OF_INSTR();
1153 /****************************************************************************
1154 REMARKS:
1155 Handles opcode 0x0f,0xb5
1156 ****************************************************************************/
1157 static void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
1159 int mod, rh, rl;
1160 u16 *dstreg;
1161 uint srcoffset;
1163 START_OF_INSTR();
1164 DECODE_PRINTF("LGS\t");
1165 FETCH_DECODE_MODRM(mod, rh, rl);
1166 if (mod < 3) {
1167 dstreg = DECODE_RM_WORD_REGISTER(rh);
1168 DECODE_PRINTF(",");
1169 srcoffset = decode_rmXX_address(mod, rl);
1170 DECODE_PRINTF("\n");
1171 TRACE_AND_STEP();
1172 *dstreg = fetch_data_word(srcoffset);
1173 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1174 } else { /* register to register */
1175 /* UNDEFINED! */
1176 TRACE_AND_STEP();
1178 DECODE_CLEAR_SEGOVR();
1179 END_OF_INSTR();
1182 /****************************************************************************
1183 REMARKS:
1184 Handles opcode 0x0f,0xb6
1185 ****************************************************************************/
1186 static void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1188 int mod, rl, rh;
1189 uint srcoffset;
1191 START_OF_INSTR();
1192 DECODE_PRINTF("MOVZX\t");
1193 FETCH_DECODE_MODRM(mod, rh, rl);
1194 if (mod < 3) {
1195 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1196 u32 *destreg;
1197 u32 srcval;
1199 destreg = DECODE_RM_LONG_REGISTER(rh);
1200 DECODE_PRINTF(",");
1201 srcoffset = decode_rmXX_address(mod, rl);
1202 srcval = fetch_data_byte(srcoffset);
1203 DECODE_PRINTF("\n");
1204 TRACE_AND_STEP();
1205 *destreg = srcval;
1206 } else {
1207 u16 *destreg;
1208 u16 srcval;
1210 destreg = DECODE_RM_WORD_REGISTER(rh);
1211 DECODE_PRINTF(",");
1212 srcoffset = decode_rmXX_address(mod, rl);
1213 srcval = fetch_data_byte(srcoffset);
1214 DECODE_PRINTF("\n");
1215 TRACE_AND_STEP();
1216 *destreg = srcval;
1218 } else { /* register to register */
1219 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1220 u32 *destreg;
1221 u8 *srcreg;
1223 destreg = DECODE_RM_LONG_REGISTER(rh);
1224 DECODE_PRINTF(",");
1225 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1226 DECODE_PRINTF("\n");
1227 TRACE_AND_STEP();
1228 *destreg = *srcreg;
1229 } else {
1230 u16 *destreg;
1231 u8 *srcreg;
1233 destreg = DECODE_RM_WORD_REGISTER(rh);
1234 DECODE_PRINTF(",");
1235 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1236 DECODE_PRINTF("\n");
1237 TRACE_AND_STEP();
1238 *destreg = *srcreg;
1241 DECODE_CLEAR_SEGOVR();
1242 END_OF_INSTR();
1245 /****************************************************************************
1246 REMARKS:
1247 Handles opcode 0x0f,0xb7
1248 ****************************************************************************/
1249 static void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1251 int mod, rl, rh;
1252 uint srcoffset;
1253 u32 *destreg;
1254 u32 srcval;
1255 u16 *srcreg;
1257 START_OF_INSTR();
1258 DECODE_PRINTF("MOVZX\t");
1259 FETCH_DECODE_MODRM(mod, rh, rl);
1260 if (mod < 3) {
1261 destreg = DECODE_RM_LONG_REGISTER(rh);
1262 DECODE_PRINTF(",");
1263 srcoffset = decode_rmXX_address(mod, rl);
1264 srcval = fetch_data_word(srcoffset);
1265 DECODE_PRINTF("\n");
1266 TRACE_AND_STEP();
1267 *destreg = srcval;
1268 } else { /* register to register */
1269 destreg = DECODE_RM_LONG_REGISTER(rh);
1270 DECODE_PRINTF(",");
1271 srcreg = DECODE_RM_WORD_REGISTER(rl);
1272 DECODE_PRINTF("\n");
1273 TRACE_AND_STEP();
1274 *destreg = *srcreg;
1276 DECODE_CLEAR_SEGOVR();
1277 END_OF_INSTR();
1280 /****************************************************************************
1281 REMARKS:
1282 Handles opcode 0x0f,0xba
1283 ****************************************************************************/
1284 static void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1286 int mod, rl, rh;
1287 uint srcoffset;
1288 u8 shift;
1289 int bit;
1291 START_OF_INSTR();
1292 FETCH_DECODE_MODRM(mod, rh, rl);
1293 switch (rh) {
1294 case 4:
1295 DECODE_PRINTF("BT\t");
1296 break;
1297 case 5:
1298 DECODE_PRINTF("BTS\t");
1299 break;
1300 case 6:
1301 DECODE_PRINTF("BTR\t");
1302 break;
1303 case 7:
1304 DECODE_PRINTF("BTC\t");
1305 break;
1306 default:
1307 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1308 TRACE_REGS();
1309 printf("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1310 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1311 HALT_SYS();
1313 if (mod < 3) {
1315 srcoffset = decode_rmXX_address(mod, rl);
1316 shift = fetch_byte_imm();
1317 DECODE_PRINTF2(",%d\n", shift);
1318 TRACE_AND_STEP();
1320 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1321 u32 srcval, mask;
1323 bit = shift & 0x1F;
1324 srcval = fetch_data_long(srcoffset);
1325 mask = (0x1 << bit);
1326 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1327 switch (rh) {
1328 case 5:
1329 store_data_long(srcoffset, srcval | mask);
1330 break;
1331 case 6:
1332 store_data_long(srcoffset, srcval & ~mask);
1333 break;
1334 case 7:
1335 store_data_long(srcoffset, srcval ^ mask);
1336 break;
1337 default:
1338 break;
1340 } else {
1341 u16 srcval, mask;
1343 bit = shift & 0xF;
1344 srcval = fetch_data_word(srcoffset);
1345 mask = (0x1 << bit);
1346 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1347 switch (rh) {
1348 case 5:
1349 store_data_word(srcoffset, srcval | mask);
1350 break;
1351 case 6:
1352 store_data_word(srcoffset, srcval & ~mask);
1353 break;
1354 case 7:
1355 store_data_word(srcoffset, srcval ^ mask);
1356 break;
1357 default:
1358 break;
1361 } else { /* register to register */
1362 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1363 u32 *srcreg;
1364 u32 mask;
1366 srcreg = DECODE_RM_LONG_REGISTER(rl);
1367 shift = fetch_byte_imm();
1368 DECODE_PRINTF2(",%d\n", shift);
1369 TRACE_AND_STEP();
1370 bit = shift & 0x1F;
1371 mask = (0x1 << bit);
1372 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1373 switch (rh) {
1374 case 5:
1375 *srcreg |= mask;
1376 break;
1377 case 6:
1378 *srcreg &= ~mask;
1379 break;
1380 case 7:
1381 *srcreg ^= mask;
1382 break;
1383 default:
1384 break;
1386 } else {
1387 u16 *srcreg;
1388 u16 mask;
1390 srcreg = DECODE_RM_WORD_REGISTER(rl);
1391 shift = fetch_byte_imm();
1392 DECODE_PRINTF2(",%d\n", shift);
1393 TRACE_AND_STEP();
1394 bit = shift & 0xF;
1395 mask = (0x1 << bit);
1396 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1397 switch (rh) {
1398 case 5:
1399 *srcreg |= mask;
1400 break;
1401 case 6:
1402 *srcreg &= ~mask;
1403 break;
1404 case 7:
1405 *srcreg ^= mask;
1406 break;
1407 default:
1408 break;
1412 DECODE_CLEAR_SEGOVR();
1413 END_OF_INSTR();
1416 /****************************************************************************
1417 REMARKS:
1418 Handles opcode 0x0f,0xbb
1419 ****************************************************************************/
1420 static void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
1422 int mod, rl, rh;
1423 uint srcoffset;
1424 int bit,disp;
1426 START_OF_INSTR();
1427 DECODE_PRINTF("BTC\t");
1428 FETCH_DECODE_MODRM(mod, rh, rl);
1429 if (mod < 3) {
1430 srcoffset = decode_rmXX_address(mod, rl);
1431 DECODE_PRINTF(",");
1432 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1433 u32 srcval,mask;
1434 u32 *shiftreg;
1436 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1437 TRACE_AND_STEP();
1438 bit = *shiftreg & 0x1F;
1439 disp = (s16)*shiftreg >> 5;
1440 srcval = fetch_data_long(srcoffset+disp);
1441 mask = (0x1 << bit);
1442 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1443 store_data_long(srcoffset+disp, srcval ^ mask);
1444 } else {
1445 u16 srcval,mask;
1446 u16 *shiftreg;
1448 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1449 TRACE_AND_STEP();
1450 bit = *shiftreg & 0xF;
1451 disp = (s16)*shiftreg >> 4;
1452 srcval = fetch_data_word(srcoffset+disp);
1453 mask = (u16)(0x1 << bit);
1454 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1455 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
1457 } else { /* register to register */
1458 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1459 u32 *srcreg,*shiftreg;
1460 u32 mask;
1462 srcreg = DECODE_RM_LONG_REGISTER(rl);
1463 DECODE_PRINTF(",");
1464 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1465 TRACE_AND_STEP();
1466 bit = *shiftreg & 0x1F;
1467 mask = (0x1 << bit);
1468 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1469 *srcreg ^= mask;
1470 } else {
1471 u16 *srcreg,*shiftreg;
1472 u16 mask;
1474 srcreg = DECODE_RM_WORD_REGISTER(rl);
1475 DECODE_PRINTF(",");
1476 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1477 TRACE_AND_STEP();
1478 bit = *shiftreg & 0xF;
1479 mask = (u16)(0x1 << bit);
1480 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1481 *srcreg ^= mask;
1484 DECODE_CLEAR_SEGOVR();
1485 END_OF_INSTR();
1488 /****************************************************************************
1489 REMARKS:
1490 Handles opcode 0x0f,0xbc
1491 ****************************************************************************/
1492 static void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
1494 int mod, rl, rh;
1495 uint srcoffset;
1497 START_OF_INSTR();
1498 DECODE_PRINTF("BSF\t");
1499 FETCH_DECODE_MODRM(mod, rh, rl);
1500 if (mod < 3) {
1501 srcoffset = decode_rmXX_address(mod, rl);
1502 DECODE_PRINTF(",");
1503 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1504 u32 srcval, *dstreg;
1506 dstreg = DECODE_RM_LONG_REGISTER(rh);
1507 TRACE_AND_STEP();
1508 srcval = fetch_data_long(srcoffset);
1509 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1510 for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
1511 if ((srcval >> *dstreg) & 1) break;
1512 } else {
1513 u16 srcval, *dstreg;
1515 dstreg = DECODE_RM_WORD_REGISTER(rh);
1516 TRACE_AND_STEP();
1517 srcval = fetch_data_word(srcoffset);
1518 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1519 for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
1520 if ((srcval >> *dstreg) & 1) break;
1522 } else { /* register to register */
1523 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1524 u32 srcval, *dstreg;
1526 srcval = *DECODE_RM_LONG_REGISTER(rl);
1527 DECODE_PRINTF(",");
1528 dstreg = DECODE_RM_LONG_REGISTER(rh);
1529 TRACE_AND_STEP();
1530 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1531 for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
1532 if ((srcval >> *dstreg) & 1) break;
1533 } else {
1534 u16 srcval, *dstreg;
1536 srcval = *DECODE_RM_WORD_REGISTER(rl);
1537 DECODE_PRINTF(",");
1538 dstreg = DECODE_RM_WORD_REGISTER(rh);
1539 TRACE_AND_STEP();
1540 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1541 for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
1542 if ((srcval >> *dstreg) & 1) break;
1545 DECODE_CLEAR_SEGOVR();
1546 END_OF_INSTR();
1549 /****************************************************************************
1550 REMARKS:
1551 Handles opcode 0x0f,0xbd
1552 ****************************************************************************/
1553 static void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
1555 int mod, rl, rh;
1556 uint srcoffset;
1558 START_OF_INSTR();
1559 DECODE_PRINTF("BSR\t");
1560 FETCH_DECODE_MODRM(mod, rh, rl);
1561 if (mod < 3) {
1562 srcoffset = decode_rmXX_address(mod, rl);
1563 DECODE_PRINTF(",");
1564 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1565 u32 srcval, *dstreg;
1567 dstreg = DECODE_RM_LONG_REGISTER(rh);
1568 TRACE_AND_STEP();
1569 srcval = fetch_data_long(srcoffset);
1570 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1571 for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
1572 if ((srcval >> *dstreg) & 1) break;
1573 } else {
1574 u16 srcval, *dstreg;
1576 dstreg = DECODE_RM_WORD_REGISTER(rh);
1577 TRACE_AND_STEP();
1578 srcval = fetch_data_word(srcoffset);
1579 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1580 for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
1581 if ((srcval >> *dstreg) & 1) break;
1583 } else { /* register to register */
1584 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1585 u32 srcval, *dstreg;
1587 srcval = *DECODE_RM_LONG_REGISTER(rl);
1588 DECODE_PRINTF(",");
1589 dstreg = DECODE_RM_LONG_REGISTER(rh);
1590 TRACE_AND_STEP();
1591 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1592 for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
1593 if ((srcval >> *dstreg) & 1) break;
1594 } else {
1595 u16 srcval, *dstreg;
1597 srcval = *DECODE_RM_WORD_REGISTER(rl);
1598 DECODE_PRINTF(",");
1599 dstreg = DECODE_RM_WORD_REGISTER(rh);
1600 TRACE_AND_STEP();
1601 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1602 for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
1603 if ((srcval >> *dstreg) & 1) break;
1606 DECODE_CLEAR_SEGOVR();
1607 END_OF_INSTR();
1610 /****************************************************************************
1611 REMARKS:
1612 Handles opcode 0x0f,0xbe
1613 ****************************************************************************/
1614 static void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1616 int mod, rl, rh;
1617 uint srcoffset;
1619 START_OF_INSTR();
1620 DECODE_PRINTF("MOVSX\t");
1621 FETCH_DECODE_MODRM(mod, rh, rl);
1622 if (mod < 3) {
1623 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1624 u32 *destreg;
1625 u32 srcval;
1627 destreg = DECODE_RM_LONG_REGISTER(rh);
1628 DECODE_PRINTF(",");
1629 srcoffset = decode_rmXX_address(mod, rl);
1630 srcval = (s32)((s8)fetch_data_byte(srcoffset));
1631 DECODE_PRINTF("\n");
1632 TRACE_AND_STEP();
1633 *destreg = srcval;
1634 } else {
1635 u16 *destreg;
1636 u16 srcval;
1638 destreg = DECODE_RM_WORD_REGISTER(rh);
1639 DECODE_PRINTF(",");
1640 srcoffset = decode_rmXX_address(mod, rl);
1641 srcval = (s16)((s8)fetch_data_byte(srcoffset));
1642 DECODE_PRINTF("\n");
1643 TRACE_AND_STEP();
1644 *destreg = srcval;
1646 } else { /* register to register */
1647 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1648 u32 *destreg;
1649 u8 *srcreg;
1651 destreg = DECODE_RM_LONG_REGISTER(rh);
1652 DECODE_PRINTF(",");
1653 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1654 DECODE_PRINTF("\n");
1655 TRACE_AND_STEP();
1656 *destreg = (s32)((s8)*srcreg);
1657 } else {
1658 u16 *destreg;
1659 u8 *srcreg;
1661 destreg = DECODE_RM_WORD_REGISTER(rh);
1662 DECODE_PRINTF(",");
1663 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1664 DECODE_PRINTF("\n");
1665 TRACE_AND_STEP();
1666 *destreg = (s16)((s8)*srcreg);
1669 DECODE_CLEAR_SEGOVR();
1670 END_OF_INSTR();
1673 /****************************************************************************
1674 REMARKS:
1675 Handles opcode 0x0f,0xbf
1676 ****************************************************************************/
1677 static void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
1679 int mod, rl, rh;
1680 uint srcoffset;
1681 u32 *destreg;
1682 u32 srcval;
1683 u16 *srcreg;
1685 START_OF_INSTR();
1686 DECODE_PRINTF("MOVSX\t");
1687 FETCH_DECODE_MODRM(mod, rh, rl);
1688 if (mod < 3) {
1689 destreg = DECODE_RM_LONG_REGISTER(rh);
1690 DECODE_PRINTF(",");
1691 srcoffset = decode_rmXX_address(mod, rl);
1692 srcval = (s32)((s16)fetch_data_word(srcoffset));
1693 DECODE_PRINTF("\n");
1694 TRACE_AND_STEP();
1695 *destreg = srcval;
1696 } else { /* register to register */
1697 destreg = DECODE_RM_LONG_REGISTER(rh);
1698 DECODE_PRINTF(",");
1699 srcreg = DECODE_RM_WORD_REGISTER(rl);
1700 DECODE_PRINTF("\n");
1701 TRACE_AND_STEP();
1702 *destreg = (s32)((s16)*srcreg);
1704 DECODE_CLEAR_SEGOVR();
1705 END_OF_INSTR();
1708 /***************************************************************************
1709 * Double byte operation code table:
1710 **************************************************************************/
1711 void (*x86emu_optab2[256])(u8) =
1713 /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
1714 /* 0x01 */ x86emuOp2_opc_01, /* Group G (ring 0 PM) */
1715 /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
1716 /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
1717 /* 0x04 */ x86emuOp2_illegal_op,
1718 /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1719 /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
1720 /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1721 /* 0x08 */ x86emuOp2_invd, /* invd (ring 0 PM) */
1722 /* 0x09 */ x86emuOp2_wbinvd, /* wbinvd (ring 0 PM) */
1723 /* 0x0a */ x86emuOp2_illegal_op,
1724 /* 0x0b */ x86emuOp2_illegal_op,
1725 /* 0x0c */ x86emuOp2_illegal_op,
1726 /* 0x0d */ x86emuOp2_illegal_op,
1727 /* 0x0e */ x86emuOp2_illegal_op,
1728 /* 0x0f */ x86emuOp2_illegal_op,
1730 /* 0x10 */ x86emuOp2_illegal_op,
1731 /* 0x11 */ x86emuOp2_illegal_op,
1732 /* 0x12 */ x86emuOp2_illegal_op,
1733 /* 0x13 */ x86emuOp2_illegal_op,
1734 /* 0x14 */ x86emuOp2_illegal_op,
1735 /* 0x15 */ x86emuOp2_illegal_op,
1736 /* 0x16 */ x86emuOp2_illegal_op,
1737 /* 0x17 */ x86emuOp2_illegal_op,
1738 /* 0x18 */ x86emuOp2_illegal_op,
1739 /* 0x19 */ x86emuOp2_illegal_op,
1740 /* 0x1a */ x86emuOp2_illegal_op,
1741 /* 0x1b */ x86emuOp2_illegal_op,
1742 /* 0x1c */ x86emuOp2_illegal_op,
1743 /* 0x1d */ x86emuOp2_illegal_op,
1744 /* 0x1e */ x86emuOp2_illegal_op,
1745 /* 0x1f */ x86emuOp2_illegal_op,
1747 /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
1748 /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
1749 /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
1750 /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
1751 /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
1752 /* 0x25 */ x86emuOp2_illegal_op,
1753 /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
1754 /* 0x27 */ x86emuOp2_illegal_op,
1755 /* 0x28 */ x86emuOp2_illegal_op,
1756 /* 0x29 */ x86emuOp2_illegal_op,
1757 /* 0x2a */ x86emuOp2_illegal_op,
1758 /* 0x2b */ x86emuOp2_illegal_op,
1759 /* 0x2c */ x86emuOp2_illegal_op,
1760 /* 0x2d */ x86emuOp2_illegal_op,
1761 /* 0x2e */ x86emuOp2_illegal_op,
1762 /* 0x2f */ x86emuOp2_illegal_op,
1764 /* 0x30 */ x86emuOp2_wrmsr,
1765 /* 0x31 */ x86emuOp2_rdtsc,
1766 /* 0x32 */ x86emuOp2_rdmsr,
1767 /* 0x33 */ x86emuOp2_illegal_op,
1768 /* 0x34 */ x86emuOp2_illegal_op,
1769 /* 0x35 */ x86emuOp2_illegal_op,
1770 /* 0x36 */ x86emuOp2_illegal_op,
1771 /* 0x37 */ x86emuOp2_illegal_op,
1772 /* 0x38 */ x86emuOp2_illegal_op,
1773 /* 0x39 */ x86emuOp2_illegal_op,
1774 /* 0x3a */ x86emuOp2_illegal_op,
1775 /* 0x3b */ x86emuOp2_illegal_op,
1776 /* 0x3c */ x86emuOp2_illegal_op,
1777 /* 0x3d */ x86emuOp2_illegal_op,
1778 /* 0x3e */ x86emuOp2_illegal_op,
1779 /* 0x3f */ x86emuOp2_illegal_op,
1781 /* 0x40 */ x86emuOp2_illegal_op,
1782 /* 0x41 */ x86emuOp2_illegal_op,
1783 /* 0x42 */ x86emuOp2_illegal_op,
1784 /* 0x43 */ x86emuOp2_illegal_op,
1785 /* 0x44 */ x86emuOp2_illegal_op,
1786 /* 0x45 */ x86emuOp2_illegal_op,
1787 /* 0x46 */ x86emuOp2_illegal_op,
1788 /* 0x47 */ x86emuOp2_illegal_op,
1789 /* 0x48 */ x86emuOp2_illegal_op,
1790 /* 0x49 */ x86emuOp2_illegal_op,
1791 /* 0x4a */ x86emuOp2_illegal_op,
1792 /* 0x4b */ x86emuOp2_illegal_op,
1793 /* 0x4c */ x86emuOp2_illegal_op,
1794 /* 0x4d */ x86emuOp2_illegal_op,
1795 /* 0x4e */ x86emuOp2_illegal_op,
1796 /* 0x4f */ x86emuOp2_illegal_op,
1798 /* 0x50 */ x86emuOp2_illegal_op,
1799 /* 0x51 */ x86emuOp2_illegal_op,
1800 /* 0x52 */ x86emuOp2_illegal_op,
1801 /* 0x53 */ x86emuOp2_illegal_op,
1802 /* 0x54 */ x86emuOp2_illegal_op,
1803 /* 0x55 */ x86emuOp2_illegal_op,
1804 /* 0x56 */ x86emuOp2_illegal_op,
1805 /* 0x57 */ x86emuOp2_illegal_op,
1806 /* 0x58 */ x86emuOp2_illegal_op,
1807 /* 0x59 */ x86emuOp2_illegal_op,
1808 /* 0x5a */ x86emuOp2_illegal_op,
1809 /* 0x5b */ x86emuOp2_illegal_op,
1810 /* 0x5c */ x86emuOp2_illegal_op,
1811 /* 0x5d */ x86emuOp2_illegal_op,
1812 /* 0x5e */ x86emuOp2_illegal_op,
1813 /* 0x5f */ x86emuOp2_illegal_op,
1815 /* 0x60 */ x86emuOp2_illegal_op,
1816 /* 0x61 */ x86emuOp2_illegal_op,
1817 /* 0x62 */ x86emuOp2_illegal_op,
1818 /* 0x63 */ x86emuOp2_illegal_op,
1819 /* 0x64 */ x86emuOp2_illegal_op,
1820 /* 0x65 */ x86emuOp2_illegal_op,
1821 /* 0x66 */ x86emuOp2_illegal_op,
1822 /* 0x67 */ x86emuOp2_illegal_op,
1823 /* 0x68 */ x86emuOp2_illegal_op,
1824 /* 0x69 */ x86emuOp2_illegal_op,
1825 /* 0x6a */ x86emuOp2_illegal_op,
1826 /* 0x6b */ x86emuOp2_illegal_op,
1827 /* 0x6c */ x86emuOp2_illegal_op,
1828 /* 0x6d */ x86emuOp2_illegal_op,
1829 /* 0x6e */ x86emuOp2_illegal_op,
1830 /* 0x6f */ x86emuOp2_illegal_op,
1832 /* 0x70 */ x86emuOp2_illegal_op,
1833 /* 0x71 */ x86emuOp2_illegal_op,
1834 /* 0x72 */ x86emuOp2_illegal_op,
1835 /* 0x73 */ x86emuOp2_illegal_op,
1836 /* 0x74 */ x86emuOp2_illegal_op,
1837 /* 0x75 */ x86emuOp2_illegal_op,
1838 /* 0x76 */ x86emuOp2_illegal_op,
1839 /* 0x77 */ x86emuOp2_illegal_op,
1840 /* 0x78 */ x86emuOp2_illegal_op,
1841 /* 0x79 */ x86emuOp2_illegal_op,
1842 /* 0x7a */ x86emuOp2_illegal_op,
1843 /* 0x7b */ x86emuOp2_illegal_op,
1844 /* 0x7c */ x86emuOp2_illegal_op,
1845 /* 0x7d */ x86emuOp2_illegal_op,
1846 /* 0x7e */ x86emuOp2_illegal_op,
1847 /* 0x7f */ x86emuOp2_illegal_op,
1849 /* 0x80 */ x86emuOp2_long_jump,
1850 /* 0x81 */ x86emuOp2_long_jump,
1851 /* 0x82 */ x86emuOp2_long_jump,
1852 /* 0x83 */ x86emuOp2_long_jump,
1853 /* 0x84 */ x86emuOp2_long_jump,
1854 /* 0x85 */ x86emuOp2_long_jump,
1855 /* 0x86 */ x86emuOp2_long_jump,
1856 /* 0x87 */ x86emuOp2_long_jump,
1857 /* 0x88 */ x86emuOp2_long_jump,
1858 /* 0x89 */ x86emuOp2_long_jump,
1859 /* 0x8a */ x86emuOp2_long_jump,
1860 /* 0x8b */ x86emuOp2_long_jump,
1861 /* 0x8c */ x86emuOp2_long_jump,
1862 /* 0x8d */ x86emuOp2_long_jump,
1863 /* 0x8e */ x86emuOp2_long_jump,
1864 /* 0x8f */ x86emuOp2_long_jump,
1866 /* 0x90 */ x86emuOp2_set_byte,
1867 /* 0x91 */ x86emuOp2_set_byte,
1868 /* 0x92 */ x86emuOp2_set_byte,
1869 /* 0x93 */ x86emuOp2_set_byte,
1870 /* 0x94 */ x86emuOp2_set_byte,
1871 /* 0x95 */ x86emuOp2_set_byte,
1872 /* 0x96 */ x86emuOp2_set_byte,
1873 /* 0x97 */ x86emuOp2_set_byte,
1874 /* 0x98 */ x86emuOp2_set_byte,
1875 /* 0x99 */ x86emuOp2_set_byte,
1876 /* 0x9a */ x86emuOp2_set_byte,
1877 /* 0x9b */ x86emuOp2_set_byte,
1878 /* 0x9c */ x86emuOp2_set_byte,
1879 /* 0x9d */ x86emuOp2_set_byte,
1880 /* 0x9e */ x86emuOp2_set_byte,
1881 /* 0x9f */ x86emuOp2_set_byte,
1883 /* 0xa0 */ x86emuOp2_push_FS,
1884 /* 0xa1 */ x86emuOp2_pop_FS,
1885 /* 0xa2 */ x86emuOp2_cpuid,
1886 /* 0xa3 */ x86emuOp2_bt_R,
1887 /* 0xa4 */ x86emuOp2_shld_IMM,
1888 /* 0xa5 */ x86emuOp2_shld_CL,
1889 /* 0xa6 */ x86emuOp2_illegal_op,
1890 /* 0xa7 */ x86emuOp2_illegal_op,
1891 /* 0xa8 */ x86emuOp2_push_GS,
1892 /* 0xa9 */ x86emuOp2_pop_GS,
1893 /* 0xaa */ x86emuOp2_illegal_op,
1894 /* 0xab */ x86emuOp2_bts_R,
1895 /* 0xac */ x86emuOp2_shrd_IMM,
1896 /* 0xad */ x86emuOp2_shrd_CL,
1897 /* 0xae */ x86emuOp2_illegal_op,
1898 /* 0xaf */ x86emuOp2_imul_R_RM,
1900 /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1901 /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1902 /* 0xb2 */ x86emuOp2_lss_R_IMM,
1903 /* 0xb3 */ x86emuOp2_btr_R,
1904 /* 0xb4 */ x86emuOp2_lfs_R_IMM,
1905 /* 0xb5 */ x86emuOp2_lgs_R_IMM,
1906 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
1907 /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
1908 /* 0xb8 */ x86emuOp2_illegal_op,
1909 /* 0xb9 */ x86emuOp2_illegal_op,
1910 /* 0xba */ x86emuOp2_btX_I,
1911 /* 0xbb */ x86emuOp2_btc_R,
1912 /* 0xbc */ x86emuOp2_bsf,
1913 /* 0xbd */ x86emuOp2_bsr,
1914 /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
1915 /* 0xbf */ x86emuOp2_movsx_word_R_RM,
1917 /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
1918 /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
1919 /* 0xc2 */ x86emuOp2_illegal_op,
1920 /* 0xc3 */ x86emuOp2_illegal_op,
1921 /* 0xc4 */ x86emuOp2_illegal_op,
1922 /* 0xc5 */ x86emuOp2_illegal_op,
1923 /* 0xc6 */ x86emuOp2_illegal_op,
1924 /* 0xc7 */ x86emuOp2_illegal_op,
1925 /* 0xc8 */ x86emuOp2_bswap,
1926 /* 0xc9 */ x86emuOp2_bswap,
1927 /* 0xca */ x86emuOp2_bswap,
1928 /* 0xcb */ x86emuOp2_bswap,
1929 /* 0xcc */ x86emuOp2_bswap,
1930 /* 0xcd */ x86emuOp2_bswap,
1931 /* 0xce */ x86emuOp2_bswap,
1932 /* 0xcf */ x86emuOp2_bswap,
1934 /* 0xd0 */ x86emuOp2_illegal_op,
1935 /* 0xd1 */ x86emuOp2_illegal_op,
1936 /* 0xd2 */ x86emuOp2_illegal_op,
1937 /* 0xd3 */ x86emuOp2_illegal_op,
1938 /* 0xd4 */ x86emuOp2_illegal_op,
1939 /* 0xd5 */ x86emuOp2_illegal_op,
1940 /* 0xd6 */ x86emuOp2_illegal_op,
1941 /* 0xd7 */ x86emuOp2_illegal_op,
1942 /* 0xd8 */ x86emuOp2_illegal_op,
1943 /* 0xd9 */ x86emuOp2_illegal_op,
1944 /* 0xda */ x86emuOp2_illegal_op,
1945 /* 0xdb */ x86emuOp2_illegal_op,
1946 /* 0xdc */ x86emuOp2_illegal_op,
1947 /* 0xdd */ x86emuOp2_illegal_op,
1948 /* 0xde */ x86emuOp2_illegal_op,
1949 /* 0xdf */ x86emuOp2_illegal_op,
1951 /* 0xe0 */ x86emuOp2_illegal_op,
1952 /* 0xe1 */ x86emuOp2_illegal_op,
1953 /* 0xe2 */ x86emuOp2_illegal_op,
1954 /* 0xe3 */ x86emuOp2_illegal_op,
1955 /* 0xe4 */ x86emuOp2_illegal_op,
1956 /* 0xe5 */ x86emuOp2_illegal_op,
1957 /* 0xe6 */ x86emuOp2_illegal_op,
1958 /* 0xe7 */ x86emuOp2_illegal_op,
1959 /* 0xe8 */ x86emuOp2_illegal_op,
1960 /* 0xe9 */ x86emuOp2_illegal_op,
1961 /* 0xea */ x86emuOp2_illegal_op,
1962 /* 0xeb */ x86emuOp2_illegal_op,
1963 /* 0xec */ x86emuOp2_illegal_op,
1964 /* 0xed */ x86emuOp2_illegal_op,
1965 /* 0xee */ x86emuOp2_illegal_op,
1966 /* 0xef */ x86emuOp2_illegal_op,
1968 /* 0xf0 */ x86emuOp2_illegal_op,
1969 /* 0xf1 */ x86emuOp2_illegal_op,
1970 /* 0xf2 */ x86emuOp2_illegal_op,
1971 /* 0xf3 */ x86emuOp2_illegal_op,
1972 /* 0xf4 */ x86emuOp2_illegal_op,
1973 /* 0xf5 */ x86emuOp2_illegal_op,
1974 /* 0xf6 */ x86emuOp2_illegal_op,
1975 /* 0xf7 */ x86emuOp2_illegal_op,
1976 /* 0xf8 */ x86emuOp2_illegal_op,
1977 /* 0xf9 */ x86emuOp2_illegal_op,
1978 /* 0xfa */ x86emuOp2_illegal_op,
1979 /* 0xfb */ x86emuOp2_illegal_op,
1980 /* 0xfc */ x86emuOp2_illegal_op,
1981 /* 0xfd */ x86emuOp2_illegal_op,
1982 /* 0xfe */ x86emuOp2_illegal_op,
1983 /* 0xff */ x86emuOp2_illegal_op,