GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / x86emu / ops2.c
blobc59c813611517b94a246429c16d60cd4b06531cd
1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1996-1999 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 ****************************************************************************/
40 /* $XFree86: xc/extras/x86emu/src/x86emu/ops2.c,v 1.4 2000/11/16 19:44:50 eich Exp $ */
42 #include "x86emu/x86emui.h"
43 #include "x86emu/ops_protos.h"
45 /*----------------------------- Implementation ----------------------------*/
47 /****************************************************************************
48 PARAMETERS:
49 op1 - Instruction op code
51 REMARKS:
52 Handles illegal opcodes.
53 ****************************************************************************/
54 void x86emuOp2_illegal_op(
55 u8 op2)
57 START_OF_INSTR();
58 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
59 TRACE_REGS();
60 printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
61 M.x86.R_CS, M.x86.R_IP-2,op2);
62 HALT_SYS();
63 END_OF_INSTR();
66 #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
68 /****************************************************************************
69 REMARKS:
70 Handles opcode 0x0f,0x80-0x8F
71 ****************************************************************************/
72 void x86emuOp2_long_jump(u8 op2)
74 s32 target;
75 char *name = 0;
76 int cond = 0;
78 /* conditional jump to word offset. */
79 START_OF_INSTR();
80 switch (op2) {
81 case 0x80:
82 name = "JO\t";
83 cond = ACCESS_FLAG(F_OF);
84 break;
85 case 0x81:
86 name = "JNO\t";
87 cond = !ACCESS_FLAG(F_OF);
88 break;
89 case 0x82:
90 name = "JB\t";
91 cond = ACCESS_FLAG(F_CF);
92 break;
93 case 0x83:
94 name = "JNB\t";
95 cond = !ACCESS_FLAG(F_CF);
96 break;
97 case 0x84:
98 name = "JZ\t";
99 cond = ACCESS_FLAG(F_ZF);
100 break;
101 case 0x85:
102 name = "JNZ\t";
103 cond = !ACCESS_FLAG(F_ZF);
104 break;
105 case 0x86:
106 name = "JBE\t";
107 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
108 break;
109 case 0x87:
110 name = "JNBE\t";
111 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
112 break;
113 case 0x88:
114 name = "JS\t";
115 cond = ACCESS_FLAG(F_SF);
116 break;
117 case 0x89:
118 name = "JNS\t";
119 cond = !ACCESS_FLAG(F_SF);
120 break;
121 case 0x8a:
122 name = "JP\t";
123 cond = ACCESS_FLAG(F_PF);
124 break;
125 case 0x8b:
126 name = "JNP\t";
127 cond = !ACCESS_FLAG(F_PF);
128 break;
129 case 0x8c:
130 name = "JL\t";
131 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
132 break;
133 case 0x8d:
134 name = "JNL\t";
135 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
136 break;
137 case 0x8e:
138 name = "JLE\t";
139 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
140 ACCESS_FLAG(F_ZF));
141 break;
142 case 0x8f:
143 name = "JNLE\t";
144 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
145 ACCESS_FLAG(F_ZF));
146 break;
148 DECODE_PRINTF(name);
149 target = (s16) fetch_word_imm();
150 target += (s16) M.x86.R_IP;
151 DECODE_PRINTF2("%04x\n", target);
152 TRACE_AND_STEP();
153 if (cond)
154 M.x86.R_IP = (u16)target;
155 DECODE_CLEAR_SEGOVR();
156 END_OF_INSTR();
159 /****************************************************************************
160 REMARKS:
161 Handles opcode 0x0f,0x90-0x9F
162 ****************************************************************************/
163 void x86emuOp2_set_byte(u8 op2)
165 int mod, rl, rh;
166 uint destoffset;
167 u8 *destreg;
168 char *name = 0;
169 int cond = 0;
171 START_OF_INSTR();
172 switch (op2) {
173 case 0x90:
174 name = "SETO\t";
175 cond = ACCESS_FLAG(F_OF);
176 break;
177 case 0x91:
178 name = "SETNO\t";
179 cond = !ACCESS_FLAG(F_OF);
180 break;
181 case 0x92:
182 name = "SETB\t";
183 cond = ACCESS_FLAG(F_CF);
184 break;
185 case 0x93:
186 name = "SETNB\t";
187 cond = !ACCESS_FLAG(F_CF);
188 break;
189 case 0x94:
190 name = "SETZ\t";
191 cond = ACCESS_FLAG(F_ZF);
192 break;
193 case 0x95:
194 name = "SETNZ\t";
195 cond = !ACCESS_FLAG(F_ZF);
196 break;
197 case 0x96:
198 name = "SETBE\t";
199 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
200 break;
201 case 0x97:
202 name = "SETNBE\t";
203 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
204 break;
205 case 0x98:
206 name = "SETS\t";
207 cond = ACCESS_FLAG(F_SF);
208 break;
209 case 0x99:
210 name = "SETNS\t";
211 cond = !ACCESS_FLAG(F_SF);
212 break;
213 case 0x9a:
214 name = "SETP\t";
215 cond = ACCESS_FLAG(F_PF);
216 break;
217 case 0x9b:
218 name = "SETNP\t";
219 cond = !ACCESS_FLAG(F_PF);
220 break;
221 case 0x9c:
222 name = "SETL\t";
223 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
224 break;
225 case 0x9d:
226 name = "SETNL\t";
227 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
228 break;
229 case 0x9e:
230 name = "SETLE\t";
231 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
232 ACCESS_FLAG(F_ZF));
233 break;
234 case 0x9f:
235 name = "SETNLE\t";
236 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
237 ACCESS_FLAG(F_ZF));
238 break;
240 DECODE_PRINTF(name);
241 FETCH_DECODE_MODRM(mod, rh, rl);
242 switch (mod) {
243 case 0:
244 destoffset = decode_rm00_address(rl);
245 TRACE_AND_STEP();
246 store_data_byte(destoffset, cond ? 0x01 : 0x00);
247 break;
248 case 1:
249 destoffset = decode_rm01_address(rl);
250 TRACE_AND_STEP();
251 store_data_byte(destoffset, cond ? 0x01 : 0x00);
252 break;
253 case 2:
254 destoffset = decode_rm10_address(rl);
255 TRACE_AND_STEP();
256 store_data_byte(destoffset, cond ? 0x01 : 0x00);
257 break;
258 case 3: /* register to register */
259 destreg = DECODE_RM_BYTE_REGISTER(rl);
260 TRACE_AND_STEP();
261 *destreg = cond ? 0x01 : 0x00;
262 break;
264 DECODE_CLEAR_SEGOVR();
265 END_OF_INSTR();
268 /****************************************************************************
269 REMARKS:
270 Handles opcode 0x0f,0xa0
271 ****************************************************************************/
272 void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
274 START_OF_INSTR();
275 DECODE_PRINTF("PUSH\tFS\n");
276 TRACE_AND_STEP();
277 push_word(M.x86.R_FS);
278 DECODE_CLEAR_SEGOVR();
279 END_OF_INSTR();
282 /****************************************************************************
283 REMARKS:
284 Handles opcode 0x0f,0xa1
285 ****************************************************************************/
286 void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
288 START_OF_INSTR();
289 DECODE_PRINTF("POP\tFS\n");
290 TRACE_AND_STEP();
291 M.x86.R_FS = pop_word();
292 DECODE_CLEAR_SEGOVR();
293 END_OF_INSTR();
296 /****************************************************************************
297 REMARKS:
298 Handles opcode 0x0f,0xa3
299 ****************************************************************************/
300 void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
302 int mod, rl, rh;
303 uint srcoffset;
304 int bit,disp;
306 START_OF_INSTR();
307 DECODE_PRINTF("BT\t");
308 FETCH_DECODE_MODRM(mod, rh, rl);
309 switch (mod) {
310 case 0:
311 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
312 u32 srcval;
313 u32 *shiftreg;
315 srcoffset = decode_rm00_address(rl);
316 DECODE_PRINTF(",");
317 shiftreg = DECODE_RM_LONG_REGISTER(rh);
318 TRACE_AND_STEP();
319 bit = *shiftreg & 0x1F;
320 disp = (s16)*shiftreg >> 5;
321 srcval = fetch_data_long(srcoffset+disp);
322 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
323 } else {
324 u16 srcval;
325 u16 *shiftreg;
327 srcoffset = decode_rm00_address(rl);
328 DECODE_PRINTF(",");
329 shiftreg = DECODE_RM_WORD_REGISTER(rh);
330 TRACE_AND_STEP();
331 bit = *shiftreg & 0xF;
332 disp = (s16)*shiftreg >> 4;
333 srcval = fetch_data_word(srcoffset+disp);
334 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
336 break;
337 case 1:
338 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
339 u32 srcval;
340 u32 *shiftreg;
342 srcoffset = decode_rm01_address(rl);
343 DECODE_PRINTF(",");
344 shiftreg = DECODE_RM_LONG_REGISTER(rh);
345 TRACE_AND_STEP();
346 bit = *shiftreg & 0x1F;
347 disp = (s16)*shiftreg >> 5;
348 srcval = fetch_data_long(srcoffset+disp);
349 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
350 } else {
351 u16 srcval;
352 u16 *shiftreg;
354 srcoffset = decode_rm01_address(rl);
355 DECODE_PRINTF(",");
356 shiftreg = DECODE_RM_WORD_REGISTER(rh);
357 TRACE_AND_STEP();
358 bit = *shiftreg & 0xF;
359 disp = (s16)*shiftreg >> 4;
360 srcval = fetch_data_word(srcoffset+disp);
361 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
363 break;
364 case 2:
365 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
366 u32 srcval;
367 u32 *shiftreg;
369 srcoffset = decode_rm10_address(rl);
370 DECODE_PRINTF(",");
371 shiftreg = DECODE_RM_LONG_REGISTER(rh);
372 TRACE_AND_STEP();
373 bit = *shiftreg & 0x1F;
374 disp = (s16)*shiftreg >> 5;
375 srcval = fetch_data_long(srcoffset+disp);
376 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
377 } else {
378 u16 srcval;
379 u16 *shiftreg;
381 srcoffset = decode_rm10_address(rl);
382 DECODE_PRINTF(",");
383 shiftreg = DECODE_RM_WORD_REGISTER(rh);
384 TRACE_AND_STEP();
385 bit = *shiftreg & 0xF;
386 disp = (s16)*shiftreg >> 4;
387 srcval = fetch_data_word(srcoffset+disp);
388 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
390 break;
391 case 3: /* register to register */
392 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
393 u32 *srcreg,*shiftreg;
395 srcreg = DECODE_RM_LONG_REGISTER(rl);
396 DECODE_PRINTF(",");
397 shiftreg = DECODE_RM_LONG_REGISTER(rh);
398 TRACE_AND_STEP();
399 bit = *shiftreg & 0x1F;
400 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
401 } else {
402 u16 *srcreg,*shiftreg;
404 srcreg = DECODE_RM_WORD_REGISTER(rl);
405 DECODE_PRINTF(",");
406 shiftreg = DECODE_RM_WORD_REGISTER(rh);
407 TRACE_AND_STEP();
408 bit = *shiftreg & 0xF;
409 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
411 break;
413 DECODE_CLEAR_SEGOVR();
414 END_OF_INSTR();
417 /****************************************************************************
418 REMARKS:
419 Handles opcode 0x0f,0xa4
420 ****************************************************************************/
421 void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
423 int mod, rl, rh;
424 uint destoffset;
425 u8 shift;
427 START_OF_INSTR();
428 DECODE_PRINTF("SHLD\t");
429 FETCH_DECODE_MODRM(mod, rh, rl);
430 switch (mod) {
431 case 0:
432 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
433 u32 destval;
434 u32 *shiftreg;
436 destoffset = decode_rm00_address(rl);
437 DECODE_PRINTF(",");
438 shiftreg = DECODE_RM_LONG_REGISTER(rh);
439 DECODE_PRINTF(",");
440 shift = fetch_byte_imm();
441 DECODE_PRINTF2("%d\n", shift);
442 TRACE_AND_STEP();
443 destval = fetch_data_long(destoffset);
444 destval = shld_long(destval,*shiftreg,shift);
445 store_data_long(destoffset, destval);
446 } else {
447 u16 destval;
448 u16 *shiftreg;
450 destoffset = decode_rm00_address(rl);
451 DECODE_PRINTF(",");
452 shiftreg = DECODE_RM_WORD_REGISTER(rh);
453 DECODE_PRINTF(",");
454 shift = fetch_byte_imm();
455 DECODE_PRINTF2("%d\n", shift);
456 TRACE_AND_STEP();
457 destval = fetch_data_word(destoffset);
458 destval = shld_word(destval,*shiftreg,shift);
459 store_data_word(destoffset, destval);
461 break;
462 case 1:
463 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
464 u32 destval;
465 u32 *shiftreg;
467 destoffset = decode_rm01_address(rl);
468 DECODE_PRINTF(",");
469 shiftreg = DECODE_RM_LONG_REGISTER(rh);
470 DECODE_PRINTF(",");
471 shift = fetch_byte_imm();
472 DECODE_PRINTF2("%d\n", shift);
473 TRACE_AND_STEP();
474 destval = fetch_data_long(destoffset);
475 destval = shld_long(destval,*shiftreg,shift);
476 store_data_long(destoffset, destval);
477 } else {
478 u16 destval;
479 u16 *shiftreg;
481 destoffset = decode_rm01_address(rl);
482 DECODE_PRINTF(",");
483 shiftreg = DECODE_RM_WORD_REGISTER(rh);
484 DECODE_PRINTF(",");
485 shift = fetch_byte_imm();
486 DECODE_PRINTF2("%d\n", shift);
487 TRACE_AND_STEP();
488 destval = fetch_data_word(destoffset);
489 destval = shld_word(destval,*shiftreg,shift);
490 store_data_word(destoffset, destval);
492 break;
493 case 2:
494 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
495 u32 destval;
496 u32 *shiftreg;
498 destoffset = decode_rm10_address(rl);
499 DECODE_PRINTF(",");
500 shiftreg = DECODE_RM_LONG_REGISTER(rh);
501 DECODE_PRINTF(",");
502 shift = fetch_byte_imm();
503 DECODE_PRINTF2("%d\n", shift);
504 TRACE_AND_STEP();
505 destval = fetch_data_long(destoffset);
506 destval = shld_long(destval,*shiftreg,shift);
507 store_data_long(destoffset, destval);
508 } else {
509 u16 destval;
510 u16 *shiftreg;
512 destoffset = decode_rm10_address(rl);
513 DECODE_PRINTF(",");
514 shiftreg = DECODE_RM_WORD_REGISTER(rh);
515 DECODE_PRINTF(",");
516 shift = fetch_byte_imm();
517 DECODE_PRINTF2("%d\n", shift);
518 TRACE_AND_STEP();
519 destval = fetch_data_word(destoffset);
520 destval = shld_word(destval,*shiftreg,shift);
521 store_data_word(destoffset, destval);
523 break;
524 case 3: /* register to register */
525 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
526 u32 *destreg,*shiftreg;
528 destreg = DECODE_RM_LONG_REGISTER(rl);
529 DECODE_PRINTF(",");
530 shiftreg = DECODE_RM_LONG_REGISTER(rh);
531 DECODE_PRINTF(",");
532 shift = fetch_byte_imm();
533 DECODE_PRINTF2("%d\n", shift);
534 TRACE_AND_STEP();
535 *destreg = shld_long(*destreg,*shiftreg,shift);
536 } else {
537 u16 *destreg,*shiftreg;
539 destreg = DECODE_RM_WORD_REGISTER(rl);
540 DECODE_PRINTF(",");
541 shiftreg = DECODE_RM_WORD_REGISTER(rh);
542 DECODE_PRINTF(",");
543 shift = fetch_byte_imm();
544 DECODE_PRINTF2("%d\n", shift);
545 TRACE_AND_STEP();
546 *destreg = shld_word(*destreg,*shiftreg,shift);
548 break;
550 DECODE_CLEAR_SEGOVR();
551 END_OF_INSTR();
554 /****************************************************************************
555 REMARKS:
556 Handles opcode 0x0f,0xa5
557 ****************************************************************************/
558 void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
560 int mod, rl, rh;
561 uint destoffset;
563 START_OF_INSTR();
564 DECODE_PRINTF("SHLD\t");
565 FETCH_DECODE_MODRM(mod, rh, rl);
566 switch (mod) {
567 case 0:
568 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
569 u32 destval;
570 u32 *shiftreg;
572 destoffset = decode_rm00_address(rl);
573 DECODE_PRINTF(",");
574 shiftreg = DECODE_RM_LONG_REGISTER(rh);
575 DECODE_PRINTF(",CL\n");
576 TRACE_AND_STEP();
577 destval = fetch_data_long(destoffset);
578 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
579 store_data_long(destoffset, destval);
580 } else {
581 u16 destval;
582 u16 *shiftreg;
584 destoffset = decode_rm00_address(rl);
585 DECODE_PRINTF(",");
586 shiftreg = DECODE_RM_WORD_REGISTER(rh);
587 DECODE_PRINTF(",CL\n");
588 TRACE_AND_STEP();
589 destval = fetch_data_word(destoffset);
590 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
591 store_data_word(destoffset, destval);
593 break;
594 case 1:
595 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
596 u32 destval;
597 u32 *shiftreg;
599 destoffset = decode_rm01_address(rl);
600 DECODE_PRINTF(",");
601 shiftreg = DECODE_RM_LONG_REGISTER(rh);
602 DECODE_PRINTF(",CL\n");
603 TRACE_AND_STEP();
604 destval = fetch_data_long(destoffset);
605 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
606 store_data_long(destoffset, destval);
607 } else {
608 u16 destval;
609 u16 *shiftreg;
611 destoffset = decode_rm01_address(rl);
612 DECODE_PRINTF(",");
613 shiftreg = DECODE_RM_WORD_REGISTER(rh);
614 DECODE_PRINTF(",CL\n");
615 TRACE_AND_STEP();
616 destval = fetch_data_word(destoffset);
617 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
618 store_data_word(destoffset, destval);
620 break;
621 case 2:
622 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
623 u32 destval;
624 u32 *shiftreg;
626 destoffset = decode_rm10_address(rl);
627 DECODE_PRINTF(",");
628 shiftreg = DECODE_RM_LONG_REGISTER(rh);
629 DECODE_PRINTF(",CL\n");
630 TRACE_AND_STEP();
631 destval = fetch_data_long(destoffset);
632 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
633 store_data_long(destoffset, destval);
634 } else {
635 u16 destval;
636 u16 *shiftreg;
638 destoffset = decode_rm10_address(rl);
639 DECODE_PRINTF(",");
640 shiftreg = DECODE_RM_WORD_REGISTER(rh);
641 DECODE_PRINTF(",CL\n");
642 TRACE_AND_STEP();
643 destval = fetch_data_word(destoffset);
644 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
645 store_data_word(destoffset, destval);
647 break;
648 case 3: /* register to register */
649 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
650 u32 *destreg,*shiftreg;
652 destreg = DECODE_RM_LONG_REGISTER(rl);
653 DECODE_PRINTF(",");
654 shiftreg = DECODE_RM_LONG_REGISTER(rh);
655 DECODE_PRINTF(",CL\n");
656 TRACE_AND_STEP();
657 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
658 } else {
659 u16 *destreg,*shiftreg;
661 destreg = DECODE_RM_WORD_REGISTER(rl);
662 DECODE_PRINTF(",");
663 shiftreg = DECODE_RM_WORD_REGISTER(rh);
664 DECODE_PRINTF(",CL\n");
665 TRACE_AND_STEP();
666 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
668 break;
670 DECODE_CLEAR_SEGOVR();
671 END_OF_INSTR();
674 /****************************************************************************
675 REMARKS:
676 Handles opcode 0x0f,0xa8
677 ****************************************************************************/
678 void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
680 START_OF_INSTR();
681 DECODE_PRINTF("PUSH\tGS\n");
682 TRACE_AND_STEP();
683 push_word(M.x86.R_GS);
684 DECODE_CLEAR_SEGOVR();
685 END_OF_INSTR();
688 /****************************************************************************
689 REMARKS:
690 Handles opcode 0x0f,0xa9
691 ****************************************************************************/
692 void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
694 START_OF_INSTR();
695 DECODE_PRINTF("POP\tGS\n");
696 TRACE_AND_STEP();
697 M.x86.R_GS = pop_word();
698 DECODE_CLEAR_SEGOVR();
699 END_OF_INSTR();
702 /****************************************************************************
703 REMARKS:
704 Handles opcode 0x0f,0xaa
705 ****************************************************************************/
706 void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
708 int mod, rl, rh;
709 uint srcoffset;
710 int bit,disp;
712 START_OF_INSTR();
713 DECODE_PRINTF("BTS\t");
714 FETCH_DECODE_MODRM(mod, rh, rl);
715 switch (mod) {
716 case 0:
717 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
718 u32 srcval,mask;
719 u32 *shiftreg;
721 srcoffset = decode_rm00_address(rl);
722 DECODE_PRINTF(",");
723 shiftreg = DECODE_RM_LONG_REGISTER(rh);
724 TRACE_AND_STEP();
725 bit = *shiftreg & 0x1F;
726 disp = (s16)*shiftreg >> 5;
727 srcval = fetch_data_long(srcoffset+disp);
728 mask = (0x1 << bit);
729 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
730 store_data_long(srcoffset+disp, srcval | mask);
731 } else {
732 u16 srcval,mask;
733 u16 *shiftreg;
735 srcoffset = decode_rm00_address(rl);
736 DECODE_PRINTF(",");
737 shiftreg = DECODE_RM_WORD_REGISTER(rh);
738 TRACE_AND_STEP();
739 bit = *shiftreg & 0xF;
740 disp = (s16)*shiftreg >> 4;
741 srcval = fetch_data_word(srcoffset+disp);
742 mask = (u16)(0x1 << bit);
743 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
744 store_data_word(srcoffset+disp, srcval | mask);
746 break;
747 case 1:
748 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
749 u32 srcval,mask;
750 u32 *shiftreg;
752 srcoffset = decode_rm01_address(rl);
753 DECODE_PRINTF(",");
754 shiftreg = DECODE_RM_LONG_REGISTER(rh);
755 TRACE_AND_STEP();
756 bit = *shiftreg & 0x1F;
757 disp = (s16)*shiftreg >> 5;
758 srcval = fetch_data_long(srcoffset+disp);
759 mask = (0x1 << bit);
760 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
761 store_data_long(srcoffset+disp, srcval | mask);
762 } else {
763 u16 srcval,mask;
764 u16 *shiftreg;
766 srcoffset = decode_rm01_address(rl);
767 DECODE_PRINTF(",");
768 shiftreg = DECODE_RM_WORD_REGISTER(rh);
769 TRACE_AND_STEP();
770 bit = *shiftreg & 0xF;
771 disp = (s16)*shiftreg >> 4;
772 srcval = fetch_data_word(srcoffset+disp);
773 mask = (u16)(0x1 << bit);
774 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
775 store_data_word(srcoffset+disp, srcval | mask);
777 break;
778 case 2:
779 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
780 u32 srcval,mask;
781 u32 *shiftreg;
783 srcoffset = decode_rm10_address(rl);
784 DECODE_PRINTF(",");
785 shiftreg = DECODE_RM_LONG_REGISTER(rh);
786 TRACE_AND_STEP();
787 bit = *shiftreg & 0x1F;
788 disp = (s16)*shiftreg >> 5;
789 srcval = fetch_data_long(srcoffset+disp);
790 mask = (0x1 << bit);
791 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
792 store_data_long(srcoffset+disp, srcval | mask);
793 } else {
794 u16 srcval,mask;
795 u16 *shiftreg;
797 srcoffset = decode_rm10_address(rl);
798 DECODE_PRINTF(",");
799 shiftreg = DECODE_RM_WORD_REGISTER(rh);
800 TRACE_AND_STEP();
801 bit = *shiftreg & 0xF;
802 disp = (s16)*shiftreg >> 4;
803 srcval = fetch_data_word(srcoffset+disp);
804 mask = (u16)(0x1 << bit);
805 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
806 store_data_word(srcoffset+disp, srcval | mask);
808 break;
809 case 3: /* register to register */
810 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
811 u32 *srcreg,*shiftreg;
812 u32 mask;
814 srcreg = DECODE_RM_LONG_REGISTER(rl);
815 DECODE_PRINTF(",");
816 shiftreg = DECODE_RM_LONG_REGISTER(rh);
817 TRACE_AND_STEP();
818 bit = *shiftreg & 0x1F;
819 mask = (0x1 << bit);
820 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
821 *srcreg |= mask;
822 } else {
823 u16 *srcreg,*shiftreg;
824 u16 mask;
826 srcreg = DECODE_RM_WORD_REGISTER(rl);
827 DECODE_PRINTF(",");
828 shiftreg = DECODE_RM_WORD_REGISTER(rh);
829 TRACE_AND_STEP();
830 bit = *shiftreg & 0xF;
831 mask = (u16)(0x1 << bit);
832 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
833 *srcreg |= mask;
835 break;
837 DECODE_CLEAR_SEGOVR();
838 END_OF_INSTR();
841 /****************************************************************************
842 REMARKS:
843 Handles opcode 0x0f,0xac
844 ****************************************************************************/
845 void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
847 int mod, rl, rh;
848 uint destoffset;
849 u8 shift;
851 START_OF_INSTR();
852 DECODE_PRINTF("SHLD\t");
853 FETCH_DECODE_MODRM(mod, rh, rl);
854 switch (mod) {
855 case 0:
856 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
857 u32 destval;
858 u32 *shiftreg;
860 destoffset = decode_rm00_address(rl);
861 DECODE_PRINTF(",");
862 shiftreg = DECODE_RM_LONG_REGISTER(rh);
863 DECODE_PRINTF(",");
864 shift = fetch_byte_imm();
865 DECODE_PRINTF2("%d\n", shift);
866 TRACE_AND_STEP();
867 destval = fetch_data_long(destoffset);
868 destval = shrd_long(destval,*shiftreg,shift);
869 store_data_long(destoffset, destval);
870 } else {
871 u16 destval;
872 u16 *shiftreg;
874 destoffset = decode_rm00_address(rl);
875 DECODE_PRINTF(",");
876 shiftreg = DECODE_RM_WORD_REGISTER(rh);
877 DECODE_PRINTF(",");
878 shift = fetch_byte_imm();
879 DECODE_PRINTF2("%d\n", shift);
880 TRACE_AND_STEP();
881 destval = fetch_data_word(destoffset);
882 destval = shrd_word(destval,*shiftreg,shift);
883 store_data_word(destoffset, destval);
885 break;
886 case 1:
887 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
888 u32 destval;
889 u32 *shiftreg;
891 destoffset = decode_rm01_address(rl);
892 DECODE_PRINTF(",");
893 shiftreg = DECODE_RM_LONG_REGISTER(rh);
894 DECODE_PRINTF(",");
895 shift = fetch_byte_imm();
896 DECODE_PRINTF2("%d\n", shift);
897 TRACE_AND_STEP();
898 destval = fetch_data_long(destoffset);
899 destval = shrd_long(destval,*shiftreg,shift);
900 store_data_long(destoffset, destval);
901 } else {
902 u16 destval;
903 u16 *shiftreg;
905 destoffset = decode_rm01_address(rl);
906 DECODE_PRINTF(",");
907 shiftreg = DECODE_RM_WORD_REGISTER(rh);
908 DECODE_PRINTF(",");
909 shift = fetch_byte_imm();
910 DECODE_PRINTF2("%d\n", shift);
911 TRACE_AND_STEP();
912 destval = fetch_data_word(destoffset);
913 destval = shrd_word(destval,*shiftreg,shift);
914 store_data_word(destoffset, destval);
916 break;
917 case 2:
918 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
919 u32 destval;
920 u32 *shiftreg;
922 destoffset = decode_rm10_address(rl);
923 DECODE_PRINTF(",");
924 shiftreg = DECODE_RM_LONG_REGISTER(rh);
925 DECODE_PRINTF(",");
926 shift = fetch_byte_imm();
927 DECODE_PRINTF2("%d\n", shift);
928 TRACE_AND_STEP();
929 destval = fetch_data_long(destoffset);
930 destval = shrd_long(destval,*shiftreg,shift);
931 store_data_long(destoffset, destval);
932 } else {
933 u16 destval;
934 u16 *shiftreg;
936 destoffset = decode_rm10_address(rl);
937 DECODE_PRINTF(",");
938 shiftreg = DECODE_RM_WORD_REGISTER(rh);
939 DECODE_PRINTF(",");
940 shift = fetch_byte_imm();
941 DECODE_PRINTF2("%d\n", shift);
942 TRACE_AND_STEP();
943 destval = fetch_data_word(destoffset);
944 destval = shrd_word(destval,*shiftreg,shift);
945 store_data_word(destoffset, destval);
947 break;
948 case 3: /* register to register */
949 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
950 u32 *destreg,*shiftreg;
952 destreg = DECODE_RM_LONG_REGISTER(rl);
953 DECODE_PRINTF(",");
954 shiftreg = DECODE_RM_LONG_REGISTER(rh);
955 DECODE_PRINTF(",");
956 shift = fetch_byte_imm();
957 DECODE_PRINTF2("%d\n", shift);
958 TRACE_AND_STEP();
959 *destreg = shrd_long(*destreg,*shiftreg,shift);
960 } else {
961 u16 *destreg,*shiftreg;
963 destreg = DECODE_RM_WORD_REGISTER(rl);
964 DECODE_PRINTF(",");
965 shiftreg = DECODE_RM_WORD_REGISTER(rh);
966 DECODE_PRINTF(",");
967 shift = fetch_byte_imm();
968 DECODE_PRINTF2("%d\n", shift);
969 TRACE_AND_STEP();
970 *destreg = shrd_word(*destreg,*shiftreg,shift);
972 break;
974 DECODE_CLEAR_SEGOVR();
975 END_OF_INSTR();
978 /****************************************************************************
979 REMARKS:
980 Handles opcode 0x0f,0xad
981 ****************************************************************************/
982 void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
984 int mod, rl, rh;
985 uint destoffset;
987 START_OF_INSTR();
988 DECODE_PRINTF("SHLD\t");
989 FETCH_DECODE_MODRM(mod, rh, rl);
990 switch (mod) {
991 case 0:
992 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
993 u32 destval;
994 u32 *shiftreg;
996 destoffset = decode_rm00_address(rl);
997 DECODE_PRINTF(",");
998 shiftreg = DECODE_RM_LONG_REGISTER(rh);
999 DECODE_PRINTF(",CL\n");
1000 TRACE_AND_STEP();
1001 destval = fetch_data_long(destoffset);
1002 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1003 store_data_long(destoffset, destval);
1004 } else {
1005 u16 destval;
1006 u16 *shiftreg;
1008 destoffset = decode_rm00_address(rl);
1009 DECODE_PRINTF(",");
1010 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1011 DECODE_PRINTF(",CL\n");
1012 TRACE_AND_STEP();
1013 destval = fetch_data_word(destoffset);
1014 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1015 store_data_word(destoffset, destval);
1017 break;
1018 case 1:
1019 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1020 u32 destval;
1021 u32 *shiftreg;
1023 destoffset = decode_rm01_address(rl);
1024 DECODE_PRINTF(",");
1025 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1026 DECODE_PRINTF(",CL\n");
1027 TRACE_AND_STEP();
1028 destval = fetch_data_long(destoffset);
1029 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1030 store_data_long(destoffset, destval);
1031 } else {
1032 u16 destval;
1033 u16 *shiftreg;
1035 destoffset = decode_rm01_address(rl);
1036 DECODE_PRINTF(",");
1037 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1038 DECODE_PRINTF(",CL\n");
1039 TRACE_AND_STEP();
1040 destval = fetch_data_word(destoffset);
1041 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1042 store_data_word(destoffset, destval);
1044 break;
1045 case 2:
1046 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1047 u32 destval;
1048 u32 *shiftreg;
1050 destoffset = decode_rm10_address(rl);
1051 DECODE_PRINTF(",");
1052 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1053 DECODE_PRINTF(",CL\n");
1054 TRACE_AND_STEP();
1055 destval = fetch_data_long(destoffset);
1056 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1057 store_data_long(destoffset, destval);
1058 } else {
1059 u16 destval;
1060 u16 *shiftreg;
1062 destoffset = decode_rm10_address(rl);
1063 DECODE_PRINTF(",");
1064 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1065 DECODE_PRINTF(",CL\n");
1066 TRACE_AND_STEP();
1067 destval = fetch_data_word(destoffset);
1068 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1069 store_data_word(destoffset, destval);
1071 break;
1072 case 3: /* register to register */
1073 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1074 u32 *destreg,*shiftreg;
1076 destreg = DECODE_RM_LONG_REGISTER(rl);
1077 DECODE_PRINTF(",");
1078 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1079 DECODE_PRINTF(",CL\n");
1080 TRACE_AND_STEP();
1081 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
1082 } else {
1083 u16 *destreg,*shiftreg;
1085 destreg = DECODE_RM_WORD_REGISTER(rl);
1086 DECODE_PRINTF(",");
1087 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1088 DECODE_PRINTF(",CL\n");
1089 TRACE_AND_STEP();
1090 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
1092 break;
1094 DECODE_CLEAR_SEGOVR();
1095 END_OF_INSTR();
1098 /****************************************************************************
1099 REMARKS:
1100 Handles opcode 0x0f,0xaf
1101 ****************************************************************************/
1102 void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
1104 int mod, rl, rh;
1105 uint srcoffset;
1107 START_OF_INSTR();
1108 DECODE_PRINTF("IMUL\t");
1109 FETCH_DECODE_MODRM(mod, rh, rl);
1110 switch (mod) {
1111 case 0:
1112 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1113 u32 *destreg;
1114 u32 srcval;
1115 u32 res_lo,res_hi;
1117 destreg = DECODE_RM_LONG_REGISTER(rh);
1118 DECODE_PRINTF(",");
1119 srcoffset = decode_rm00_address(rl);
1120 srcval = fetch_data_long(srcoffset);
1121 TRACE_AND_STEP();
1122 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1123 if (res_hi != 0) {
1124 SET_FLAG(F_CF);
1125 SET_FLAG(F_OF);
1126 } else {
1127 CLEAR_FLAG(F_CF);
1128 CLEAR_FLAG(F_OF);
1130 *destreg = (u32)res_lo;
1131 } else {
1132 u16 *destreg;
1133 u16 srcval;
1134 u32 res;
1136 destreg = DECODE_RM_WORD_REGISTER(rh);
1137 DECODE_PRINTF(",");
1138 srcoffset = decode_rm00_address(rl);
1139 srcval = fetch_data_word(srcoffset);
1140 TRACE_AND_STEP();
1141 res = (s16)*destreg * (s16)srcval;
1142 if (res > 0xFFFF) {
1143 SET_FLAG(F_CF);
1144 SET_FLAG(F_OF);
1145 } else {
1146 CLEAR_FLAG(F_CF);
1147 CLEAR_FLAG(F_OF);
1149 *destreg = (u16)res;
1151 break;
1152 case 1:
1153 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1154 u32 *destreg;
1155 u32 srcval;
1156 u32 res_lo,res_hi;
1158 destreg = DECODE_RM_LONG_REGISTER(rh);
1159 DECODE_PRINTF(",");
1160 srcoffset = decode_rm01_address(rl);
1161 srcval = fetch_data_long(srcoffset);
1162 TRACE_AND_STEP();
1163 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1164 if (res_hi != 0) {
1165 SET_FLAG(F_CF);
1166 SET_FLAG(F_OF);
1167 } else {
1168 CLEAR_FLAG(F_CF);
1169 CLEAR_FLAG(F_OF);
1171 *destreg = (u32)res_lo;
1172 } else {
1173 u16 *destreg;
1174 u16 srcval;
1175 u32 res;
1177 destreg = DECODE_RM_WORD_REGISTER(rh);
1178 DECODE_PRINTF(",");
1179 srcoffset = decode_rm01_address(rl);
1180 srcval = fetch_data_word(srcoffset);
1181 TRACE_AND_STEP();
1182 res = (s16)*destreg * (s16)srcval;
1183 if (res > 0xFFFF) {
1184 SET_FLAG(F_CF);
1185 SET_FLAG(F_OF);
1186 } else {
1187 CLEAR_FLAG(F_CF);
1188 CLEAR_FLAG(F_OF);
1190 *destreg = (u16)res;
1192 break;
1193 case 2:
1194 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1195 u32 *destreg;
1196 u32 srcval;
1197 u32 res_lo,res_hi;
1199 destreg = DECODE_RM_LONG_REGISTER(rh);
1200 DECODE_PRINTF(",");
1201 srcoffset = decode_rm10_address(rl);
1202 srcval = fetch_data_long(srcoffset);
1203 TRACE_AND_STEP();
1204 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1205 if (res_hi != 0) {
1206 SET_FLAG(F_CF);
1207 SET_FLAG(F_OF);
1208 } else {
1209 CLEAR_FLAG(F_CF);
1210 CLEAR_FLAG(F_OF);
1212 *destreg = (u32)res_lo;
1213 } else {
1214 u16 *destreg;
1215 u16 srcval;
1216 u32 res;
1218 destreg = DECODE_RM_WORD_REGISTER(rh);
1219 DECODE_PRINTF(",");
1220 srcoffset = decode_rm10_address(rl);
1221 srcval = fetch_data_word(srcoffset);
1222 TRACE_AND_STEP();
1223 res = (s16)*destreg * (s16)srcval;
1224 if (res > 0xFFFF) {
1225 SET_FLAG(F_CF);
1226 SET_FLAG(F_OF);
1227 } else {
1228 CLEAR_FLAG(F_CF);
1229 CLEAR_FLAG(F_OF);
1231 *destreg = (u16)res;
1233 break;
1234 case 3: /* register to register */
1235 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1236 u32 *destreg,*srcreg;
1237 u32 res_lo,res_hi;
1239 destreg = DECODE_RM_LONG_REGISTER(rh);
1240 DECODE_PRINTF(",");
1241 srcreg = DECODE_RM_LONG_REGISTER(rl);
1242 TRACE_AND_STEP();
1243 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
1244 if (res_hi != 0) {
1245 SET_FLAG(F_CF);
1246 SET_FLAG(F_OF);
1247 } else {
1248 CLEAR_FLAG(F_CF);
1249 CLEAR_FLAG(F_OF);
1251 *destreg = (u32)res_lo;
1252 } else {
1253 u16 *destreg,*srcreg;
1254 u32 res;
1256 destreg = DECODE_RM_WORD_REGISTER(rh);
1257 DECODE_PRINTF(",");
1258 srcreg = DECODE_RM_WORD_REGISTER(rl);
1259 res = (s16)*destreg * (s16)*srcreg;
1260 if (res > 0xFFFF) {
1261 SET_FLAG(F_CF);
1262 SET_FLAG(F_OF);
1263 } else {
1264 CLEAR_FLAG(F_CF);
1265 CLEAR_FLAG(F_OF);
1267 *destreg = (u16)res;
1269 break;
1271 DECODE_CLEAR_SEGOVR();
1272 END_OF_INSTR();
1275 /****************************************************************************
1276 REMARKS:
1277 Handles opcode 0x0f,0xb2
1278 ****************************************************************************/
1279 void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
1281 int mod, rh, rl;
1282 u16 *dstreg;
1283 uint srcoffset;
1285 START_OF_INSTR();
1286 DECODE_PRINTF("LSS\t");
1287 FETCH_DECODE_MODRM(mod, rh, rl);
1288 switch (mod) {
1289 case 0:
1290 dstreg = DECODE_RM_WORD_REGISTER(rh);
1291 DECODE_PRINTF(",");
1292 srcoffset = decode_rm00_address(rl);
1293 DECODE_PRINTF("\n");
1294 TRACE_AND_STEP();
1295 *dstreg = fetch_data_word(srcoffset);
1296 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1297 break;
1298 case 1:
1299 dstreg = DECODE_RM_WORD_REGISTER(rh);
1300 DECODE_PRINTF(",");
1301 srcoffset = decode_rm01_address(rl);
1302 DECODE_PRINTF("\n");
1303 TRACE_AND_STEP();
1304 *dstreg = fetch_data_word(srcoffset);
1305 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1306 break;
1307 case 2:
1308 dstreg = DECODE_RM_WORD_REGISTER(rh);
1309 DECODE_PRINTF(",");
1310 srcoffset = decode_rm10_address(rl);
1311 DECODE_PRINTF("\n");
1312 TRACE_AND_STEP();
1313 *dstreg = fetch_data_word(srcoffset);
1314 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1315 break;
1316 case 3: /* register to register */
1317 /* UNDEFINED! */
1318 TRACE_AND_STEP();
1320 DECODE_CLEAR_SEGOVR();
1321 END_OF_INSTR();
1324 /****************************************************************************
1325 REMARKS:
1326 Handles opcode 0x0f,0xb3
1327 ****************************************************************************/
1328 void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
1330 int mod, rl, rh;
1331 uint srcoffset;
1332 int bit,disp;
1334 START_OF_INSTR();
1335 DECODE_PRINTF("BTR\t");
1336 FETCH_DECODE_MODRM(mod, rh, rl);
1337 switch (mod) {
1338 case 0:
1339 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1340 u32 srcval,mask;
1341 u32 *shiftreg;
1343 srcoffset = decode_rm00_address(rl);
1344 DECODE_PRINTF(",");
1345 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1346 TRACE_AND_STEP();
1347 bit = *shiftreg & 0x1F;
1348 disp = (s16)*shiftreg >> 5;
1349 srcval = fetch_data_long(srcoffset+disp);
1350 mask = (0x1 << bit);
1351 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1352 store_data_long(srcoffset+disp, srcval & ~mask);
1353 } else {
1354 u16 srcval,mask;
1355 u16 *shiftreg;
1357 srcoffset = decode_rm00_address(rl);
1358 DECODE_PRINTF(",");
1359 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1360 TRACE_AND_STEP();
1361 bit = *shiftreg & 0xF;
1362 disp = (s16)*shiftreg >> 4;
1363 srcval = fetch_data_word(srcoffset+disp);
1364 mask = (u16)(0x1 << bit);
1365 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1366 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1368 break;
1369 case 1:
1370 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1371 u32 srcval,mask;
1372 u32 *shiftreg;
1374 srcoffset = decode_rm01_address(rl);
1375 DECODE_PRINTF(",");
1376 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1377 TRACE_AND_STEP();
1378 bit = *shiftreg & 0x1F;
1379 disp = (s16)*shiftreg >> 5;
1380 srcval = fetch_data_long(srcoffset+disp);
1381 mask = (0x1 << bit);
1382 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1383 store_data_long(srcoffset+disp, srcval & ~mask);
1384 } else {
1385 u16 srcval,mask;
1386 u16 *shiftreg;
1388 srcoffset = decode_rm01_address(rl);
1389 DECODE_PRINTF(",");
1390 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1391 TRACE_AND_STEP();
1392 bit = *shiftreg & 0xF;
1393 disp = (s16)*shiftreg >> 4;
1394 srcval = fetch_data_word(srcoffset+disp);
1395 mask = (u16)(0x1 << bit);
1396 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1397 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1399 break;
1400 case 2:
1401 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1402 u32 srcval,mask;
1403 u32 *shiftreg;
1405 srcoffset = decode_rm10_address(rl);
1406 DECODE_PRINTF(",");
1407 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1408 TRACE_AND_STEP();
1409 bit = *shiftreg & 0x1F;
1410 disp = (s16)*shiftreg >> 5;
1411 srcval = fetch_data_long(srcoffset+disp);
1412 mask = (0x1 << bit);
1413 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1414 store_data_long(srcoffset+disp, srcval & ~mask);
1415 } else {
1416 u16 srcval,mask;
1417 u16 *shiftreg;
1419 srcoffset = decode_rm10_address(rl);
1420 DECODE_PRINTF(",");
1421 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1422 TRACE_AND_STEP();
1423 bit = *shiftreg & 0xF;
1424 disp = (s16)*shiftreg >> 4;
1425 srcval = fetch_data_word(srcoffset+disp);
1426 mask = (u16)(0x1 << bit);
1427 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1428 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1430 break;
1431 case 3: /* register to register */
1432 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1433 u32 *srcreg,*shiftreg;
1434 u32 mask;
1436 srcreg = DECODE_RM_LONG_REGISTER(rl);
1437 DECODE_PRINTF(",");
1438 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1439 TRACE_AND_STEP();
1440 bit = *shiftreg & 0x1F;
1441 mask = (0x1 << bit);
1442 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1443 *srcreg &= ~mask;
1444 } else {
1445 u16 *srcreg,*shiftreg;
1446 u16 mask;
1448 srcreg = DECODE_RM_WORD_REGISTER(rl);
1449 DECODE_PRINTF(",");
1450 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1451 TRACE_AND_STEP();
1452 bit = *shiftreg & 0xF;
1453 mask = (u16)(0x1 << bit);
1454 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1455 *srcreg &= ~mask;
1457 break;
1459 DECODE_CLEAR_SEGOVR();
1460 END_OF_INSTR();
1463 /****************************************************************************
1464 REMARKS:
1465 Handles opcode 0x0f,0xb4
1466 ****************************************************************************/
1467 void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
1469 int mod, rh, rl;
1470 u16 *dstreg;
1471 uint srcoffset;
1473 START_OF_INSTR();
1474 DECODE_PRINTF("LFS\t");
1475 FETCH_DECODE_MODRM(mod, rh, rl);
1476 switch (mod) {
1477 case 0:
1478 dstreg = DECODE_RM_WORD_REGISTER(rh);
1479 DECODE_PRINTF(",");
1480 srcoffset = decode_rm00_address(rl);
1481 DECODE_PRINTF("\n");
1482 TRACE_AND_STEP();
1483 *dstreg = fetch_data_word(srcoffset);
1484 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1485 break;
1486 case 1:
1487 dstreg = DECODE_RM_WORD_REGISTER(rh);
1488 DECODE_PRINTF(",");
1489 srcoffset = decode_rm01_address(rl);
1490 DECODE_PRINTF("\n");
1491 TRACE_AND_STEP();
1492 *dstreg = fetch_data_word(srcoffset);
1493 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1494 break;
1495 case 2:
1496 dstreg = DECODE_RM_WORD_REGISTER(rh);
1497 DECODE_PRINTF(",");
1498 srcoffset = decode_rm10_address(rl);
1499 DECODE_PRINTF("\n");
1500 TRACE_AND_STEP();
1501 *dstreg = fetch_data_word(srcoffset);
1502 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1503 break;
1504 case 3: /* register to register */
1505 /* UNDEFINED! */
1506 TRACE_AND_STEP();
1508 DECODE_CLEAR_SEGOVR();
1509 END_OF_INSTR();
1512 /****************************************************************************
1513 REMARKS:
1514 Handles opcode 0x0f,0xb5
1515 ****************************************************************************/
1516 void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
1518 int mod, rh, rl;
1519 u16 *dstreg;
1520 uint srcoffset;
1522 START_OF_INSTR();
1523 DECODE_PRINTF("LGS\t");
1524 FETCH_DECODE_MODRM(mod, rh, rl);
1525 switch (mod) {
1526 case 0:
1527 dstreg = DECODE_RM_WORD_REGISTER(rh);
1528 DECODE_PRINTF(",");
1529 srcoffset = decode_rm00_address(rl);
1530 DECODE_PRINTF("\n");
1531 TRACE_AND_STEP();
1532 *dstreg = fetch_data_word(srcoffset);
1533 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1534 break;
1535 case 1:
1536 dstreg = DECODE_RM_WORD_REGISTER(rh);
1537 DECODE_PRINTF(",");
1538 srcoffset = decode_rm01_address(rl);
1539 DECODE_PRINTF("\n");
1540 TRACE_AND_STEP();
1541 *dstreg = fetch_data_word(srcoffset);
1542 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1543 break;
1544 case 2:
1545 dstreg = DECODE_RM_WORD_REGISTER(rh);
1546 DECODE_PRINTF(",");
1547 srcoffset = decode_rm10_address(rl);
1548 DECODE_PRINTF("\n");
1549 TRACE_AND_STEP();
1550 *dstreg = fetch_data_word(srcoffset);
1551 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1552 break;
1553 case 3: /* register to register */
1554 /* UNDEFINED! */
1555 TRACE_AND_STEP();
1557 DECODE_CLEAR_SEGOVR();
1558 END_OF_INSTR();
1561 /****************************************************************************
1562 REMARKS:
1563 Handles opcode 0x0f,0xb6
1564 ****************************************************************************/
1565 void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1567 int mod, rl, rh;
1568 uint srcoffset;
1570 START_OF_INSTR();
1571 DECODE_PRINTF("MOVZX\t");
1572 FETCH_DECODE_MODRM(mod, rh, rl);
1573 switch (mod) {
1574 case 0:
1575 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1576 u32 *destreg;
1577 u32 srcval;
1579 destreg = DECODE_RM_LONG_REGISTER(rh);
1580 DECODE_PRINTF(",");
1581 srcoffset = decode_rm00_address(rl);
1582 srcval = fetch_data_byte(srcoffset);
1583 DECODE_PRINTF("\n");
1584 TRACE_AND_STEP();
1585 *destreg = srcval;
1586 } else {
1587 u16 *destreg;
1588 u16 srcval;
1590 destreg = DECODE_RM_WORD_REGISTER(rh);
1591 DECODE_PRINTF(",");
1592 srcoffset = decode_rm00_address(rl);
1593 srcval = fetch_data_byte(srcoffset);
1594 DECODE_PRINTF("\n");
1595 TRACE_AND_STEP();
1596 *destreg = srcval;
1598 break;
1599 case 1:
1600 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1601 u32 *destreg;
1602 u32 srcval;
1604 destreg = DECODE_RM_LONG_REGISTER(rh);
1605 DECODE_PRINTF(",");
1606 srcoffset = decode_rm01_address(rl);
1607 srcval = fetch_data_byte(srcoffset);
1608 DECODE_PRINTF("\n");
1609 TRACE_AND_STEP();
1610 *destreg = srcval;
1611 } else {
1612 u16 *destreg;
1613 u16 srcval;
1615 destreg = DECODE_RM_WORD_REGISTER(rh);
1616 DECODE_PRINTF(",");
1617 srcoffset = decode_rm01_address(rl);
1618 srcval = fetch_data_byte(srcoffset);
1619 DECODE_PRINTF("\n");
1620 TRACE_AND_STEP();
1621 *destreg = srcval;
1623 break;
1624 case 2:
1625 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1626 u32 *destreg;
1627 u32 srcval;
1629 destreg = DECODE_RM_LONG_REGISTER(rh);
1630 DECODE_PRINTF(",");
1631 srcoffset = decode_rm10_address(rl);
1632 srcval = fetch_data_byte(srcoffset);
1633 DECODE_PRINTF("\n");
1634 TRACE_AND_STEP();
1635 *destreg = srcval;
1636 } else {
1637 u16 *destreg;
1638 u16 srcval;
1640 destreg = DECODE_RM_WORD_REGISTER(rh);
1641 DECODE_PRINTF(",");
1642 srcoffset = decode_rm10_address(rl);
1643 srcval = fetch_data_byte(srcoffset);
1644 DECODE_PRINTF("\n");
1645 TRACE_AND_STEP();
1646 *destreg = srcval;
1648 break;
1649 case 3: /* register to register */
1650 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1651 u32 *destreg;
1652 u8 *srcreg;
1654 destreg = DECODE_RM_LONG_REGISTER(rh);
1655 DECODE_PRINTF(",");
1656 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1657 DECODE_PRINTF("\n");
1658 TRACE_AND_STEP();
1659 *destreg = *srcreg;
1660 } else {
1661 u16 *destreg;
1662 u8 *srcreg;
1664 destreg = DECODE_RM_WORD_REGISTER(rh);
1665 DECODE_PRINTF(",");
1666 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1667 DECODE_PRINTF("\n");
1668 TRACE_AND_STEP();
1669 *destreg = *srcreg;
1671 break;
1673 DECODE_CLEAR_SEGOVR();
1674 END_OF_INSTR();
1677 /****************************************************************************
1678 REMARKS:
1679 Handles opcode 0x0f,0xb7
1680 ****************************************************************************/
1681 void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1683 int mod, rl, rh;
1684 uint srcoffset;
1685 u32 *destreg;
1686 u32 srcval;
1687 u16 *srcreg;
1689 START_OF_INSTR();
1690 DECODE_PRINTF("MOVZX\t");
1691 FETCH_DECODE_MODRM(mod, rh, rl);
1692 switch (mod) {
1693 case 0:
1694 destreg = DECODE_RM_LONG_REGISTER(rh);
1695 DECODE_PRINTF(",");
1696 srcoffset = decode_rm00_address(rl);
1697 srcval = fetch_data_word(srcoffset);
1698 DECODE_PRINTF("\n");
1699 TRACE_AND_STEP();
1700 *destreg = srcval;
1701 break;
1702 case 1:
1703 destreg = DECODE_RM_LONG_REGISTER(rh);
1704 DECODE_PRINTF(",");
1705 srcoffset = decode_rm01_address(rl);
1706 srcval = fetch_data_word(srcoffset);
1707 DECODE_PRINTF("\n");
1708 TRACE_AND_STEP();
1709 *destreg = srcval;
1710 break;
1711 case 2:
1712 destreg = DECODE_RM_LONG_REGISTER(rh);
1713 DECODE_PRINTF(",");
1714 srcoffset = decode_rm10_address(rl);
1715 srcval = fetch_data_word(srcoffset);
1716 DECODE_PRINTF("\n");
1717 TRACE_AND_STEP();
1718 *destreg = srcval;
1719 break;
1720 case 3: /* register to register */
1721 destreg = DECODE_RM_LONG_REGISTER(rh);
1722 DECODE_PRINTF(",");
1723 srcreg = DECODE_RM_WORD_REGISTER(rl);
1724 DECODE_PRINTF("\n");
1725 TRACE_AND_STEP();
1726 *destreg = *srcreg;
1727 break;
1729 DECODE_CLEAR_SEGOVR();
1730 END_OF_INSTR();
1733 /****************************************************************************
1734 REMARKS:
1735 Handles opcode 0x0f,0xba
1736 ****************************************************************************/
1737 void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1739 int mod, rl, rh;
1740 uint srcoffset;
1741 int bit;
1743 START_OF_INSTR();
1744 FETCH_DECODE_MODRM(mod, rh, rl);
1745 switch (rh) {
1746 case 3:
1747 DECODE_PRINTF("BT\t");
1748 break;
1749 case 4:
1750 DECODE_PRINTF("BTS\t");
1751 break;
1752 case 5:
1753 DECODE_PRINTF("BTR\t");
1754 break;
1755 case 6:
1756 DECODE_PRINTF("BTC\t");
1757 break;
1758 default:
1759 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1760 TRACE_REGS();
1761 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1762 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1763 HALT_SYS();
1765 switch (mod) {
1766 case 0:
1767 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1768 u32 srcval, mask;
1769 u8 shift;
1771 srcoffset = decode_rm00_address(rl);
1772 DECODE_PRINTF(",");
1773 shift = fetch_byte_imm();
1774 TRACE_AND_STEP();
1775 bit = shift & 0x1F;
1776 srcval = fetch_data_long(srcoffset);
1777 mask = (0x1 << bit);
1778 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1779 switch (rh) {
1780 case 4:
1781 store_data_long(srcoffset, srcval | mask);
1782 break;
1783 case 5:
1784 store_data_long(srcoffset, srcval & ~mask);
1785 break;
1786 case 6:
1787 store_data_long(srcoffset, srcval ^ mask);
1788 break;
1789 default:
1790 break;
1792 } else {
1793 u16 srcval, mask;
1794 u8 shift;
1796 srcoffset = decode_rm00_address(rl);
1797 DECODE_PRINTF(",");
1798 shift = fetch_byte_imm();
1799 TRACE_AND_STEP();
1800 bit = shift & 0xF;
1801 srcval = fetch_data_word(srcoffset);
1802 mask = (0x1 << bit);
1803 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1804 switch (rh) {
1805 case 4:
1806 store_data_word(srcoffset, srcval | mask);
1807 break;
1808 case 5:
1809 store_data_word(srcoffset, srcval & ~mask);
1810 break;
1811 case 6:
1812 store_data_word(srcoffset, srcval ^ mask);
1813 break;
1814 default:
1815 break;
1818 break;
1819 case 1:
1820 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1821 u32 srcval, mask;
1822 u8 shift;
1824 srcoffset = decode_rm01_address(rl);
1825 DECODE_PRINTF(",");
1826 shift = fetch_byte_imm();
1827 TRACE_AND_STEP();
1828 bit = shift & 0x1F;
1829 srcval = fetch_data_long(srcoffset);
1830 mask = (0x1 << bit);
1831 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1832 switch (rh) {
1833 case 4:
1834 store_data_long(srcoffset, srcval | mask);
1835 break;
1836 case 5:
1837 store_data_long(srcoffset, srcval & ~mask);
1838 break;
1839 case 6:
1840 store_data_long(srcoffset, srcval ^ mask);
1841 break;
1842 default:
1843 break;
1845 } else {
1846 u16 srcval, mask;
1847 u8 shift;
1849 srcoffset = decode_rm01_address(rl);
1850 DECODE_PRINTF(",");
1851 shift = fetch_byte_imm();
1852 TRACE_AND_STEP();
1853 bit = shift & 0xF;
1854 srcval = fetch_data_word(srcoffset);
1855 mask = (0x1 << bit);
1856 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1857 switch (rh) {
1858 case 4:
1859 store_data_word(srcoffset, srcval | mask);
1860 break;
1861 case 5:
1862 store_data_word(srcoffset, srcval & ~mask);
1863 break;
1864 case 6:
1865 store_data_word(srcoffset, srcval ^ mask);
1866 break;
1867 default:
1868 break;
1871 break;
1872 case 2:
1873 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1874 u32 srcval, mask;
1875 u8 shift;
1877 srcoffset = decode_rm10_address(rl);
1878 DECODE_PRINTF(",");
1879 shift = fetch_byte_imm();
1880 TRACE_AND_STEP();
1881 bit = shift & 0x1F;
1882 srcval = fetch_data_long(srcoffset);
1883 mask = (0x1 << bit);
1884 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1885 switch (rh) {
1886 case 4:
1887 store_data_long(srcoffset, srcval | mask);
1888 break;
1889 case 5:
1890 store_data_long(srcoffset, srcval & ~mask);
1891 break;
1892 case 6:
1893 store_data_long(srcoffset, srcval ^ mask);
1894 break;
1895 default:
1896 break;
1898 } else {
1899 u16 srcval, mask;
1900 u8 shift;
1902 srcoffset = decode_rm10_address(rl);
1903 DECODE_PRINTF(",");
1904 shift = fetch_byte_imm();
1905 TRACE_AND_STEP();
1906 bit = shift & 0xF;
1907 srcval = fetch_data_word(srcoffset);
1908 mask = (0x1 << bit);
1909 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1910 switch (rh) {
1911 case 4:
1912 store_data_word(srcoffset, srcval | mask);
1913 break;
1914 case 5:
1915 store_data_word(srcoffset, srcval & ~mask);
1916 break;
1917 case 6:
1918 store_data_word(srcoffset, srcval ^ mask);
1919 break;
1920 default:
1921 break;
1924 break;
1925 case 3: /* register to register */
1926 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1927 u32 *srcreg;
1928 u32 mask;
1929 u8 shift;
1931 srcreg = DECODE_RM_LONG_REGISTER(rl);
1932 DECODE_PRINTF(",");
1933 shift = fetch_byte_imm();
1934 TRACE_AND_STEP();
1935 bit = shift & 0x1F;
1936 mask = (0x1 << bit);
1937 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1938 switch (rh) {
1939 case 4:
1940 *srcreg |= mask;
1941 break;
1942 case 5:
1943 *srcreg &= ~mask;
1944 break;
1945 case 6:
1946 *srcreg ^= mask;
1947 break;
1948 default:
1949 break;
1951 } else {
1952 u16 *srcreg;
1953 u16 mask;
1954 u8 shift;
1956 srcreg = DECODE_RM_WORD_REGISTER(rl);
1957 DECODE_PRINTF(",");
1958 shift = fetch_byte_imm();
1959 TRACE_AND_STEP();
1960 bit = shift & 0xF;
1961 mask = (0x1 << bit);
1962 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1963 switch (rh) {
1964 case 4:
1965 *srcreg |= mask;
1966 break;
1967 case 5:
1968 *srcreg &= ~mask;
1969 break;
1970 case 6:
1971 *srcreg ^= mask;
1972 break;
1973 default:
1974 break;
1977 break;
1979 DECODE_CLEAR_SEGOVR();
1980 END_OF_INSTR();
1983 /****************************************************************************
1984 REMARKS:
1985 Handles opcode 0x0f,0xbb
1986 ****************************************************************************/
1987 void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
1989 int mod, rl, rh;
1990 uint srcoffset;
1991 int bit,disp;
1993 START_OF_INSTR();
1994 DECODE_PRINTF("BTC\t");
1995 FETCH_DECODE_MODRM(mod, rh, rl);
1996 switch (mod) {
1997 case 0:
1998 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1999 u32 srcval,mask;
2000 u32 *shiftreg;
2002 srcoffset = decode_rm00_address(rl);
2003 DECODE_PRINTF(",");
2004 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2005 TRACE_AND_STEP();
2006 bit = *shiftreg & 0x1F;
2007 disp = (s16)*shiftreg >> 5;
2008 srcval = fetch_data_long(srcoffset+disp);
2009 mask = (0x1 << bit);
2010 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2011 store_data_long(srcoffset+disp, srcval ^ mask);
2012 } else {
2013 u16 srcval,mask;
2014 u16 *shiftreg;
2016 srcoffset = decode_rm00_address(rl);
2017 DECODE_PRINTF(",");
2018 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2019 TRACE_AND_STEP();
2020 bit = *shiftreg & 0xF;
2021 disp = (s16)*shiftreg >> 4;
2022 srcval = fetch_data_word(srcoffset+disp);
2023 mask = (u16)(0x1 << bit);
2024 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2025 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2027 break;
2028 case 1:
2029 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2030 u32 srcval,mask;
2031 u32 *shiftreg;
2033 srcoffset = decode_rm01_address(rl);
2034 DECODE_PRINTF(",");
2035 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2036 TRACE_AND_STEP();
2037 bit = *shiftreg & 0x1F;
2038 disp = (s16)*shiftreg >> 5;
2039 srcval = fetch_data_long(srcoffset+disp);
2040 mask = (0x1 << bit);
2041 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2042 store_data_long(srcoffset+disp, srcval ^ mask);
2043 } else {
2044 u16 srcval,mask;
2045 u16 *shiftreg;
2047 srcoffset = decode_rm01_address(rl);
2048 DECODE_PRINTF(",");
2049 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2050 TRACE_AND_STEP();
2051 bit = *shiftreg & 0xF;
2052 disp = (s16)*shiftreg >> 4;
2053 srcval = fetch_data_word(srcoffset+disp);
2054 mask = (u16)(0x1 << bit);
2055 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2056 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2058 break;
2059 case 2:
2060 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2061 u32 srcval,mask;
2062 u32 *shiftreg;
2064 srcoffset = decode_rm10_address(rl);
2065 DECODE_PRINTF(",");
2066 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2067 TRACE_AND_STEP();
2068 bit = *shiftreg & 0x1F;
2069 disp = (s16)*shiftreg >> 5;
2070 srcval = fetch_data_long(srcoffset+disp);
2071 mask = (0x1 << bit);
2072 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2073 store_data_long(srcoffset+disp, srcval ^ mask);
2074 } else {
2075 u16 srcval,mask;
2076 u16 *shiftreg;
2078 srcoffset = decode_rm10_address(rl);
2079 DECODE_PRINTF(",");
2080 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2081 TRACE_AND_STEP();
2082 bit = *shiftreg & 0xF;
2083 disp = (s16)*shiftreg >> 4;
2084 srcval = fetch_data_word(srcoffset+disp);
2085 mask = (u16)(0x1 << bit);
2086 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2087 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2089 break;
2090 case 3: /* register to register */
2091 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2092 u32 *srcreg,*shiftreg;
2093 u32 mask;
2095 srcreg = DECODE_RM_LONG_REGISTER(rl);
2096 DECODE_PRINTF(",");
2097 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2098 TRACE_AND_STEP();
2099 bit = *shiftreg & 0x1F;
2100 mask = (0x1 << bit);
2101 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2102 *srcreg ^= mask;
2103 } else {
2104 u16 *srcreg,*shiftreg;
2105 u16 mask;
2107 srcreg = DECODE_RM_WORD_REGISTER(rl);
2108 DECODE_PRINTF(",");
2109 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2110 TRACE_AND_STEP();
2111 bit = *shiftreg & 0xF;
2112 mask = (u16)(0x1 << bit);
2113 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2114 *srcreg ^= mask;
2116 break;
2118 DECODE_CLEAR_SEGOVR();
2119 END_OF_INSTR();
2122 /****************************************************************************
2123 REMARKS:
2124 Handles opcode 0x0f,0xbc
2125 ****************************************************************************/
2126 void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
2128 int mod, rl, rh;
2129 uint srcoffset;
2131 START_OF_INSTR();
2132 DECODE_PRINTF("BSF\n");
2133 FETCH_DECODE_MODRM(mod, rh, rl);
2134 switch(mod) {
2135 case 0:
2136 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2137 u32 srcval, *dstreg;
2139 srcoffset = decode_rm00_address(rl);
2140 DECODE_PRINTF(",");
2141 dstreg = DECODE_RM_LONG_REGISTER(rh);
2142 TRACE_AND_STEP();
2143 srcval = fetch_data_long(srcoffset);
2144 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2145 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2146 if ((srcval >> *dstreg) & 1) break;
2147 } else {
2148 u16 srcval, *dstreg;
2150 srcoffset = decode_rm00_address(rl);
2151 DECODE_PRINTF(",");
2152 dstreg = DECODE_RM_WORD_REGISTER(rh);
2153 TRACE_AND_STEP();
2154 srcval = fetch_data_word(srcoffset);
2155 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2156 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2157 if ((srcval >> *dstreg) & 1) break;
2159 break;
2160 case 1:
2161 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2162 u32 srcval, *dstreg;
2164 srcoffset = decode_rm01_address(rl);
2165 DECODE_PRINTF(",");
2166 dstreg = DECODE_RM_LONG_REGISTER(rh);
2167 TRACE_AND_STEP();
2168 srcval = fetch_data_long(srcoffset);
2169 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2170 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2171 if ((srcval >> *dstreg) & 1) break;
2172 } else {
2173 u16 srcval, *dstreg;
2175 srcoffset = decode_rm01_address(rl);
2176 DECODE_PRINTF(",");
2177 dstreg = DECODE_RM_WORD_REGISTER(rh);
2178 TRACE_AND_STEP();
2179 srcval = fetch_data_word(srcoffset);
2180 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2181 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2182 if ((srcval >> *dstreg) & 1) break;
2184 break;
2185 case 2:
2186 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2187 u32 srcval, *dstreg;
2189 srcoffset = decode_rm10_address(rl);
2190 DECODE_PRINTF(",");
2191 dstreg = DECODE_RM_LONG_REGISTER(rh);
2192 TRACE_AND_STEP();
2193 srcval = fetch_data_long(srcoffset);
2194 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2195 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2196 if ((srcval >> *dstreg) & 1) break;
2197 } else {
2198 u16 srcval, *dstreg;
2200 srcoffset = decode_rm10_address(rl);
2201 DECODE_PRINTF(",");
2202 dstreg = DECODE_RM_WORD_REGISTER(rh);
2203 TRACE_AND_STEP();
2204 srcval = fetch_data_word(srcoffset);
2205 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2206 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2207 if ((srcval >> *dstreg) & 1) break;
2209 break;
2210 case 3: /* register to register */
2211 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2212 u32 *srcreg, *dstreg;
2214 srcreg = DECODE_RM_LONG_REGISTER(rl);
2215 DECODE_PRINTF(",");
2216 dstreg = DECODE_RM_LONG_REGISTER(rh);
2217 TRACE_AND_STEP();
2218 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
2219 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2220 if ((*srcreg >> *dstreg) & 1) break;
2221 } else {
2222 u16 *srcreg, *dstreg;
2224 srcreg = DECODE_RM_WORD_REGISTER(rl);
2225 DECODE_PRINTF(",");
2226 dstreg = DECODE_RM_WORD_REGISTER(rh);
2227 TRACE_AND_STEP();
2228 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
2229 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2230 if ((*srcreg >> *dstreg) & 1) break;
2232 break;
2234 DECODE_CLEAR_SEGOVR();
2235 END_OF_INSTR();
2238 /****************************************************************************
2239 REMARKS:
2240 Handles opcode 0x0f,0xbd
2241 ****************************************************************************/
2242 void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
2244 int mod, rl, rh;
2245 uint srcoffset;
2247 START_OF_INSTR();
2248 DECODE_PRINTF("BSF\n");
2249 FETCH_DECODE_MODRM(mod, rh, rl);
2250 switch(mod) {
2251 case 0:
2252 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2253 u32 srcval, *dstreg;
2255 srcoffset = decode_rm00_address(rl);
2256 DECODE_PRINTF(",");
2257 dstreg = DECODE_RM_LONG_REGISTER(rh);
2258 TRACE_AND_STEP();
2259 srcval = fetch_data_long(srcoffset);
2260 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2261 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2262 if ((srcval >> *dstreg) & 1) break;
2263 } else {
2264 u16 srcval, *dstreg;
2266 srcoffset = decode_rm00_address(rl);
2267 DECODE_PRINTF(",");
2268 dstreg = DECODE_RM_WORD_REGISTER(rh);
2269 TRACE_AND_STEP();
2270 srcval = fetch_data_word(srcoffset);
2271 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2272 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2273 if ((srcval >> *dstreg) & 1) break;
2275 break;
2276 case 1:
2277 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2278 u32 srcval, *dstreg;
2280 srcoffset = decode_rm01_address(rl);
2281 DECODE_PRINTF(",");
2282 dstreg = DECODE_RM_LONG_REGISTER(rh);
2283 TRACE_AND_STEP();
2284 srcval = fetch_data_long(srcoffset);
2285 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2286 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2287 if ((srcval >> *dstreg) & 1) break;
2288 } else {
2289 u16 srcval, *dstreg;
2291 srcoffset = decode_rm01_address(rl);
2292 DECODE_PRINTF(",");
2293 dstreg = DECODE_RM_WORD_REGISTER(rh);
2294 TRACE_AND_STEP();
2295 srcval = fetch_data_word(srcoffset);
2296 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2297 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2298 if ((srcval >> *dstreg) & 1) break;
2300 break;
2301 case 2:
2302 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2303 u32 srcval, *dstreg;
2305 srcoffset = decode_rm10_address(rl);
2306 DECODE_PRINTF(",");
2307 dstreg = DECODE_RM_LONG_REGISTER(rh);
2308 TRACE_AND_STEP();
2309 srcval = fetch_data_long(srcoffset);
2310 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2311 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2312 if ((srcval >> *dstreg) & 1) break;
2313 } else {
2314 u16 srcval, *dstreg;
2316 srcoffset = decode_rm10_address(rl);
2317 DECODE_PRINTF(",");
2318 dstreg = DECODE_RM_WORD_REGISTER(rh);
2319 TRACE_AND_STEP();
2320 srcval = fetch_data_word(srcoffset);
2321 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2322 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2323 if ((srcval >> *dstreg) & 1) break;
2325 break;
2326 case 3: /* register to register */
2327 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2328 u32 *srcreg, *dstreg;
2330 srcreg = DECODE_RM_LONG_REGISTER(rl);
2331 DECODE_PRINTF(",");
2332 dstreg = DECODE_RM_LONG_REGISTER(rh);
2333 TRACE_AND_STEP();
2334 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
2335 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2336 if ((*srcreg >> *dstreg) & 1) break;
2337 } else {
2338 u16 *srcreg, *dstreg;
2340 srcreg = DECODE_RM_WORD_REGISTER(rl);
2341 DECODE_PRINTF(",");
2342 dstreg = DECODE_RM_WORD_REGISTER(rh);
2343 TRACE_AND_STEP();
2344 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
2345 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2346 if ((*srcreg >> *dstreg) & 1) break;
2348 break;
2350 DECODE_CLEAR_SEGOVR();
2351 END_OF_INSTR();
2354 /****************************************************************************
2355 REMARKS:
2356 Handles opcode 0x0f,0xbe
2357 ****************************************************************************/
2358 void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
2360 int mod, rl, rh;
2361 uint srcoffset;
2363 START_OF_INSTR();
2364 DECODE_PRINTF("MOVSX\t");
2365 FETCH_DECODE_MODRM(mod, rh, rl);
2366 switch (mod) {
2367 case 0:
2368 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2369 u32 *destreg;
2370 u32 srcval;
2372 destreg = DECODE_RM_LONG_REGISTER(rh);
2373 DECODE_PRINTF(",");
2374 srcoffset = decode_rm00_address(rl);
2375 srcval = (s32)((s8)fetch_data_byte(srcoffset));
2376 DECODE_PRINTF("\n");
2377 TRACE_AND_STEP();
2378 *destreg = srcval;
2379 } else {
2380 u16 *destreg;
2381 u16 srcval;
2383 destreg = DECODE_RM_WORD_REGISTER(rh);
2384 DECODE_PRINTF(",");
2385 srcoffset = decode_rm00_address(rl);
2386 srcval = (s16)((s8)fetch_data_byte(srcoffset));
2387 DECODE_PRINTF("\n");
2388 TRACE_AND_STEP();
2389 *destreg = srcval;
2391 break;
2392 case 1:
2393 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2394 u32 *destreg;
2395 u32 srcval;
2397 destreg = DECODE_RM_LONG_REGISTER(rh);
2398 DECODE_PRINTF(",");
2399 srcoffset = decode_rm01_address(rl);
2400 srcval = (s32)((s8)fetch_data_byte(srcoffset));
2401 DECODE_PRINTF("\n");
2402 TRACE_AND_STEP();
2403 *destreg = srcval;
2404 } else {
2405 u16 *destreg;
2406 u16 srcval;
2408 destreg = DECODE_RM_WORD_REGISTER(rh);
2409 DECODE_PRINTF(",");
2410 srcoffset = decode_rm01_address(rl);
2411 srcval = (s16)((s8)fetch_data_byte(srcoffset));
2412 DECODE_PRINTF("\n");
2413 TRACE_AND_STEP();
2414 *destreg = srcval;
2416 break;
2417 case 2:
2418 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2419 u32 *destreg;
2420 u32 srcval;
2422 destreg = DECODE_RM_LONG_REGISTER(rh);
2423 DECODE_PRINTF(",");
2424 srcoffset = decode_rm10_address(rl);
2425 srcval = (s32)((s8)fetch_data_byte(srcoffset));
2426 DECODE_PRINTF("\n");
2427 TRACE_AND_STEP();
2428 *destreg = srcval;
2429 } else {
2430 u16 *destreg;
2431 u16 srcval;
2433 destreg = DECODE_RM_WORD_REGISTER(rh);
2434 DECODE_PRINTF(",");
2435 srcoffset = decode_rm10_address(rl);
2436 srcval = (s16)((s8)fetch_data_byte(srcoffset));
2437 DECODE_PRINTF("\n");
2438 TRACE_AND_STEP();
2439 *destreg = srcval;
2441 break;
2442 case 3: /* register to register */
2443 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2444 u32 *destreg;
2445 u8 *srcreg;
2447 destreg = DECODE_RM_LONG_REGISTER(rh);
2448 DECODE_PRINTF(",");
2449 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2450 DECODE_PRINTF("\n");
2451 TRACE_AND_STEP();
2452 *destreg = (s32)((s8)*srcreg);
2453 } else {
2454 u16 *destreg;
2455 u8 *srcreg;
2457 destreg = DECODE_RM_WORD_REGISTER(rh);
2458 DECODE_PRINTF(",");
2459 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2460 DECODE_PRINTF("\n");
2461 TRACE_AND_STEP();
2462 *destreg = (s16)((s8)*srcreg);
2464 break;
2466 DECODE_CLEAR_SEGOVR();
2467 END_OF_INSTR();
2470 /****************************************************************************
2471 REMARKS:
2472 Handles opcode 0x0f,0xbf
2473 ****************************************************************************/
2474 void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
2476 int mod, rl, rh;
2477 uint srcoffset;
2478 u32 *destreg;
2479 u32 srcval;
2480 u16 *srcreg;
2482 START_OF_INSTR();
2483 DECODE_PRINTF("MOVSX\t");
2484 FETCH_DECODE_MODRM(mod, rh, rl);
2485 switch (mod) {
2486 case 0:
2487 destreg = DECODE_RM_LONG_REGISTER(rh);
2488 DECODE_PRINTF(",");
2489 srcoffset = decode_rm00_address(rl);
2490 srcval = (s32)((s16)fetch_data_word(srcoffset));
2491 DECODE_PRINTF("\n");
2492 TRACE_AND_STEP();
2493 *destreg = srcval;
2494 break;
2495 case 1:
2496 destreg = DECODE_RM_LONG_REGISTER(rh);
2497 DECODE_PRINTF(",");
2498 srcoffset = decode_rm01_address(rl);
2499 srcval = (s32)((s16)fetch_data_word(srcoffset));
2500 DECODE_PRINTF("\n");
2501 TRACE_AND_STEP();
2502 *destreg = srcval;
2503 break;
2504 case 2:
2505 destreg = DECODE_RM_LONG_REGISTER(rh);
2506 DECODE_PRINTF(",");
2507 srcoffset = decode_rm10_address(rl);
2508 srcval = (s32)((s16)fetch_data_word(srcoffset));
2509 DECODE_PRINTF("\n");
2510 TRACE_AND_STEP();
2511 *destreg = srcval;
2512 break;
2513 case 3: /* register to register */
2514 destreg = DECODE_RM_LONG_REGISTER(rh);
2515 DECODE_PRINTF(",");
2516 srcreg = DECODE_RM_WORD_REGISTER(rl);
2517 DECODE_PRINTF("\n");
2518 TRACE_AND_STEP();
2519 *destreg = (s32)((s16)*srcreg);
2520 break;
2522 DECODE_CLEAR_SEGOVR();
2523 END_OF_INSTR();
2526 /***************************************************************************
2527 * Double byte operation code table:
2528 **************************************************************************/
2529 void (*x86emu_optab2[256])(u8) =
2531 /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
2532 /* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */
2533 /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
2534 /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
2535 /* 0x04 */ x86emuOp2_illegal_op,
2536 /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
2537 /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
2538 /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
2539 /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */
2540 /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */
2541 /* 0x0a */ x86emuOp2_illegal_op,
2542 /* 0x0b */ x86emuOp2_illegal_op,
2543 /* 0x0c */ x86emuOp2_illegal_op,
2544 /* 0x0d */ x86emuOp2_illegal_op,
2545 /* 0x0e */ x86emuOp2_illegal_op,
2546 /* 0x0f */ x86emuOp2_illegal_op,
2548 /* 0x10 */ x86emuOp2_illegal_op,
2549 /* 0x11 */ x86emuOp2_illegal_op,
2550 /* 0x12 */ x86emuOp2_illegal_op,
2551 /* 0x13 */ x86emuOp2_illegal_op,
2552 /* 0x14 */ x86emuOp2_illegal_op,
2553 /* 0x15 */ x86emuOp2_illegal_op,
2554 /* 0x16 */ x86emuOp2_illegal_op,
2555 /* 0x17 */ x86emuOp2_illegal_op,
2556 /* 0x18 */ x86emuOp2_illegal_op,
2557 /* 0x19 */ x86emuOp2_illegal_op,
2558 /* 0x1a */ x86emuOp2_illegal_op,
2559 /* 0x1b */ x86emuOp2_illegal_op,
2560 /* 0x1c */ x86emuOp2_illegal_op,
2561 /* 0x1d */ x86emuOp2_illegal_op,
2562 /* 0x1e */ x86emuOp2_illegal_op,
2563 /* 0x1f */ x86emuOp2_illegal_op,
2565 /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
2566 /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
2567 /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
2568 /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
2569 /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
2570 /* 0x25 */ x86emuOp2_illegal_op,
2571 /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
2572 /* 0x27 */ x86emuOp2_illegal_op,
2573 /* 0x28 */ x86emuOp2_illegal_op,
2574 /* 0x29 */ x86emuOp2_illegal_op,
2575 /* 0x2a */ x86emuOp2_illegal_op,
2576 /* 0x2b */ x86emuOp2_illegal_op,
2577 /* 0x2c */ x86emuOp2_illegal_op,
2578 /* 0x2d */ x86emuOp2_illegal_op,
2579 /* 0x2e */ x86emuOp2_illegal_op,
2580 /* 0x2f */ x86emuOp2_illegal_op,
2582 /* 0x30 */ x86emuOp2_illegal_op,
2583 /* 0x31 */ x86emuOp2_illegal_op,
2584 /* 0x32 */ x86emuOp2_illegal_op,
2585 /* 0x33 */ x86emuOp2_illegal_op,
2586 /* 0x34 */ x86emuOp2_illegal_op,
2587 /* 0x35 */ x86emuOp2_illegal_op,
2588 /* 0x36 */ x86emuOp2_illegal_op,
2589 /* 0x37 */ x86emuOp2_illegal_op,
2590 /* 0x38 */ x86emuOp2_illegal_op,
2591 /* 0x39 */ x86emuOp2_illegal_op,
2592 /* 0x3a */ x86emuOp2_illegal_op,
2593 /* 0x3b */ x86emuOp2_illegal_op,
2594 /* 0x3c */ x86emuOp2_illegal_op,
2595 /* 0x3d */ x86emuOp2_illegal_op,
2596 /* 0x3e */ x86emuOp2_illegal_op,
2597 /* 0x3f */ x86emuOp2_illegal_op,
2599 /* 0x40 */ x86emuOp2_illegal_op,
2600 /* 0x41 */ x86emuOp2_illegal_op,
2601 /* 0x42 */ x86emuOp2_illegal_op,
2602 /* 0x43 */ x86emuOp2_illegal_op,
2603 /* 0x44 */ x86emuOp2_illegal_op,
2604 /* 0x45 */ x86emuOp2_illegal_op,
2605 /* 0x46 */ x86emuOp2_illegal_op,
2606 /* 0x47 */ x86emuOp2_illegal_op,
2607 /* 0x48 */ x86emuOp2_illegal_op,
2608 /* 0x49 */ x86emuOp2_illegal_op,
2609 /* 0x4a */ x86emuOp2_illegal_op,
2610 /* 0x4b */ x86emuOp2_illegal_op,
2611 /* 0x4c */ x86emuOp2_illegal_op,
2612 /* 0x4d */ x86emuOp2_illegal_op,
2613 /* 0x4e */ x86emuOp2_illegal_op,
2614 /* 0x4f */ x86emuOp2_illegal_op,
2616 /* 0x50 */ x86emuOp2_illegal_op,
2617 /* 0x51 */ x86emuOp2_illegal_op,
2618 /* 0x52 */ x86emuOp2_illegal_op,
2619 /* 0x53 */ x86emuOp2_illegal_op,
2620 /* 0x54 */ x86emuOp2_illegal_op,
2621 /* 0x55 */ x86emuOp2_illegal_op,
2622 /* 0x56 */ x86emuOp2_illegal_op,
2623 /* 0x57 */ x86emuOp2_illegal_op,
2624 /* 0x58 */ x86emuOp2_illegal_op,
2625 /* 0x59 */ x86emuOp2_illegal_op,
2626 /* 0x5a */ x86emuOp2_illegal_op,
2627 /* 0x5b */ x86emuOp2_illegal_op,
2628 /* 0x5c */ x86emuOp2_illegal_op,
2629 /* 0x5d */ x86emuOp2_illegal_op,
2630 /* 0x5e */ x86emuOp2_illegal_op,
2631 /* 0x5f */ x86emuOp2_illegal_op,
2633 /* 0x60 */ x86emuOp2_illegal_op,
2634 /* 0x61 */ x86emuOp2_illegal_op,
2635 /* 0x62 */ x86emuOp2_illegal_op,
2636 /* 0x63 */ x86emuOp2_illegal_op,
2637 /* 0x64 */ x86emuOp2_illegal_op,
2638 /* 0x65 */ x86emuOp2_illegal_op,
2639 /* 0x66 */ x86emuOp2_illegal_op,
2640 /* 0x67 */ x86emuOp2_illegal_op,
2641 /* 0x68 */ x86emuOp2_illegal_op,
2642 /* 0x69 */ x86emuOp2_illegal_op,
2643 /* 0x6a */ x86emuOp2_illegal_op,
2644 /* 0x6b */ x86emuOp2_illegal_op,
2645 /* 0x6c */ x86emuOp2_illegal_op,
2646 /* 0x6d */ x86emuOp2_illegal_op,
2647 /* 0x6e */ x86emuOp2_illegal_op,
2648 /* 0x6f */ x86emuOp2_illegal_op,
2650 /* 0x70 */ x86emuOp2_illegal_op,
2651 /* 0x71 */ x86emuOp2_illegal_op,
2652 /* 0x72 */ x86emuOp2_illegal_op,
2653 /* 0x73 */ x86emuOp2_illegal_op,
2654 /* 0x74 */ x86emuOp2_illegal_op,
2655 /* 0x75 */ x86emuOp2_illegal_op,
2656 /* 0x76 */ x86emuOp2_illegal_op,
2657 /* 0x77 */ x86emuOp2_illegal_op,
2658 /* 0x78 */ x86emuOp2_illegal_op,
2659 /* 0x79 */ x86emuOp2_illegal_op,
2660 /* 0x7a */ x86emuOp2_illegal_op,
2661 /* 0x7b */ x86emuOp2_illegal_op,
2662 /* 0x7c */ x86emuOp2_illegal_op,
2663 /* 0x7d */ x86emuOp2_illegal_op,
2664 /* 0x7e */ x86emuOp2_illegal_op,
2665 /* 0x7f */ x86emuOp2_illegal_op,
2667 /* 0x80 */ x86emuOp2_long_jump,
2668 /* 0x81 */ x86emuOp2_long_jump,
2669 /* 0x82 */ x86emuOp2_long_jump,
2670 /* 0x83 */ x86emuOp2_long_jump,
2671 /* 0x84 */ x86emuOp2_long_jump,
2672 /* 0x85 */ x86emuOp2_long_jump,
2673 /* 0x86 */ x86emuOp2_long_jump,
2674 /* 0x87 */ x86emuOp2_long_jump,
2675 /* 0x88 */ x86emuOp2_long_jump,
2676 /* 0x89 */ x86emuOp2_long_jump,
2677 /* 0x8a */ x86emuOp2_long_jump,
2678 /* 0x8b */ x86emuOp2_long_jump,
2679 /* 0x8c */ x86emuOp2_long_jump,
2680 /* 0x8d */ x86emuOp2_long_jump,
2681 /* 0x8e */ x86emuOp2_long_jump,
2682 /* 0x8f */ x86emuOp2_long_jump,
2684 /* 0x90 */ x86emuOp2_set_byte,
2685 /* 0x91 */ x86emuOp2_set_byte,
2686 /* 0x92 */ x86emuOp2_set_byte,
2687 /* 0x93 */ x86emuOp2_set_byte,
2688 /* 0x94 */ x86emuOp2_set_byte,
2689 /* 0x95 */ x86emuOp2_set_byte,
2690 /* 0x96 */ x86emuOp2_set_byte,
2691 /* 0x97 */ x86emuOp2_set_byte,
2692 /* 0x98 */ x86emuOp2_set_byte,
2693 /* 0x99 */ x86emuOp2_set_byte,
2694 /* 0x9a */ x86emuOp2_set_byte,
2695 /* 0x9b */ x86emuOp2_set_byte,
2696 /* 0x9c */ x86emuOp2_set_byte,
2697 /* 0x9d */ x86emuOp2_set_byte,
2698 /* 0x9e */ x86emuOp2_set_byte,
2699 /* 0x9f */ x86emuOp2_set_byte,
2701 /* 0xa0 */ x86emuOp2_push_FS,
2702 /* 0xa1 */ x86emuOp2_pop_FS,
2703 /* 0xa2 */ x86emuOp2_illegal_op,
2704 /* 0xa3 */ x86emuOp2_bt_R,
2705 /* 0xa4 */ x86emuOp2_shld_IMM,
2706 /* 0xa5 */ x86emuOp2_shld_CL,
2707 /* 0xa6 */ x86emuOp2_illegal_op,
2708 /* 0xa7 */ x86emuOp2_illegal_op,
2709 /* 0xa8 */ x86emuOp2_push_GS,
2710 /* 0xa9 */ x86emuOp2_pop_GS,
2711 /* 0xaa */ x86emuOp2_illegal_op,
2712 /* 0xab */ x86emuOp2_bt_R,
2713 /* 0xac */ x86emuOp2_shrd_IMM,
2714 /* 0xad */ x86emuOp2_shrd_CL,
2715 /* 0xae */ x86emuOp2_illegal_op,
2716 /* 0xaf */ x86emuOp2_imul_R_RM,
2718 /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
2719 /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
2720 /* 0xb2 */ x86emuOp2_lss_R_IMM,
2721 /* 0xb3 */ x86emuOp2_btr_R,
2722 /* 0xb4 */ x86emuOp2_lfs_R_IMM,
2723 /* 0xb5 */ x86emuOp2_lgs_R_IMM,
2724 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
2725 /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
2726 /* 0xb8 */ x86emuOp2_illegal_op,
2727 /* 0xb9 */ x86emuOp2_illegal_op,
2728 /* 0xba */ x86emuOp2_btX_I,
2729 /* 0xbb */ x86emuOp2_btc_R,
2730 /* 0xbc */ x86emuOp2_bsf,
2731 /* 0xbd */ x86emuOp2_bsr,
2732 /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
2733 /* 0xbf */ x86emuOp2_movsx_word_R_RM,
2735 /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
2736 /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
2737 /* 0xc2 */ x86emuOp2_illegal_op,
2738 /* 0xc3 */ x86emuOp2_illegal_op,
2739 /* 0xc4 */ x86emuOp2_illegal_op,
2740 /* 0xc5 */ x86emuOp2_illegal_op,
2741 /* 0xc6 */ x86emuOp2_illegal_op,
2742 /* 0xc7 */ x86emuOp2_illegal_op,
2743 /* 0xc8 */ x86emuOp2_illegal_op, /* TODO: bswap */
2744 /* 0xc9 */ x86emuOp2_illegal_op, /* TODO: bswap */
2745 /* 0xca */ x86emuOp2_illegal_op, /* TODO: bswap */
2746 /* 0xcb */ x86emuOp2_illegal_op, /* TODO: bswap */
2747 /* 0xcc */ x86emuOp2_illegal_op, /* TODO: bswap */
2748 /* 0xcd */ x86emuOp2_illegal_op, /* TODO: bswap */
2749 /* 0xce */ x86emuOp2_illegal_op, /* TODO: bswap */
2750 /* 0xcf */ x86emuOp2_illegal_op, /* TODO: bswap */
2752 /* 0xd0 */ x86emuOp2_illegal_op,
2753 /* 0xd1 */ x86emuOp2_illegal_op,
2754 /* 0xd2 */ x86emuOp2_illegal_op,
2755 /* 0xd3 */ x86emuOp2_illegal_op,
2756 /* 0xd4 */ x86emuOp2_illegal_op,
2757 /* 0xd5 */ x86emuOp2_illegal_op,
2758 /* 0xd6 */ x86emuOp2_illegal_op,
2759 /* 0xd7 */ x86emuOp2_illegal_op,
2760 /* 0xd8 */ x86emuOp2_illegal_op,
2761 /* 0xd9 */ x86emuOp2_illegal_op,
2762 /* 0xda */ x86emuOp2_illegal_op,
2763 /* 0xdb */ x86emuOp2_illegal_op,
2764 /* 0xdc */ x86emuOp2_illegal_op,
2765 /* 0xdd */ x86emuOp2_illegal_op,
2766 /* 0xde */ x86emuOp2_illegal_op,
2767 /* 0xdf */ x86emuOp2_illegal_op,
2769 /* 0xe0 */ x86emuOp2_illegal_op,
2770 /* 0xe1 */ x86emuOp2_illegal_op,
2771 /* 0xe2 */ x86emuOp2_illegal_op,
2772 /* 0xe3 */ x86emuOp2_illegal_op,
2773 /* 0xe4 */ x86emuOp2_illegal_op,
2774 /* 0xe5 */ x86emuOp2_illegal_op,
2775 /* 0xe6 */ x86emuOp2_illegal_op,
2776 /* 0xe7 */ x86emuOp2_illegal_op,
2777 /* 0xe8 */ x86emuOp2_illegal_op,
2778 /* 0xe9 */ x86emuOp2_illegal_op,
2779 /* 0xea */ x86emuOp2_illegal_op,
2780 /* 0xeb */ x86emuOp2_illegal_op,
2781 /* 0xec */ x86emuOp2_illegal_op,
2782 /* 0xed */ x86emuOp2_illegal_op,
2783 /* 0xee */ x86emuOp2_illegal_op,
2784 /* 0xef */ x86emuOp2_illegal_op,
2786 /* 0xf0 */ x86emuOp2_illegal_op,
2787 /* 0xf1 */ x86emuOp2_illegal_op,
2788 /* 0xf2 */ x86emuOp2_illegal_op,
2789 /* 0xf3 */ x86emuOp2_illegal_op,
2790 /* 0xf4 */ x86emuOp2_illegal_op,
2791 /* 0xf5 */ x86emuOp2_illegal_op,
2792 /* 0xf6 */ x86emuOp2_illegal_op,
2793 /* 0xf7 */ x86emuOp2_illegal_op,
2794 /* 0xf8 */ x86emuOp2_illegal_op,
2795 /* 0xf9 */ x86emuOp2_illegal_op,
2796 /* 0xfa */ x86emuOp2_illegal_op,
2797 /* 0xfb */ x86emuOp2_illegal_op,
2798 /* 0xfc */ x86emuOp2_illegal_op,
2799 /* 0xfd */ x86emuOp2_illegal_op,
2800 /* 0xfe */ x86emuOp2_illegal_op,
2801 /* 0xff */ x86emuOp2_illegal_op,