Add support for bswap and cpuid.
[v86d.git] / libs / x86emu / ops2.c
bloba1eda76d7df94e649ae8574ec40edce8223498ed
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 ****************************************************************************/
41 #include "x86emu/x86emui.h"
43 #undef bswap_32
44 #define bswap_32(x) (((x & 0xff000000) >> 24) | \
45 ((x & 0x00ff0000) >> 8) | \
46 ((x & 0x0000ff00) << 8) | \
47 ((x & 0x000000ff) << 24))
49 /*----------------------------- Implementation ----------------------------*/
51 /****************************************************************************
52 PARAMETERS:
53 op1 - Instruction op code
55 REMARKS:
56 Handles illegal opcodes.
57 ****************************************************************************/
58 static void x86emuOp2_illegal_op(
59 u8 op2)
61 START_OF_INSTR();
62 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
63 TRACE_REGS();
64 printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
65 M.x86.R_CS, M.x86.R_IP-2,op2);
66 HALT_SYS();
67 END_OF_INSTR();
70 #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
72 /****************************************************************************
73 REMARKS:
74 Handles opcode 0x0f,0x31
75 ****************************************************************************/
76 static void x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
78 #ifdef __HAS_LONG_LONG__
79 static u64 counter = 0;
80 #else
81 static u32 counter = 0;
82 #endif
84 counter += 0x10000;
86 /* read timestamp counter */
88 * Note that instead of actually trying to accurately measure this, we just
89 * increase the counter by a fixed amount every time we hit one of these
90 * instructions. Feel free to come up with a better method.
92 START_OF_INSTR();
93 DECODE_PRINTF("RDTSC\n");
94 TRACE_AND_STEP();
95 #ifdef __HAS_LONG_LONG__
96 M.x86.R_EAX = counter & 0xffffffff;
97 M.x86.R_EDX = counter >> 32;
98 #else
99 M.x86.R_EAX = counter;
100 M.x86.R_EDX = 0;
101 #endif
102 DECODE_CLEAR_SEGOVR();
103 END_OF_INSTR();
106 /****************************************************************************
107 REMARKS:
108 Handles opcode 0x0f,0x80-0x8F
109 ****************************************************************************/
110 static void x86emuOp2_long_jump(u8 op2)
112 s32 target;
113 char *name = 0;
114 int cond = 0;
116 /* conditional jump to word offset. */
117 START_OF_INSTR();
118 switch (op2) {
119 case 0x80:
120 name = "JO\t";
121 cond = ACCESS_FLAG(F_OF);
122 break;
123 case 0x81:
124 name = "JNO\t";
125 cond = !ACCESS_FLAG(F_OF);
126 break;
127 case 0x82:
128 name = "JB\t";
129 cond = ACCESS_FLAG(F_CF);
130 break;
131 case 0x83:
132 name = "JNB\t";
133 cond = !ACCESS_FLAG(F_CF);
134 break;
135 case 0x84:
136 name = "JZ\t";
137 cond = ACCESS_FLAG(F_ZF);
138 break;
139 case 0x85:
140 name = "JNZ\t";
141 cond = !ACCESS_FLAG(F_ZF);
142 break;
143 case 0x86:
144 name = "JBE\t";
145 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
146 break;
147 case 0x87:
148 name = "JNBE\t";
149 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
150 break;
151 case 0x88:
152 name = "JS\t";
153 cond = ACCESS_FLAG(F_SF);
154 break;
155 case 0x89:
156 name = "JNS\t";
157 cond = !ACCESS_FLAG(F_SF);
158 break;
159 case 0x8a:
160 name = "JP\t";
161 cond = ACCESS_FLAG(F_PF);
162 break;
163 case 0x8b:
164 name = "JNP\t";
165 cond = !ACCESS_FLAG(F_PF);
166 break;
167 case 0x8c:
168 name = "JL\t";
169 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
170 break;
171 case 0x8d:
172 name = "JNL\t";
173 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
174 break;
175 case 0x8e:
176 name = "JLE\t";
177 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
178 ACCESS_FLAG(F_ZF));
179 break;
180 case 0x8f:
181 name = "JNLE\t";
182 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
183 ACCESS_FLAG(F_ZF));
184 break;
186 DECODE_PRINTF(name);
187 (void)name;
188 target = (s16) fetch_word_imm();
189 target += (s16) M.x86.R_IP;
190 DECODE_PRINTF2("%04x\n", target);
191 TRACE_AND_STEP();
192 if (cond)
193 M.x86.R_IP = (u16)target;
194 DECODE_CLEAR_SEGOVR();
195 END_OF_INSTR();
198 /****************************************************************************
199 REMARKS:
200 Handles opcode 0x0f,0x90-0x9F
201 ****************************************************************************/
202 static void x86emuOp2_set_byte(u8 op2)
204 int mod, rl, rh;
205 uint destoffset;
206 u8 *destreg;
207 char *name = 0;
208 int cond = 0;
210 START_OF_INSTR();
211 switch (op2) {
212 case 0x90:
213 name = "SETO\t";
214 cond = ACCESS_FLAG(F_OF);
215 break;
216 case 0x91:
217 name = "SETNO\t";
218 cond = !ACCESS_FLAG(F_OF);
219 break;
220 case 0x92:
221 name = "SETB\t";
222 cond = ACCESS_FLAG(F_CF);
223 break;
224 case 0x93:
225 name = "SETNB\t";
226 cond = !ACCESS_FLAG(F_CF);
227 break;
228 case 0x94:
229 name = "SETZ\t";
230 cond = ACCESS_FLAG(F_ZF);
231 break;
232 case 0x95:
233 name = "SETNZ\t";
234 cond = !ACCESS_FLAG(F_ZF);
235 break;
236 case 0x96:
237 name = "SETBE\t";
238 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
239 break;
240 case 0x97:
241 name = "SETNBE\t";
242 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
243 break;
244 case 0x98:
245 name = "SETS\t";
246 cond = ACCESS_FLAG(F_SF);
247 break;
248 case 0x99:
249 name = "SETNS\t";
250 cond = !ACCESS_FLAG(F_SF);
251 break;
252 case 0x9a:
253 name = "SETP\t";
254 cond = ACCESS_FLAG(F_PF);
255 break;
256 case 0x9b:
257 name = "SETNP\t";
258 cond = !ACCESS_FLAG(F_PF);
259 break;
260 case 0x9c:
261 name = "SETL\t";
262 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
263 break;
264 case 0x9d:
265 name = "SETNL\t";
266 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
267 break;
268 case 0x9e:
269 name = "SETLE\t";
270 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
271 ACCESS_FLAG(F_ZF));
272 break;
273 case 0x9f:
274 name = "SETNLE\t";
275 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
276 ACCESS_FLAG(F_ZF));
277 break;
279 DECODE_PRINTF(name);
280 (void)name;
281 FETCH_DECODE_MODRM(mod, rh, rl);
282 switch (mod) {
283 case 0:
284 destoffset = decode_rm00_address(rl);
285 TRACE_AND_STEP();
286 store_data_byte(destoffset, cond ? 0x01 : 0x00);
287 break;
288 case 1:
289 destoffset = decode_rm01_address(rl);
290 TRACE_AND_STEP();
291 store_data_byte(destoffset, cond ? 0x01 : 0x00);
292 break;
293 case 2:
294 destoffset = decode_rm10_address(rl);
295 TRACE_AND_STEP();
296 store_data_byte(destoffset, cond ? 0x01 : 0x00);
297 break;
298 case 3: /* register to register */
299 destreg = DECODE_RM_BYTE_REGISTER(rl);
300 TRACE_AND_STEP();
301 *destreg = cond ? 0x01 : 0x00;
302 break;
304 DECODE_CLEAR_SEGOVR();
305 END_OF_INSTR();
308 /****************************************************************************
309 REMARKS:
310 Handles opcode 0x0f,0xa0
311 ****************************************************************************/
312 static void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
314 START_OF_INSTR();
315 DECODE_PRINTF("PUSH\tFS\n");
316 TRACE_AND_STEP();
317 push_word(M.x86.R_FS);
318 DECODE_CLEAR_SEGOVR();
319 END_OF_INSTR();
322 /****************************************************************************
323 REMARKS:
324 Handles opcode 0x0f,0xa1
325 ****************************************************************************/
326 static void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
328 START_OF_INSTR();
329 DECODE_PRINTF("POP\tFS\n");
330 TRACE_AND_STEP();
331 M.x86.R_FS = pop_word();
332 DECODE_CLEAR_SEGOVR();
333 END_OF_INSTR();
336 /****************************************************************************
337 REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
338 Handles opcode 0x0f,0xa2
339 ****************************************************************************/
340 static void x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
342 START_OF_INSTR();
343 DECODE_PRINTF("CPUID\n");
344 TRACE_AND_STEP();
345 cpuid();
346 DECODE_CLEAR_SEGOVR();
347 END_OF_INSTR();
350 /****************************************************************************
351 REMARKS:
352 Handles opcode 0x0f,0xa3
353 ****************************************************************************/
354 static void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
356 int mod, rl, rh;
357 uint srcoffset;
358 int bit,disp;
360 START_OF_INSTR();
361 DECODE_PRINTF("BT\t");
362 FETCH_DECODE_MODRM(mod, rh, rl);
363 switch (mod) {
364 case 0:
365 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
366 u32 srcval;
367 u32 *shiftreg;
369 srcoffset = decode_rm00_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_rm00_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 1:
392 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
393 u32 srcval;
394 u32 *shiftreg;
396 srcoffset = decode_rm01_address(rl);
397 DECODE_PRINTF(",");
398 shiftreg = DECODE_RM_LONG_REGISTER(rh);
399 TRACE_AND_STEP();
400 bit = *shiftreg & 0x1F;
401 disp = (s16)*shiftreg >> 5;
402 srcval = fetch_data_long(srcoffset+disp);
403 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
404 } else {
405 u16 srcval;
406 u16 *shiftreg;
408 srcoffset = decode_rm01_address(rl);
409 DECODE_PRINTF(",");
410 shiftreg = DECODE_RM_WORD_REGISTER(rh);
411 TRACE_AND_STEP();
412 bit = *shiftreg & 0xF;
413 disp = (s16)*shiftreg >> 4;
414 srcval = fetch_data_word(srcoffset+disp);
415 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
417 break;
418 case 2:
419 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
420 u32 srcval;
421 u32 *shiftreg;
423 srcoffset = decode_rm10_address(rl);
424 DECODE_PRINTF(",");
425 shiftreg = DECODE_RM_LONG_REGISTER(rh);
426 TRACE_AND_STEP();
427 bit = *shiftreg & 0x1F;
428 disp = (s16)*shiftreg >> 5;
429 srcval = fetch_data_long(srcoffset+disp);
430 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
431 } else {
432 u16 srcval;
433 u16 *shiftreg;
435 srcoffset = decode_rm10_address(rl);
436 DECODE_PRINTF(",");
437 shiftreg = DECODE_RM_WORD_REGISTER(rh);
438 TRACE_AND_STEP();
439 bit = *shiftreg & 0xF;
440 disp = (s16)*shiftreg >> 4;
441 srcval = fetch_data_word(srcoffset+disp);
442 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
444 break;
445 case 3: /* register to register */
446 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
447 u32 *srcreg,*shiftreg;
449 srcreg = DECODE_RM_LONG_REGISTER(rl);
450 DECODE_PRINTF(",");
451 shiftreg = DECODE_RM_LONG_REGISTER(rh);
452 TRACE_AND_STEP();
453 bit = *shiftreg & 0x1F;
454 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
455 } else {
456 u16 *srcreg,*shiftreg;
458 srcreg = DECODE_RM_WORD_REGISTER(rl);
459 DECODE_PRINTF(",");
460 shiftreg = DECODE_RM_WORD_REGISTER(rh);
461 TRACE_AND_STEP();
462 bit = *shiftreg & 0xF;
463 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
465 break;
467 DECODE_CLEAR_SEGOVR();
468 END_OF_INSTR();
471 /****************************************************************************
472 REMARKS:
473 Handles opcode 0x0f,0xa4
474 ****************************************************************************/
475 static void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
477 int mod, rl, rh;
478 uint destoffset;
479 u8 shift;
481 START_OF_INSTR();
482 DECODE_PRINTF("SHLD\t");
483 FETCH_DECODE_MODRM(mod, rh, rl);
484 switch (mod) {
485 case 0:
486 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
487 u32 destval;
488 u32 *shiftreg;
490 destoffset = decode_rm00_address(rl);
491 DECODE_PRINTF(",");
492 shiftreg = DECODE_RM_LONG_REGISTER(rh);
493 DECODE_PRINTF(",");
494 shift = fetch_byte_imm();
495 DECODE_PRINTF2("%d\n", shift);
496 TRACE_AND_STEP();
497 destval = fetch_data_long(destoffset);
498 destval = shld_long(destval,*shiftreg,shift);
499 store_data_long(destoffset, destval);
500 } else {
501 u16 destval;
502 u16 *shiftreg;
504 destoffset = decode_rm00_address(rl);
505 DECODE_PRINTF(",");
506 shiftreg = DECODE_RM_WORD_REGISTER(rh);
507 DECODE_PRINTF(",");
508 shift = fetch_byte_imm();
509 DECODE_PRINTF2("%d\n", shift);
510 TRACE_AND_STEP();
511 destval = fetch_data_word(destoffset);
512 destval = shld_word(destval,*shiftreg,shift);
513 store_data_word(destoffset, destval);
515 break;
516 case 1:
517 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
518 u32 destval;
519 u32 *shiftreg;
521 destoffset = decode_rm01_address(rl);
522 DECODE_PRINTF(",");
523 shiftreg = DECODE_RM_LONG_REGISTER(rh);
524 DECODE_PRINTF(",");
525 shift = fetch_byte_imm();
526 DECODE_PRINTF2("%d\n", shift);
527 TRACE_AND_STEP();
528 destval = fetch_data_long(destoffset);
529 destval = shld_long(destval,*shiftreg,shift);
530 store_data_long(destoffset, destval);
531 } else {
532 u16 destval;
533 u16 *shiftreg;
535 destoffset = decode_rm01_address(rl);
536 DECODE_PRINTF(",");
537 shiftreg = DECODE_RM_WORD_REGISTER(rh);
538 DECODE_PRINTF(",");
539 shift = fetch_byte_imm();
540 DECODE_PRINTF2("%d\n", shift);
541 TRACE_AND_STEP();
542 destval = fetch_data_word(destoffset);
543 destval = shld_word(destval,*shiftreg,shift);
544 store_data_word(destoffset, destval);
546 break;
547 case 2:
548 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
549 u32 destval;
550 u32 *shiftreg;
552 destoffset = decode_rm10_address(rl);
553 DECODE_PRINTF(",");
554 shiftreg = DECODE_RM_LONG_REGISTER(rh);
555 DECODE_PRINTF(",");
556 shift = fetch_byte_imm();
557 DECODE_PRINTF2("%d\n", shift);
558 TRACE_AND_STEP();
559 destval = fetch_data_long(destoffset);
560 destval = shld_long(destval,*shiftreg,shift);
561 store_data_long(destoffset, destval);
562 } else {
563 u16 destval;
564 u16 *shiftreg;
566 destoffset = decode_rm10_address(rl);
567 DECODE_PRINTF(",");
568 shiftreg = DECODE_RM_WORD_REGISTER(rh);
569 DECODE_PRINTF(",");
570 shift = fetch_byte_imm();
571 DECODE_PRINTF2("%d\n", shift);
572 TRACE_AND_STEP();
573 destval = fetch_data_word(destoffset);
574 destval = shld_word(destval,*shiftreg,shift);
575 store_data_word(destoffset, destval);
577 break;
578 case 3: /* register to register */
579 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
580 u32 *destreg,*shiftreg;
582 destreg = DECODE_RM_LONG_REGISTER(rl);
583 DECODE_PRINTF(",");
584 shiftreg = DECODE_RM_LONG_REGISTER(rh);
585 DECODE_PRINTF(",");
586 shift = fetch_byte_imm();
587 DECODE_PRINTF2("%d\n", shift);
588 TRACE_AND_STEP();
589 *destreg = shld_long(*destreg,*shiftreg,shift);
590 } else {
591 u16 *destreg,*shiftreg;
593 destreg = DECODE_RM_WORD_REGISTER(rl);
594 DECODE_PRINTF(",");
595 shiftreg = DECODE_RM_WORD_REGISTER(rh);
596 DECODE_PRINTF(",");
597 shift = fetch_byte_imm();
598 DECODE_PRINTF2("%d\n", shift);
599 TRACE_AND_STEP();
600 *destreg = shld_word(*destreg,*shiftreg,shift);
602 break;
604 DECODE_CLEAR_SEGOVR();
605 END_OF_INSTR();
608 /****************************************************************************
609 REMARKS:
610 Handles opcode 0x0f,0xa5
611 ****************************************************************************/
612 static void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
614 int mod, rl, rh;
615 uint destoffset;
617 START_OF_INSTR();
618 DECODE_PRINTF("SHLD\t");
619 FETCH_DECODE_MODRM(mod, rh, rl);
620 switch (mod) {
621 case 0:
622 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
623 u32 destval;
624 u32 *shiftreg;
626 destoffset = decode_rm00_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_rm00_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 1:
649 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
650 u32 destval;
651 u32 *shiftreg;
653 destoffset = decode_rm01_address(rl);
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 destoffset = decode_rm01_address(rl);
666 DECODE_PRINTF(",");
667 shiftreg = DECODE_RM_WORD_REGISTER(rh);
668 DECODE_PRINTF(",CL\n");
669 TRACE_AND_STEP();
670 destval = fetch_data_word(destoffset);
671 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
672 store_data_word(destoffset, destval);
674 break;
675 case 2:
676 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
677 u32 destval;
678 u32 *shiftreg;
680 destoffset = decode_rm10_address(rl);
681 DECODE_PRINTF(",");
682 shiftreg = DECODE_RM_LONG_REGISTER(rh);
683 DECODE_PRINTF(",CL\n");
684 TRACE_AND_STEP();
685 destval = fetch_data_long(destoffset);
686 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
687 store_data_long(destoffset, destval);
688 } else {
689 u16 destval;
690 u16 *shiftreg;
692 destoffset = decode_rm10_address(rl);
693 DECODE_PRINTF(",");
694 shiftreg = DECODE_RM_WORD_REGISTER(rh);
695 DECODE_PRINTF(",CL\n");
696 TRACE_AND_STEP();
697 destval = fetch_data_word(destoffset);
698 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
699 store_data_word(destoffset, destval);
701 break;
702 case 3: /* register to register */
703 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
704 u32 *destreg,*shiftreg;
706 destreg = DECODE_RM_LONG_REGISTER(rl);
707 DECODE_PRINTF(",");
708 shiftreg = DECODE_RM_LONG_REGISTER(rh);
709 DECODE_PRINTF(",CL\n");
710 TRACE_AND_STEP();
711 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
712 } else {
713 u16 *destreg,*shiftreg;
715 destreg = DECODE_RM_WORD_REGISTER(rl);
716 DECODE_PRINTF(",");
717 shiftreg = DECODE_RM_WORD_REGISTER(rh);
718 DECODE_PRINTF(",CL\n");
719 TRACE_AND_STEP();
720 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
722 break;
724 DECODE_CLEAR_SEGOVR();
725 END_OF_INSTR();
728 /****************************************************************************
729 REMARKS:
730 Handles opcode 0x0f,0xa8
731 ****************************************************************************/
732 static void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
734 START_OF_INSTR();
735 DECODE_PRINTF("PUSH\tGS\n");
736 TRACE_AND_STEP();
737 push_word(M.x86.R_GS);
738 DECODE_CLEAR_SEGOVR();
739 END_OF_INSTR();
742 /****************************************************************************
743 REMARKS:
744 Handles opcode 0x0f,0xa9
745 ****************************************************************************/
746 static void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
748 START_OF_INSTR();
749 DECODE_PRINTF("POP\tGS\n");
750 TRACE_AND_STEP();
751 M.x86.R_GS = pop_word();
752 DECODE_CLEAR_SEGOVR();
753 END_OF_INSTR();
756 /****************************************************************************
757 REMARKS:
758 Handles opcode 0x0f,0xab
759 ****************************************************************************/
760 static void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
762 int mod, rl, rh;
763 uint srcoffset;
764 int bit,disp;
766 START_OF_INSTR();
767 DECODE_PRINTF("BTS\t");
768 FETCH_DECODE_MODRM(mod, rh, rl);
769 switch (mod) {
770 case 0:
771 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
772 u32 srcval,mask;
773 u32 *shiftreg;
775 srcoffset = decode_rm00_address(rl);
776 DECODE_PRINTF(",");
777 shiftreg = DECODE_RM_LONG_REGISTER(rh);
778 TRACE_AND_STEP();
779 bit = *shiftreg & 0x1F;
780 disp = (s16)*shiftreg >> 5;
781 srcval = fetch_data_long(srcoffset+disp);
782 mask = (0x1 << bit);
783 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
784 store_data_long(srcoffset+disp, srcval | mask);
785 } else {
786 u16 srcval,mask;
787 u16 *shiftreg;
789 srcoffset = decode_rm00_address(rl);
790 DECODE_PRINTF(",");
791 shiftreg = DECODE_RM_WORD_REGISTER(rh);
792 TRACE_AND_STEP();
793 bit = *shiftreg & 0xF;
794 disp = (s16)*shiftreg >> 4;
795 srcval = fetch_data_word(srcoffset+disp);
796 mask = (u16)(0x1 << bit);
797 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
798 store_data_word(srcoffset+disp, srcval | mask);
800 break;
801 case 1:
802 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
803 u32 srcval,mask;
804 u32 *shiftreg;
806 srcoffset = decode_rm01_address(rl);
807 DECODE_PRINTF(",");
808 shiftreg = DECODE_RM_LONG_REGISTER(rh);
809 TRACE_AND_STEP();
810 bit = *shiftreg & 0x1F;
811 disp = (s16)*shiftreg >> 5;
812 srcval = fetch_data_long(srcoffset+disp);
813 mask = (0x1 << bit);
814 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
815 store_data_long(srcoffset+disp, srcval | mask);
816 } else {
817 u16 srcval,mask;
818 u16 *shiftreg;
820 srcoffset = decode_rm01_address(rl);
821 DECODE_PRINTF(",");
822 shiftreg = DECODE_RM_WORD_REGISTER(rh);
823 TRACE_AND_STEP();
824 bit = *shiftreg & 0xF;
825 disp = (s16)*shiftreg >> 4;
826 srcval = fetch_data_word(srcoffset+disp);
827 mask = (u16)(0x1 << bit);
828 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
829 store_data_word(srcoffset+disp, srcval | mask);
831 break;
832 case 2:
833 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
834 u32 srcval,mask;
835 u32 *shiftreg;
837 srcoffset = decode_rm10_address(rl);
838 DECODE_PRINTF(",");
839 shiftreg = DECODE_RM_LONG_REGISTER(rh);
840 TRACE_AND_STEP();
841 bit = *shiftreg & 0x1F;
842 disp = (s16)*shiftreg >> 5;
843 srcval = fetch_data_long(srcoffset+disp);
844 mask = (0x1 << bit);
845 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
846 store_data_long(srcoffset+disp, srcval | mask);
847 } else {
848 u16 srcval,mask;
849 u16 *shiftreg;
851 srcoffset = decode_rm10_address(rl);
852 DECODE_PRINTF(",");
853 shiftreg = DECODE_RM_WORD_REGISTER(rh);
854 TRACE_AND_STEP();
855 bit = *shiftreg & 0xF;
856 disp = (s16)*shiftreg >> 4;
857 srcval = fetch_data_word(srcoffset+disp);
858 mask = (u16)(0x1 << bit);
859 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
860 store_data_word(srcoffset+disp, srcval | mask);
862 break;
863 case 3: /* register to register */
864 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
865 u32 *srcreg,*shiftreg;
866 u32 mask;
868 srcreg = DECODE_RM_LONG_REGISTER(rl);
869 DECODE_PRINTF(",");
870 shiftreg = DECODE_RM_LONG_REGISTER(rh);
871 TRACE_AND_STEP();
872 bit = *shiftreg & 0x1F;
873 mask = (0x1 << bit);
874 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
875 *srcreg |= mask;
876 } else {
877 u16 *srcreg,*shiftreg;
878 u16 mask;
880 srcreg = DECODE_RM_WORD_REGISTER(rl);
881 DECODE_PRINTF(",");
882 shiftreg = DECODE_RM_WORD_REGISTER(rh);
883 TRACE_AND_STEP();
884 bit = *shiftreg & 0xF;
885 mask = (u16)(0x1 << bit);
886 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
887 *srcreg |= mask;
889 break;
891 DECODE_CLEAR_SEGOVR();
892 END_OF_INSTR();
895 /****************************************************************************
896 REMARKS:
897 Handles opcode 0x0f,0xac
898 ****************************************************************************/
899 static void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
901 int mod, rl, rh;
902 uint destoffset;
903 u8 shift;
905 START_OF_INSTR();
906 DECODE_PRINTF("SHLD\t");
907 FETCH_DECODE_MODRM(mod, rh, rl);
908 switch (mod) {
909 case 0:
910 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
911 u32 destval;
912 u32 *shiftreg;
914 destoffset = decode_rm00_address(rl);
915 DECODE_PRINTF(",");
916 shiftreg = DECODE_RM_LONG_REGISTER(rh);
917 DECODE_PRINTF(",");
918 shift = fetch_byte_imm();
919 DECODE_PRINTF2("%d\n", shift);
920 TRACE_AND_STEP();
921 destval = fetch_data_long(destoffset);
922 destval = shrd_long(destval,*shiftreg,shift);
923 store_data_long(destoffset, destval);
924 } else {
925 u16 destval;
926 u16 *shiftreg;
928 destoffset = decode_rm00_address(rl);
929 DECODE_PRINTF(",");
930 shiftreg = DECODE_RM_WORD_REGISTER(rh);
931 DECODE_PRINTF(",");
932 shift = fetch_byte_imm();
933 DECODE_PRINTF2("%d\n", shift);
934 TRACE_AND_STEP();
935 destval = fetch_data_word(destoffset);
936 destval = shrd_word(destval,*shiftreg,shift);
937 store_data_word(destoffset, destval);
939 break;
940 case 1:
941 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
942 u32 destval;
943 u32 *shiftreg;
945 destoffset = decode_rm01_address(rl);
946 DECODE_PRINTF(",");
947 shiftreg = DECODE_RM_LONG_REGISTER(rh);
948 DECODE_PRINTF(",");
949 shift = fetch_byte_imm();
950 DECODE_PRINTF2("%d\n", shift);
951 TRACE_AND_STEP();
952 destval = fetch_data_long(destoffset);
953 destval = shrd_long(destval,*shiftreg,shift);
954 store_data_long(destoffset, destval);
955 } else {
956 u16 destval;
957 u16 *shiftreg;
959 destoffset = decode_rm01_address(rl);
960 DECODE_PRINTF(",");
961 shiftreg = DECODE_RM_WORD_REGISTER(rh);
962 DECODE_PRINTF(",");
963 shift = fetch_byte_imm();
964 DECODE_PRINTF2("%d\n", shift);
965 TRACE_AND_STEP();
966 destval = fetch_data_word(destoffset);
967 destval = shrd_word(destval,*shiftreg,shift);
968 store_data_word(destoffset, destval);
970 break;
971 case 2:
972 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
973 u32 destval;
974 u32 *shiftreg;
976 destoffset = decode_rm10_address(rl);
977 DECODE_PRINTF(",");
978 shiftreg = DECODE_RM_LONG_REGISTER(rh);
979 DECODE_PRINTF(",");
980 shift = fetch_byte_imm();
981 DECODE_PRINTF2("%d\n", shift);
982 TRACE_AND_STEP();
983 destval = fetch_data_long(destoffset);
984 destval = shrd_long(destval,*shiftreg,shift);
985 store_data_long(destoffset, destval);
986 } else {
987 u16 destval;
988 u16 *shiftreg;
990 destoffset = decode_rm10_address(rl);
991 DECODE_PRINTF(",");
992 shiftreg = DECODE_RM_WORD_REGISTER(rh);
993 DECODE_PRINTF(",");
994 shift = fetch_byte_imm();
995 DECODE_PRINTF2("%d\n", shift);
996 TRACE_AND_STEP();
997 destval = fetch_data_word(destoffset);
998 destval = shrd_word(destval,*shiftreg,shift);
999 store_data_word(destoffset, destval);
1001 break;
1002 case 3: /* register to register */
1003 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1004 u32 *destreg,*shiftreg;
1006 destreg = DECODE_RM_LONG_REGISTER(rl);
1007 DECODE_PRINTF(",");
1008 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1009 DECODE_PRINTF(",");
1010 shift = fetch_byte_imm();
1011 DECODE_PRINTF2("%d\n", shift);
1012 TRACE_AND_STEP();
1013 *destreg = shrd_long(*destreg,*shiftreg,shift);
1014 } else {
1015 u16 *destreg,*shiftreg;
1017 destreg = DECODE_RM_WORD_REGISTER(rl);
1018 DECODE_PRINTF(",");
1019 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1020 DECODE_PRINTF(",");
1021 shift = fetch_byte_imm();
1022 DECODE_PRINTF2("%d\n", shift);
1023 TRACE_AND_STEP();
1024 *destreg = shrd_word(*destreg,*shiftreg,shift);
1026 break;
1028 DECODE_CLEAR_SEGOVR();
1029 END_OF_INSTR();
1032 /****************************************************************************
1033 REMARKS:
1034 Handles opcode 0x0f,0xad
1035 ****************************************************************************/
1036 static void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
1038 int mod, rl, rh;
1039 uint destoffset;
1041 START_OF_INSTR();
1042 DECODE_PRINTF("SHLD\t");
1043 FETCH_DECODE_MODRM(mod, rh, rl);
1044 switch (mod) {
1045 case 0:
1046 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1047 u32 destval;
1048 u32 *shiftreg;
1050 destoffset = decode_rm00_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_rm00_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 1:
1073 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1074 u32 destval;
1075 u32 *shiftreg;
1077 destoffset = decode_rm01_address(rl);
1078 DECODE_PRINTF(",");
1079 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1080 DECODE_PRINTF(",CL\n");
1081 TRACE_AND_STEP();
1082 destval = fetch_data_long(destoffset);
1083 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1084 store_data_long(destoffset, destval);
1085 } else {
1086 u16 destval;
1087 u16 *shiftreg;
1089 destoffset = decode_rm01_address(rl);
1090 DECODE_PRINTF(",");
1091 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1092 DECODE_PRINTF(",CL\n");
1093 TRACE_AND_STEP();
1094 destval = fetch_data_word(destoffset);
1095 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1096 store_data_word(destoffset, destval);
1098 break;
1099 case 2:
1100 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1101 u32 destval;
1102 u32 *shiftreg;
1104 destoffset = decode_rm10_address(rl);
1105 DECODE_PRINTF(",");
1106 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1107 DECODE_PRINTF(",CL\n");
1108 TRACE_AND_STEP();
1109 destval = fetch_data_long(destoffset);
1110 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1111 store_data_long(destoffset, destval);
1112 } else {
1113 u16 destval;
1114 u16 *shiftreg;
1116 destoffset = decode_rm10_address(rl);
1117 DECODE_PRINTF(",");
1118 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1119 DECODE_PRINTF(",CL\n");
1120 TRACE_AND_STEP();
1121 destval = fetch_data_word(destoffset);
1122 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1123 store_data_word(destoffset, destval);
1125 break;
1126 case 3: /* register to register */
1127 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1128 u32 *destreg,*shiftreg;
1130 destreg = DECODE_RM_LONG_REGISTER(rl);
1131 DECODE_PRINTF(",");
1132 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1133 DECODE_PRINTF(",CL\n");
1134 TRACE_AND_STEP();
1135 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
1136 } else {
1137 u16 *destreg,*shiftreg;
1139 destreg = DECODE_RM_WORD_REGISTER(rl);
1140 DECODE_PRINTF(",");
1141 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1142 DECODE_PRINTF(",CL\n");
1143 TRACE_AND_STEP();
1144 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
1146 break;
1148 DECODE_CLEAR_SEGOVR();
1149 END_OF_INSTR();
1152 /****************************************************************************
1153 REMARKS:
1154 Handles opcode 0x0f,0xaf
1155 ****************************************************************************/
1156 static void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
1158 int mod, rl, rh;
1159 uint srcoffset;
1161 START_OF_INSTR();
1162 DECODE_PRINTF("IMUL\t");
1163 FETCH_DECODE_MODRM(mod, rh, rl);
1164 switch (mod) {
1165 case 0:
1166 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1167 u32 *destreg;
1168 u32 srcval;
1169 u32 res_lo,res_hi;
1171 destreg = DECODE_RM_LONG_REGISTER(rh);
1172 DECODE_PRINTF(",");
1173 srcoffset = decode_rm00_address(rl);
1174 srcval = fetch_data_long(srcoffset);
1175 TRACE_AND_STEP();
1176 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1177 if (res_hi != 0) {
1178 SET_FLAG(F_CF);
1179 SET_FLAG(F_OF);
1180 } else {
1181 CLEAR_FLAG(F_CF);
1182 CLEAR_FLAG(F_OF);
1184 *destreg = (u32)res_lo;
1185 } else {
1186 u16 *destreg;
1187 u16 srcval;
1188 u32 res;
1190 destreg = DECODE_RM_WORD_REGISTER(rh);
1191 DECODE_PRINTF(",");
1192 srcoffset = decode_rm00_address(rl);
1193 srcval = fetch_data_word(srcoffset);
1194 TRACE_AND_STEP();
1195 res = (s16)*destreg * (s16)srcval;
1196 if (res > 0xFFFF) {
1197 SET_FLAG(F_CF);
1198 SET_FLAG(F_OF);
1199 } else {
1200 CLEAR_FLAG(F_CF);
1201 CLEAR_FLAG(F_OF);
1203 *destreg = (u16)res;
1205 break;
1206 case 1:
1207 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1208 u32 *destreg;
1209 u32 srcval;
1210 u32 res_lo,res_hi;
1212 destreg = DECODE_RM_LONG_REGISTER(rh);
1213 DECODE_PRINTF(",");
1214 srcoffset = decode_rm01_address(rl);
1215 srcval = fetch_data_long(srcoffset);
1216 TRACE_AND_STEP();
1217 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1218 if (res_hi != 0) {
1219 SET_FLAG(F_CF);
1220 SET_FLAG(F_OF);
1221 } else {
1222 CLEAR_FLAG(F_CF);
1223 CLEAR_FLAG(F_OF);
1225 *destreg = (u32)res_lo;
1226 } else {
1227 u16 *destreg;
1228 u16 srcval;
1229 u32 res;
1231 destreg = DECODE_RM_WORD_REGISTER(rh);
1232 DECODE_PRINTF(",");
1233 srcoffset = decode_rm01_address(rl);
1234 srcval = fetch_data_word(srcoffset);
1235 TRACE_AND_STEP();
1236 res = (s16)*destreg * (s16)srcval;
1237 if (res > 0xFFFF) {
1238 SET_FLAG(F_CF);
1239 SET_FLAG(F_OF);
1240 } else {
1241 CLEAR_FLAG(F_CF);
1242 CLEAR_FLAG(F_OF);
1244 *destreg = (u16)res;
1246 break;
1247 case 2:
1248 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1249 u32 *destreg;
1250 u32 srcval;
1251 u32 res_lo,res_hi;
1253 destreg = DECODE_RM_LONG_REGISTER(rh);
1254 DECODE_PRINTF(",");
1255 srcoffset = decode_rm10_address(rl);
1256 srcval = fetch_data_long(srcoffset);
1257 TRACE_AND_STEP();
1258 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1259 if (res_hi != 0) {
1260 SET_FLAG(F_CF);
1261 SET_FLAG(F_OF);
1262 } else {
1263 CLEAR_FLAG(F_CF);
1264 CLEAR_FLAG(F_OF);
1266 *destreg = (u32)res_lo;
1267 } else {
1268 u16 *destreg;
1269 u16 srcval;
1270 u32 res;
1272 destreg = DECODE_RM_WORD_REGISTER(rh);
1273 DECODE_PRINTF(",");
1274 srcoffset = decode_rm10_address(rl);
1275 srcval = fetch_data_word(srcoffset);
1276 TRACE_AND_STEP();
1277 res = (s16)*destreg * (s16)srcval;
1278 if (res > 0xFFFF) {
1279 SET_FLAG(F_CF);
1280 SET_FLAG(F_OF);
1281 } else {
1282 CLEAR_FLAG(F_CF);
1283 CLEAR_FLAG(F_OF);
1285 *destreg = (u16)res;
1287 break;
1288 case 3: /* register to register */
1289 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1290 u32 *destreg,*srcreg;
1291 u32 res_lo,res_hi;
1293 destreg = DECODE_RM_LONG_REGISTER(rh);
1294 DECODE_PRINTF(",");
1295 srcreg = DECODE_RM_LONG_REGISTER(rl);
1296 TRACE_AND_STEP();
1297 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
1298 if (res_hi != 0) {
1299 SET_FLAG(F_CF);
1300 SET_FLAG(F_OF);
1301 } else {
1302 CLEAR_FLAG(F_CF);
1303 CLEAR_FLAG(F_OF);
1305 *destreg = (u32)res_lo;
1306 } else {
1307 u16 *destreg,*srcreg;
1308 u32 res;
1310 destreg = DECODE_RM_WORD_REGISTER(rh);
1311 DECODE_PRINTF(",");
1312 srcreg = DECODE_RM_WORD_REGISTER(rl);
1313 res = (s16)*destreg * (s16)*srcreg;
1314 if (res > 0xFFFF) {
1315 SET_FLAG(F_CF);
1316 SET_FLAG(F_OF);
1317 } else {
1318 CLEAR_FLAG(F_CF);
1319 CLEAR_FLAG(F_OF);
1321 *destreg = (u16)res;
1323 break;
1325 DECODE_CLEAR_SEGOVR();
1326 END_OF_INSTR();
1329 /****************************************************************************
1330 REMARKS:
1331 Handles opcode 0x0f,0xb2
1332 ****************************************************************************/
1333 static void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
1335 int mod, rh, rl;
1336 u16 *dstreg;
1337 uint srcoffset;
1339 START_OF_INSTR();
1340 DECODE_PRINTF("LSS\t");
1341 FETCH_DECODE_MODRM(mod, rh, rl);
1342 switch (mod) {
1343 case 0:
1344 dstreg = DECODE_RM_WORD_REGISTER(rh);
1345 DECODE_PRINTF(",");
1346 srcoffset = decode_rm00_address(rl);
1347 DECODE_PRINTF("\n");
1348 TRACE_AND_STEP();
1349 *dstreg = fetch_data_word(srcoffset);
1350 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1351 break;
1352 case 1:
1353 dstreg = DECODE_RM_WORD_REGISTER(rh);
1354 DECODE_PRINTF(",");
1355 srcoffset = decode_rm01_address(rl);
1356 DECODE_PRINTF("\n");
1357 TRACE_AND_STEP();
1358 *dstreg = fetch_data_word(srcoffset);
1359 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1360 break;
1361 case 2:
1362 dstreg = DECODE_RM_WORD_REGISTER(rh);
1363 DECODE_PRINTF(",");
1364 srcoffset = decode_rm10_address(rl);
1365 DECODE_PRINTF("\n");
1366 TRACE_AND_STEP();
1367 *dstreg = fetch_data_word(srcoffset);
1368 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1369 break;
1370 case 3: /* register to register */
1371 /* UNDEFINED! */
1372 TRACE_AND_STEP();
1374 DECODE_CLEAR_SEGOVR();
1375 END_OF_INSTR();
1378 /****************************************************************************
1379 REMARKS:
1380 Handles opcode 0x0f,0xb3
1381 ****************************************************************************/
1382 static void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
1384 int mod, rl, rh;
1385 uint srcoffset;
1386 int bit,disp;
1388 START_OF_INSTR();
1389 DECODE_PRINTF("BTR\t");
1390 FETCH_DECODE_MODRM(mod, rh, rl);
1391 switch (mod) {
1392 case 0:
1393 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1394 u32 srcval,mask;
1395 u32 *shiftreg;
1397 srcoffset = decode_rm00_address(rl);
1398 DECODE_PRINTF(",");
1399 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1400 TRACE_AND_STEP();
1401 bit = *shiftreg & 0x1F;
1402 disp = (s16)*shiftreg >> 5;
1403 srcval = fetch_data_long(srcoffset+disp);
1404 mask = (0x1 << bit);
1405 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1406 store_data_long(srcoffset+disp, srcval & ~mask);
1407 } else {
1408 u16 srcval,mask;
1409 u16 *shiftreg;
1411 srcoffset = decode_rm00_address(rl);
1412 DECODE_PRINTF(",");
1413 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1414 TRACE_AND_STEP();
1415 bit = *shiftreg & 0xF;
1416 disp = (s16)*shiftreg >> 4;
1417 srcval = fetch_data_word(srcoffset+disp);
1418 mask = (u16)(0x1 << bit);
1419 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1420 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1422 break;
1423 case 1:
1424 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1425 u32 srcval,mask;
1426 u32 *shiftreg;
1428 srcoffset = decode_rm01_address(rl);
1429 DECODE_PRINTF(",");
1430 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1431 TRACE_AND_STEP();
1432 bit = *shiftreg & 0x1F;
1433 disp = (s16)*shiftreg >> 5;
1434 srcval = fetch_data_long(srcoffset+disp);
1435 mask = (0x1 << bit);
1436 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1437 store_data_long(srcoffset+disp, srcval & ~mask);
1438 } else {
1439 u16 srcval,mask;
1440 u16 *shiftreg;
1442 srcoffset = decode_rm01_address(rl);
1443 DECODE_PRINTF(",");
1444 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1445 TRACE_AND_STEP();
1446 bit = *shiftreg & 0xF;
1447 disp = (s16)*shiftreg >> 4;
1448 srcval = fetch_data_word(srcoffset+disp);
1449 mask = (u16)(0x1 << bit);
1450 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1451 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1453 break;
1454 case 2:
1455 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1456 u32 srcval,mask;
1457 u32 *shiftreg;
1459 srcoffset = decode_rm10_address(rl);
1460 DECODE_PRINTF(",");
1461 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1462 TRACE_AND_STEP();
1463 bit = *shiftreg & 0x1F;
1464 disp = (s16)*shiftreg >> 5;
1465 srcval = fetch_data_long(srcoffset+disp);
1466 mask = (0x1 << bit);
1467 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1468 store_data_long(srcoffset+disp, srcval & ~mask);
1469 } else {
1470 u16 srcval,mask;
1471 u16 *shiftreg;
1473 srcoffset = decode_rm10_address(rl);
1474 DECODE_PRINTF(",");
1475 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1476 TRACE_AND_STEP();
1477 bit = *shiftreg & 0xF;
1478 disp = (s16)*shiftreg >> 4;
1479 srcval = fetch_data_word(srcoffset+disp);
1480 mask = (u16)(0x1 << bit);
1481 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1482 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1484 break;
1485 case 3: /* register to register */
1486 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1487 u32 *srcreg,*shiftreg;
1488 u32 mask;
1490 srcreg = DECODE_RM_LONG_REGISTER(rl);
1491 DECODE_PRINTF(",");
1492 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1493 TRACE_AND_STEP();
1494 bit = *shiftreg & 0x1F;
1495 mask = (0x1 << bit);
1496 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1497 *srcreg &= ~mask;
1498 } else {
1499 u16 *srcreg,*shiftreg;
1500 u16 mask;
1502 srcreg = DECODE_RM_WORD_REGISTER(rl);
1503 DECODE_PRINTF(",");
1504 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1505 TRACE_AND_STEP();
1506 bit = *shiftreg & 0xF;
1507 mask = (u16)(0x1 << bit);
1508 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1509 *srcreg &= ~mask;
1511 break;
1513 DECODE_CLEAR_SEGOVR();
1514 END_OF_INSTR();
1517 /****************************************************************************
1518 REMARKS:
1519 Handles opcode 0x0f,0xb4
1520 ****************************************************************************/
1521 static void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
1523 int mod, rh, rl;
1524 u16 *dstreg;
1525 uint srcoffset;
1527 START_OF_INSTR();
1528 DECODE_PRINTF("LFS\t");
1529 FETCH_DECODE_MODRM(mod, rh, rl);
1530 switch (mod) {
1531 case 0:
1532 dstreg = DECODE_RM_WORD_REGISTER(rh);
1533 DECODE_PRINTF(",");
1534 srcoffset = decode_rm00_address(rl);
1535 DECODE_PRINTF("\n");
1536 TRACE_AND_STEP();
1537 *dstreg = fetch_data_word(srcoffset);
1538 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1539 break;
1540 case 1:
1541 dstreg = DECODE_RM_WORD_REGISTER(rh);
1542 DECODE_PRINTF(",");
1543 srcoffset = decode_rm01_address(rl);
1544 DECODE_PRINTF("\n");
1545 TRACE_AND_STEP();
1546 *dstreg = fetch_data_word(srcoffset);
1547 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1548 break;
1549 case 2:
1550 dstreg = DECODE_RM_WORD_REGISTER(rh);
1551 DECODE_PRINTF(",");
1552 srcoffset = decode_rm10_address(rl);
1553 DECODE_PRINTF("\n");
1554 TRACE_AND_STEP();
1555 *dstreg = fetch_data_word(srcoffset);
1556 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1557 break;
1558 case 3: /* register to register */
1559 /* UNDEFINED! */
1560 TRACE_AND_STEP();
1562 DECODE_CLEAR_SEGOVR();
1563 END_OF_INSTR();
1566 /****************************************************************************
1567 REMARKS:
1568 Handles opcode 0x0f,0xb5
1569 ****************************************************************************/
1570 static void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
1572 int mod, rh, rl;
1573 u16 *dstreg;
1574 uint srcoffset;
1576 START_OF_INSTR();
1577 DECODE_PRINTF("LGS\t");
1578 FETCH_DECODE_MODRM(mod, rh, rl);
1579 switch (mod) {
1580 case 0:
1581 dstreg = DECODE_RM_WORD_REGISTER(rh);
1582 DECODE_PRINTF(",");
1583 srcoffset = decode_rm00_address(rl);
1584 DECODE_PRINTF("\n");
1585 TRACE_AND_STEP();
1586 *dstreg = fetch_data_word(srcoffset);
1587 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1588 break;
1589 case 1:
1590 dstreg = DECODE_RM_WORD_REGISTER(rh);
1591 DECODE_PRINTF(",");
1592 srcoffset = decode_rm01_address(rl);
1593 DECODE_PRINTF("\n");
1594 TRACE_AND_STEP();
1595 *dstreg = fetch_data_word(srcoffset);
1596 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1597 break;
1598 case 2:
1599 dstreg = DECODE_RM_WORD_REGISTER(rh);
1600 DECODE_PRINTF(",");
1601 srcoffset = decode_rm10_address(rl);
1602 DECODE_PRINTF("\n");
1603 TRACE_AND_STEP();
1604 *dstreg = fetch_data_word(srcoffset);
1605 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1606 break;
1607 case 3: /* register to register */
1608 /* UNDEFINED! */
1609 TRACE_AND_STEP();
1611 DECODE_CLEAR_SEGOVR();
1612 END_OF_INSTR();
1615 /****************************************************************************
1616 REMARKS:
1617 Handles opcode 0x0f,0xb6
1618 ****************************************************************************/
1619 static void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1621 int mod, rl, rh;
1622 uint srcoffset;
1624 START_OF_INSTR();
1625 DECODE_PRINTF("MOVZX\t");
1626 FETCH_DECODE_MODRM(mod, rh, rl);
1627 switch (mod) {
1628 case 0:
1629 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1630 u32 *destreg;
1631 u32 srcval;
1633 destreg = DECODE_RM_LONG_REGISTER(rh);
1634 DECODE_PRINTF(",");
1635 srcoffset = decode_rm00_address(rl);
1636 srcval = fetch_data_byte(srcoffset);
1637 DECODE_PRINTF("\n");
1638 TRACE_AND_STEP();
1639 *destreg = srcval;
1640 } else {
1641 u16 *destreg;
1642 u16 srcval;
1644 destreg = DECODE_RM_WORD_REGISTER(rh);
1645 DECODE_PRINTF(",");
1646 srcoffset = decode_rm00_address(rl);
1647 srcval = fetch_data_byte(srcoffset);
1648 DECODE_PRINTF("\n");
1649 TRACE_AND_STEP();
1650 *destreg = srcval;
1652 break;
1653 case 1:
1654 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1655 u32 *destreg;
1656 u32 srcval;
1658 destreg = DECODE_RM_LONG_REGISTER(rh);
1659 DECODE_PRINTF(",");
1660 srcoffset = decode_rm01_address(rl);
1661 srcval = fetch_data_byte(srcoffset);
1662 DECODE_PRINTF("\n");
1663 TRACE_AND_STEP();
1664 *destreg = srcval;
1665 } else {
1666 u16 *destreg;
1667 u16 srcval;
1669 destreg = DECODE_RM_WORD_REGISTER(rh);
1670 DECODE_PRINTF(",");
1671 srcoffset = decode_rm01_address(rl);
1672 srcval = fetch_data_byte(srcoffset);
1673 DECODE_PRINTF("\n");
1674 TRACE_AND_STEP();
1675 *destreg = srcval;
1677 break;
1678 case 2:
1679 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1680 u32 *destreg;
1681 u32 srcval;
1683 destreg = DECODE_RM_LONG_REGISTER(rh);
1684 DECODE_PRINTF(",");
1685 srcoffset = decode_rm10_address(rl);
1686 srcval = fetch_data_byte(srcoffset);
1687 DECODE_PRINTF("\n");
1688 TRACE_AND_STEP();
1689 *destreg = srcval;
1690 } else {
1691 u16 *destreg;
1692 u16 srcval;
1694 destreg = DECODE_RM_WORD_REGISTER(rh);
1695 DECODE_PRINTF(",");
1696 srcoffset = decode_rm10_address(rl);
1697 srcval = fetch_data_byte(srcoffset);
1698 DECODE_PRINTF("\n");
1699 TRACE_AND_STEP();
1700 *destreg = srcval;
1702 break;
1703 case 3: /* register to register */
1704 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1705 u32 *destreg;
1706 u8 *srcreg;
1708 destreg = DECODE_RM_LONG_REGISTER(rh);
1709 DECODE_PRINTF(",");
1710 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1711 DECODE_PRINTF("\n");
1712 TRACE_AND_STEP();
1713 *destreg = *srcreg;
1714 } else {
1715 u16 *destreg;
1716 u8 *srcreg;
1718 destreg = DECODE_RM_WORD_REGISTER(rh);
1719 DECODE_PRINTF(",");
1720 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1721 DECODE_PRINTF("\n");
1722 TRACE_AND_STEP();
1723 *destreg = *srcreg;
1725 break;
1727 DECODE_CLEAR_SEGOVR();
1728 END_OF_INSTR();
1731 /****************************************************************************
1732 REMARKS:
1733 Handles opcode 0x0f,0xb7
1734 ****************************************************************************/
1735 static void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1737 int mod, rl, rh;
1738 uint srcoffset;
1739 u32 *destreg;
1740 u32 srcval;
1741 u16 *srcreg;
1743 START_OF_INSTR();
1744 DECODE_PRINTF("MOVZX\t");
1745 FETCH_DECODE_MODRM(mod, rh, rl);
1746 switch (mod) {
1747 case 0:
1748 destreg = DECODE_RM_LONG_REGISTER(rh);
1749 DECODE_PRINTF(",");
1750 srcoffset = decode_rm00_address(rl);
1751 srcval = fetch_data_word(srcoffset);
1752 DECODE_PRINTF("\n");
1753 TRACE_AND_STEP();
1754 *destreg = srcval;
1755 break;
1756 case 1:
1757 destreg = DECODE_RM_LONG_REGISTER(rh);
1758 DECODE_PRINTF(",");
1759 srcoffset = decode_rm01_address(rl);
1760 srcval = fetch_data_word(srcoffset);
1761 DECODE_PRINTF("\n");
1762 TRACE_AND_STEP();
1763 *destreg = srcval;
1764 break;
1765 case 2:
1766 destreg = DECODE_RM_LONG_REGISTER(rh);
1767 DECODE_PRINTF(",");
1768 srcoffset = decode_rm10_address(rl);
1769 srcval = fetch_data_word(srcoffset);
1770 DECODE_PRINTF("\n");
1771 TRACE_AND_STEP();
1772 *destreg = srcval;
1773 break;
1774 case 3: /* register to register */
1775 destreg = DECODE_RM_LONG_REGISTER(rh);
1776 DECODE_PRINTF(",");
1777 srcreg = DECODE_RM_WORD_REGISTER(rl);
1778 DECODE_PRINTF("\n");
1779 TRACE_AND_STEP();
1780 *destreg = *srcreg;
1781 break;
1783 DECODE_CLEAR_SEGOVR();
1784 END_OF_INSTR();
1787 /****************************************************************************
1788 REMARKS:
1789 Handles opcode 0x0f,0xba
1790 ****************************************************************************/
1791 static void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1793 int mod, rl, rh;
1794 uint srcoffset;
1795 int bit;
1797 START_OF_INSTR();
1798 FETCH_DECODE_MODRM(mod, rh, rl);
1799 switch (rh) {
1800 case 4:
1801 DECODE_PRINTF("BT\t");
1802 break;
1803 case 5:
1804 DECODE_PRINTF("BTS\t");
1805 break;
1806 case 6:
1807 DECODE_PRINTF("BTR\t");
1808 break;
1809 case 7:
1810 DECODE_PRINTF("BTC\t");
1811 break;
1812 default:
1813 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1814 TRACE_REGS();
1815 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1816 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1817 HALT_SYS();
1819 switch (mod) {
1820 case 0:
1821 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1822 u32 srcval, mask;
1823 u8 shift;
1825 srcoffset = decode_rm00_address(rl);
1826 DECODE_PRINTF(",");
1827 shift = fetch_byte_imm();
1828 TRACE_AND_STEP();
1829 bit = shift & 0x1F;
1830 srcval = fetch_data_long(srcoffset);
1831 mask = (0x1 << bit);
1832 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1833 switch (rh) {
1834 case 5:
1835 store_data_long(srcoffset, srcval | mask);
1836 break;
1837 case 6:
1838 store_data_long(srcoffset, srcval & ~mask);
1839 break;
1840 case 7:
1841 store_data_long(srcoffset, srcval ^ mask);
1842 break;
1843 default:
1844 break;
1846 } else {
1847 u16 srcval, mask;
1848 u8 shift;
1850 srcoffset = decode_rm00_address(rl);
1851 DECODE_PRINTF(",");
1852 shift = fetch_byte_imm();
1853 TRACE_AND_STEP();
1854 bit = shift & 0xF;
1855 srcval = fetch_data_word(srcoffset);
1856 mask = (0x1 << bit);
1857 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1858 switch (rh) {
1859 case 5:
1860 store_data_word(srcoffset, srcval | mask);
1861 break;
1862 case 6:
1863 store_data_word(srcoffset, srcval & ~mask);
1864 break;
1865 case 7:
1866 store_data_word(srcoffset, srcval ^ mask);
1867 break;
1868 default:
1869 break;
1872 break;
1873 case 1:
1874 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1875 u32 srcval, mask;
1876 u8 shift;
1878 srcoffset = decode_rm01_address(rl);
1879 DECODE_PRINTF(",");
1880 shift = fetch_byte_imm();
1881 TRACE_AND_STEP();
1882 bit = shift & 0x1F;
1883 srcval = fetch_data_long(srcoffset);
1884 mask = (0x1 << bit);
1885 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1886 switch (rh) {
1887 case 5:
1888 store_data_long(srcoffset, srcval | mask);
1889 break;
1890 case 6:
1891 store_data_long(srcoffset, srcval & ~mask);
1892 break;
1893 case 7:
1894 store_data_long(srcoffset, srcval ^ mask);
1895 break;
1896 default:
1897 break;
1899 } else {
1900 u16 srcval, mask;
1901 u8 shift;
1903 srcoffset = decode_rm01_address(rl);
1904 DECODE_PRINTF(",");
1905 shift = fetch_byte_imm();
1906 TRACE_AND_STEP();
1907 bit = shift & 0xF;
1908 srcval = fetch_data_word(srcoffset);
1909 mask = (0x1 << bit);
1910 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1911 switch (rh) {
1912 case 5:
1913 store_data_word(srcoffset, srcval | mask);
1914 break;
1915 case 6:
1916 store_data_word(srcoffset, srcval & ~mask);
1917 break;
1918 case 7:
1919 store_data_word(srcoffset, srcval ^ mask);
1920 break;
1921 default:
1922 break;
1925 break;
1926 case 2:
1927 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1928 u32 srcval, mask;
1929 u8 shift;
1931 srcoffset = decode_rm10_address(rl);
1932 DECODE_PRINTF(",");
1933 shift = fetch_byte_imm();
1934 TRACE_AND_STEP();
1935 bit = shift & 0x1F;
1936 srcval = fetch_data_long(srcoffset);
1937 mask = (0x1 << bit);
1938 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1939 switch (rh) {
1940 case 5:
1941 store_data_long(srcoffset, srcval | mask);
1942 break;
1943 case 6:
1944 store_data_long(srcoffset, srcval & ~mask);
1945 break;
1946 case 7:
1947 store_data_long(srcoffset, srcval ^ mask);
1948 break;
1949 default:
1950 break;
1952 } else {
1953 u16 srcval, mask;
1954 u8 shift;
1956 srcoffset = decode_rm10_address(rl);
1957 DECODE_PRINTF(",");
1958 shift = fetch_byte_imm();
1959 TRACE_AND_STEP();
1960 bit = shift & 0xF;
1961 srcval = fetch_data_word(srcoffset);
1962 mask = (0x1 << bit);
1963 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1964 switch (rh) {
1965 case 5:
1966 store_data_word(srcoffset, srcval | mask);
1967 break;
1968 case 6:
1969 store_data_word(srcoffset, srcval & ~mask);
1970 break;
1971 case 7:
1972 store_data_word(srcoffset, srcval ^ mask);
1973 break;
1974 default:
1975 break;
1978 break;
1979 case 3: /* register to register */
1980 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1981 u32 *srcreg;
1982 u32 mask;
1983 u8 shift;
1985 srcreg = DECODE_RM_LONG_REGISTER(rl);
1986 DECODE_PRINTF(",");
1987 shift = fetch_byte_imm();
1988 TRACE_AND_STEP();
1989 bit = shift & 0x1F;
1990 mask = (0x1 << bit);
1991 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1992 switch (rh) {
1993 case 5:
1994 *srcreg |= mask;
1995 break;
1996 case 6:
1997 *srcreg &= ~mask;
1998 break;
1999 case 7:
2000 *srcreg ^= mask;
2001 break;
2002 default:
2003 break;
2005 } else {
2006 u16 *srcreg;
2007 u16 mask;
2008 u8 shift;
2010 srcreg = DECODE_RM_WORD_REGISTER(rl);
2011 DECODE_PRINTF(",");
2012 shift = fetch_byte_imm();
2013 TRACE_AND_STEP();
2014 bit = shift & 0xF;
2015 mask = (0x1 << bit);
2016 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2017 switch (rh) {
2018 case 5:
2019 *srcreg |= mask;
2020 break;
2021 case 6:
2022 *srcreg &= ~mask;
2023 break;
2024 case 7:
2025 *srcreg ^= mask;
2026 break;
2027 default:
2028 break;
2031 break;
2033 DECODE_CLEAR_SEGOVR();
2034 END_OF_INSTR();
2037 /****************************************************************************
2038 REMARKS:
2039 Handles opcode 0x0f,0xbb
2040 ****************************************************************************/
2041 static void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
2043 int mod, rl, rh;
2044 uint srcoffset;
2045 int bit,disp;
2047 START_OF_INSTR();
2048 DECODE_PRINTF("BTC\t");
2049 FETCH_DECODE_MODRM(mod, rh, rl);
2050 switch (mod) {
2051 case 0:
2052 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2053 u32 srcval,mask;
2054 u32 *shiftreg;
2056 srcoffset = decode_rm00_address(rl);
2057 DECODE_PRINTF(",");
2058 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2059 TRACE_AND_STEP();
2060 bit = *shiftreg & 0x1F;
2061 disp = (s16)*shiftreg >> 5;
2062 srcval = fetch_data_long(srcoffset+disp);
2063 mask = (0x1 << bit);
2064 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2065 store_data_long(srcoffset+disp, srcval ^ mask);
2066 } else {
2067 u16 srcval,mask;
2068 u16 *shiftreg;
2070 srcoffset = decode_rm00_address(rl);
2071 DECODE_PRINTF(",");
2072 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2073 TRACE_AND_STEP();
2074 bit = *shiftreg & 0xF;
2075 disp = (s16)*shiftreg >> 4;
2076 srcval = fetch_data_word(srcoffset+disp);
2077 mask = (u16)(0x1 << bit);
2078 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2079 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2081 break;
2082 case 1:
2083 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2084 u32 srcval,mask;
2085 u32 *shiftreg;
2087 srcoffset = decode_rm01_address(rl);
2088 DECODE_PRINTF(",");
2089 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2090 TRACE_AND_STEP();
2091 bit = *shiftreg & 0x1F;
2092 disp = (s16)*shiftreg >> 5;
2093 srcval = fetch_data_long(srcoffset+disp);
2094 mask = (0x1 << bit);
2095 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2096 store_data_long(srcoffset+disp, srcval ^ mask);
2097 } else {
2098 u16 srcval,mask;
2099 u16 *shiftreg;
2101 srcoffset = decode_rm01_address(rl);
2102 DECODE_PRINTF(",");
2103 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2104 TRACE_AND_STEP();
2105 bit = *shiftreg & 0xF;
2106 disp = (s16)*shiftreg >> 4;
2107 srcval = fetch_data_word(srcoffset+disp);
2108 mask = (u16)(0x1 << bit);
2109 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2110 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2112 break;
2113 case 2:
2114 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2115 u32 srcval,mask;
2116 u32 *shiftreg;
2118 srcoffset = decode_rm10_address(rl);
2119 DECODE_PRINTF(",");
2120 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2121 TRACE_AND_STEP();
2122 bit = *shiftreg & 0x1F;
2123 disp = (s16)*shiftreg >> 5;
2124 srcval = fetch_data_long(srcoffset+disp);
2125 mask = (0x1 << bit);
2126 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2127 store_data_long(srcoffset+disp, srcval ^ mask);
2128 } else {
2129 u16 srcval,mask;
2130 u16 *shiftreg;
2132 srcoffset = decode_rm10_address(rl);
2133 DECODE_PRINTF(",");
2134 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2135 TRACE_AND_STEP();
2136 bit = *shiftreg & 0xF;
2137 disp = (s16)*shiftreg >> 4;
2138 srcval = fetch_data_word(srcoffset+disp);
2139 mask = (u16)(0x1 << bit);
2140 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2141 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2143 break;
2144 case 3: /* register to register */
2145 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2146 u32 *srcreg,*shiftreg;
2147 u32 mask;
2149 srcreg = DECODE_RM_LONG_REGISTER(rl);
2150 DECODE_PRINTF(",");
2151 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2152 TRACE_AND_STEP();
2153 bit = *shiftreg & 0x1F;
2154 mask = (0x1 << bit);
2155 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2156 *srcreg ^= mask;
2157 } else {
2158 u16 *srcreg,*shiftreg;
2159 u16 mask;
2161 srcreg = DECODE_RM_WORD_REGISTER(rl);
2162 DECODE_PRINTF(",");
2163 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2164 TRACE_AND_STEP();
2165 bit = *shiftreg & 0xF;
2166 mask = (u16)(0x1 << bit);
2167 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2168 *srcreg ^= mask;
2170 break;
2172 DECODE_CLEAR_SEGOVR();
2173 END_OF_INSTR();
2176 /****************************************************************************
2177 REMARKS:
2178 Handles opcode 0x0f,0xbc
2179 ****************************************************************************/
2180 static void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
2182 int mod, rl, rh;
2183 uint srcoffset;
2185 START_OF_INSTR();
2186 DECODE_PRINTF("BSF\t");
2187 FETCH_DECODE_MODRM(mod, rh, rl);
2188 switch(mod) {
2189 case 0:
2190 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2191 u32 srcval, *dstreg;
2193 srcoffset = decode_rm00_address(rl);
2194 DECODE_PRINTF(",");
2195 dstreg = DECODE_RM_LONG_REGISTER(rh);
2196 TRACE_AND_STEP();
2197 srcval = fetch_data_long(srcoffset);
2198 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2199 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2200 if ((srcval >> *dstreg) & 1) break;
2201 } else {
2202 u16 srcval, *dstreg;
2204 srcoffset = decode_rm00_address(rl);
2205 DECODE_PRINTF(",");
2206 dstreg = DECODE_RM_WORD_REGISTER(rh);
2207 TRACE_AND_STEP();
2208 srcval = fetch_data_word(srcoffset);
2209 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2210 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2211 if ((srcval >> *dstreg) & 1) break;
2213 break;
2214 case 1:
2215 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2216 u32 srcval, *dstreg;
2218 srcoffset = decode_rm01_address(rl);
2219 DECODE_PRINTF(",");
2220 dstreg = DECODE_RM_LONG_REGISTER(rh);
2221 TRACE_AND_STEP();
2222 srcval = fetch_data_long(srcoffset);
2223 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2224 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2225 if ((srcval >> *dstreg) & 1) break;
2226 } else {
2227 u16 srcval, *dstreg;
2229 srcoffset = decode_rm01_address(rl);
2230 DECODE_PRINTF(",");
2231 dstreg = DECODE_RM_WORD_REGISTER(rh);
2232 TRACE_AND_STEP();
2233 srcval = fetch_data_word(srcoffset);
2234 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2235 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2236 if ((srcval >> *dstreg) & 1) break;
2238 break;
2239 case 2:
2240 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2241 u32 srcval, *dstreg;
2243 srcoffset = decode_rm10_address(rl);
2244 DECODE_PRINTF(",");
2245 dstreg = DECODE_RM_LONG_REGISTER(rh);
2246 TRACE_AND_STEP();
2247 srcval = fetch_data_long(srcoffset);
2248 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2249 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2250 if ((srcval >> *dstreg) & 1) break;
2251 } else {
2252 u16 srcval, *dstreg;
2254 srcoffset = decode_rm10_address(rl);
2255 DECODE_PRINTF(",");
2256 dstreg = DECODE_RM_WORD_REGISTER(rh);
2257 TRACE_AND_STEP();
2258 srcval = fetch_data_word(srcoffset);
2259 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2260 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2261 if ((srcval >> *dstreg) & 1) break;
2263 break;
2264 case 3: /* register to register */
2265 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2266 u32 srcval, *dstreg;
2268 srcval = *DECODE_RM_LONG_REGISTER(rl);
2269 DECODE_PRINTF(",");
2270 dstreg = DECODE_RM_LONG_REGISTER(rh);
2271 TRACE_AND_STEP();
2272 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2273 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2274 if ((srcval >> *dstreg) & 1) break;
2275 } else {
2276 u16 srcval, *dstreg;
2278 srcval = *DECODE_RM_WORD_REGISTER(rl);
2279 DECODE_PRINTF(",");
2280 dstreg = DECODE_RM_WORD_REGISTER(rh);
2281 TRACE_AND_STEP();
2282 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2283 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2284 if ((srcval >> *dstreg) & 1) break;
2286 break;
2288 DECODE_CLEAR_SEGOVR();
2289 END_OF_INSTR();
2292 /****************************************************************************
2293 REMARKS:
2294 Handles opcode 0x0f,0xbd
2295 ****************************************************************************/
2296 static void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
2298 int mod, rl, rh;
2299 uint srcoffset;
2301 START_OF_INSTR();
2302 DECODE_PRINTF("BSR\t");
2303 FETCH_DECODE_MODRM(mod, rh, rl);
2304 switch(mod) {
2305 case 0:
2306 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2307 u32 srcval, *dstreg;
2309 srcoffset = decode_rm00_address(rl);
2310 DECODE_PRINTF(",");
2311 dstreg = DECODE_RM_LONG_REGISTER(rh);
2312 TRACE_AND_STEP();
2313 srcval = fetch_data_long(srcoffset);
2314 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2315 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2316 if ((srcval >> *dstreg) & 1) break;
2317 } else {
2318 u16 srcval, *dstreg;
2320 srcoffset = decode_rm00_address(rl);
2321 DECODE_PRINTF(",");
2322 dstreg = DECODE_RM_WORD_REGISTER(rh);
2323 TRACE_AND_STEP();
2324 srcval = fetch_data_word(srcoffset);
2325 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2326 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2327 if ((srcval >> *dstreg) & 1) break;
2329 break;
2330 case 1:
2331 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2332 u32 srcval, *dstreg;
2334 srcoffset = decode_rm01_address(rl);
2335 DECODE_PRINTF(",");
2336 dstreg = DECODE_RM_LONG_REGISTER(rh);
2337 TRACE_AND_STEP();
2338 srcval = fetch_data_long(srcoffset);
2339 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2340 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2341 if ((srcval >> *dstreg) & 1) break;
2342 } else {
2343 u16 srcval, *dstreg;
2345 srcoffset = decode_rm01_address(rl);
2346 DECODE_PRINTF(",");
2347 dstreg = DECODE_RM_WORD_REGISTER(rh);
2348 TRACE_AND_STEP();
2349 srcval = fetch_data_word(srcoffset);
2350 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2351 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2352 if ((srcval >> *dstreg) & 1) break;
2354 break;
2355 case 2:
2356 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2357 u32 srcval, *dstreg;
2359 srcoffset = decode_rm10_address(rl);
2360 DECODE_PRINTF(",");
2361 dstreg = DECODE_RM_LONG_REGISTER(rh);
2362 TRACE_AND_STEP();
2363 srcval = fetch_data_long(srcoffset);
2364 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2365 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2366 if ((srcval >> *dstreg) & 1) break;
2367 } else {
2368 u16 srcval, *dstreg;
2370 srcoffset = decode_rm10_address(rl);
2371 DECODE_PRINTF(",");
2372 dstreg = DECODE_RM_WORD_REGISTER(rh);
2373 TRACE_AND_STEP();
2374 srcval = fetch_data_word(srcoffset);
2375 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2376 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2377 if ((srcval >> *dstreg) & 1) break;
2379 break;
2380 case 3: /* register to register */
2381 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2382 u32 srcval, *dstreg;
2384 srcval = *DECODE_RM_LONG_REGISTER(rl);
2385 DECODE_PRINTF(",");
2386 dstreg = DECODE_RM_LONG_REGISTER(rh);
2387 TRACE_AND_STEP();
2388 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2389 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2390 if ((srcval >> *dstreg) & 1) break;
2391 } else {
2392 u16 srcval, *dstreg;
2394 srcval = *DECODE_RM_WORD_REGISTER(rl);
2395 DECODE_PRINTF(",");
2396 dstreg = DECODE_RM_WORD_REGISTER(rh);
2397 TRACE_AND_STEP();
2398 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2399 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2400 if ((srcval >> *dstreg) & 1) break;
2402 break;
2404 DECODE_CLEAR_SEGOVR();
2405 END_OF_INSTR();
2408 /****************************************************************************
2409 REMARKS:
2410 Handles opcode 0x0f,0xbe
2411 ****************************************************************************/
2412 static void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
2414 int mod, rl, rh;
2415 uint srcoffset;
2417 START_OF_INSTR();
2418 DECODE_PRINTF("MOVSX\t");
2419 FETCH_DECODE_MODRM(mod, rh, rl);
2420 switch (mod) {
2421 case 0:
2422 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2423 u32 *destreg;
2424 u32 srcval;
2426 destreg = DECODE_RM_LONG_REGISTER(rh);
2427 DECODE_PRINTF(",");
2428 srcoffset = decode_rm00_address(rl);
2429 srcval = (s32)((s8)fetch_data_byte(srcoffset));
2430 DECODE_PRINTF("\n");
2431 TRACE_AND_STEP();
2432 *destreg = srcval;
2433 } else {
2434 u16 *destreg;
2435 u16 srcval;
2437 destreg = DECODE_RM_WORD_REGISTER(rh);
2438 DECODE_PRINTF(",");
2439 srcoffset = decode_rm00_address(rl);
2440 srcval = (s16)((s8)fetch_data_byte(srcoffset));
2441 DECODE_PRINTF("\n");
2442 TRACE_AND_STEP();
2443 *destreg = srcval;
2445 break;
2446 case 1:
2447 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2448 u32 *destreg;
2449 u32 srcval;
2451 destreg = DECODE_RM_LONG_REGISTER(rh);
2452 DECODE_PRINTF(",");
2453 srcoffset = decode_rm01_address(rl);
2454 srcval = (s32)((s8)fetch_data_byte(srcoffset));
2455 DECODE_PRINTF("\n");
2456 TRACE_AND_STEP();
2457 *destreg = srcval;
2458 } else {
2459 u16 *destreg;
2460 u16 srcval;
2462 destreg = DECODE_RM_WORD_REGISTER(rh);
2463 DECODE_PRINTF(",");
2464 srcoffset = decode_rm01_address(rl);
2465 srcval = (s16)((s8)fetch_data_byte(srcoffset));
2466 DECODE_PRINTF("\n");
2467 TRACE_AND_STEP();
2468 *destreg = srcval;
2470 break;
2471 case 2:
2472 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2473 u32 *destreg;
2474 u32 srcval;
2476 destreg = DECODE_RM_LONG_REGISTER(rh);
2477 DECODE_PRINTF(",");
2478 srcoffset = decode_rm10_address(rl);
2479 srcval = (s32)((s8)fetch_data_byte(srcoffset));
2480 DECODE_PRINTF("\n");
2481 TRACE_AND_STEP();
2482 *destreg = srcval;
2483 } else {
2484 u16 *destreg;
2485 u16 srcval;
2487 destreg = DECODE_RM_WORD_REGISTER(rh);
2488 DECODE_PRINTF(",");
2489 srcoffset = decode_rm10_address(rl);
2490 srcval = (s16)((s8)fetch_data_byte(srcoffset));
2491 DECODE_PRINTF("\n");
2492 TRACE_AND_STEP();
2493 *destreg = srcval;
2495 break;
2496 case 3: /* register to register */
2497 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2498 u32 *destreg;
2499 u8 *srcreg;
2501 destreg = DECODE_RM_LONG_REGISTER(rh);
2502 DECODE_PRINTF(",");
2503 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2504 DECODE_PRINTF("\n");
2505 TRACE_AND_STEP();
2506 *destreg = (s32)((s8)*srcreg);
2507 } else {
2508 u16 *destreg;
2509 u8 *srcreg;
2511 destreg = DECODE_RM_WORD_REGISTER(rh);
2512 DECODE_PRINTF(",");
2513 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2514 DECODE_PRINTF("\n");
2515 TRACE_AND_STEP();
2516 *destreg = (s16)((s8)*srcreg);
2518 break;
2520 DECODE_CLEAR_SEGOVR();
2521 END_OF_INSTR();
2524 /****************************************************************************
2525 REMARKS:
2526 Handles opcode 0x0f,0xbf
2527 ****************************************************************************/
2528 static void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
2530 int mod, rl, rh;
2531 uint srcoffset;
2532 u32 *destreg;
2533 u32 srcval;
2534 u16 *srcreg;
2536 START_OF_INSTR();
2537 DECODE_PRINTF("MOVSX\t");
2538 FETCH_DECODE_MODRM(mod, rh, rl);
2539 switch (mod) {
2540 case 0:
2541 destreg = DECODE_RM_LONG_REGISTER(rh);
2542 DECODE_PRINTF(",");
2543 srcoffset = decode_rm00_address(rl);
2544 srcval = (s32)((s16)fetch_data_word(srcoffset));
2545 DECODE_PRINTF("\n");
2546 TRACE_AND_STEP();
2547 *destreg = srcval;
2548 break;
2549 case 1:
2550 destreg = DECODE_RM_LONG_REGISTER(rh);
2551 DECODE_PRINTF(",");
2552 srcoffset = decode_rm01_address(rl);
2553 srcval = (s32)((s16)fetch_data_word(srcoffset));
2554 DECODE_PRINTF("\n");
2555 TRACE_AND_STEP();
2556 *destreg = srcval;
2557 break;
2558 case 2:
2559 destreg = DECODE_RM_LONG_REGISTER(rh);
2560 DECODE_PRINTF(",");
2561 srcoffset = decode_rm10_address(rl);
2562 srcval = (s32)((s16)fetch_data_word(srcoffset));
2563 DECODE_PRINTF("\n");
2564 TRACE_AND_STEP();
2565 *destreg = srcval;
2566 break;
2567 case 3: /* register to register */
2568 destreg = DECODE_RM_LONG_REGISTER(rh);
2569 DECODE_PRINTF(",");
2570 srcreg = DECODE_RM_WORD_REGISTER(rl);
2571 DECODE_PRINTF("\n");
2572 TRACE_AND_STEP();
2573 *destreg = (s32)((s16)*srcreg);
2574 break;
2576 DECODE_CLEAR_SEGOVR();
2577 END_OF_INSTR();
2580 /* Handles opcodes 0xc8-0xcf */
2581 static void x86emuOp2_bswap(u8 X86EMU_UNUSED(op2))
2583 START_OF_INSTR();
2584 DECODE_PRINTF("BSWAP\n");
2585 TRACE_AND_STEP();
2587 switch (op2) {
2588 case 0xc8:
2589 M.x86.R_EAX = bswap_32(M.x86.R_EAX);
2590 break;
2591 case 0xc9:
2592 M.x86.R_ECX = bswap_32(M.x86.R_ECX);
2593 break;
2594 case 0xca:
2595 M.x86.R_EDX = bswap_32(M.x86.R_EDX);
2596 break;
2597 case 0xcb:
2598 M.x86.R_EBX = bswap_32(M.x86.R_EBX);
2599 break;
2600 case 0xcc:
2601 M.x86.R_ESP = bswap_32(M.x86.R_ESP);
2602 break;
2603 case 0xcd:
2604 M.x86.R_EBP = bswap_32(M.x86.R_EBP);
2605 break;
2606 case 0xce:
2607 M.x86.R_ESI = bswap_32(M.x86.R_ESI);
2608 break;
2609 case 0xcf:
2610 M.x86.R_EDI = bswap_32(M.x86.R_EDI);
2611 break;
2612 default:
2613 /* can't happen */
2614 break;
2617 DECODE_CLEAR_SEGOVR();
2618 END_OF_INSTR();
2621 /***************************************************************************
2622 * Double byte operation code table:
2623 **************************************************************************/
2624 void (*x86emu_optab2[256])(u8) =
2626 /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
2627 /* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */
2628 /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
2629 /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
2630 /* 0x04 */ x86emuOp2_illegal_op,
2631 /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
2632 /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
2633 /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
2634 /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */
2635 /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */
2636 /* 0x0a */ x86emuOp2_illegal_op,
2637 /* 0x0b */ x86emuOp2_illegal_op,
2638 /* 0x0c */ x86emuOp2_illegal_op,
2639 /* 0x0d */ x86emuOp2_illegal_op,
2640 /* 0x0e */ x86emuOp2_illegal_op,
2641 /* 0x0f */ x86emuOp2_illegal_op,
2643 /* 0x10 */ x86emuOp2_illegal_op,
2644 /* 0x11 */ x86emuOp2_illegal_op,
2645 /* 0x12 */ x86emuOp2_illegal_op,
2646 /* 0x13 */ x86emuOp2_illegal_op,
2647 /* 0x14 */ x86emuOp2_illegal_op,
2648 /* 0x15 */ x86emuOp2_illegal_op,
2649 /* 0x16 */ x86emuOp2_illegal_op,
2650 /* 0x17 */ x86emuOp2_illegal_op,
2651 /* 0x18 */ x86emuOp2_illegal_op,
2652 /* 0x19 */ x86emuOp2_illegal_op,
2653 /* 0x1a */ x86emuOp2_illegal_op,
2654 /* 0x1b */ x86emuOp2_illegal_op,
2655 /* 0x1c */ x86emuOp2_illegal_op,
2656 /* 0x1d */ x86emuOp2_illegal_op,
2657 /* 0x1e */ x86emuOp2_illegal_op,
2658 /* 0x1f */ x86emuOp2_illegal_op,
2660 /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
2661 /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
2662 /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
2663 /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
2664 /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
2665 /* 0x25 */ x86emuOp2_illegal_op,
2666 /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
2667 /* 0x27 */ x86emuOp2_illegal_op,
2668 /* 0x28 */ x86emuOp2_illegal_op,
2669 /* 0x29 */ x86emuOp2_illegal_op,
2670 /* 0x2a */ x86emuOp2_illegal_op,
2671 /* 0x2b */ x86emuOp2_illegal_op,
2672 /* 0x2c */ x86emuOp2_illegal_op,
2673 /* 0x2d */ x86emuOp2_illegal_op,
2674 /* 0x2e */ x86emuOp2_illegal_op,
2675 /* 0x2f */ x86emuOp2_illegal_op,
2677 /* 0x30 */ x86emuOp2_illegal_op,
2678 /* 0x31 */ x86emuOp2_rdtsc,
2679 /* 0x32 */ x86emuOp2_illegal_op,
2680 /* 0x33 */ x86emuOp2_illegal_op,
2681 /* 0x34 */ x86emuOp2_illegal_op,
2682 /* 0x35 */ x86emuOp2_illegal_op,
2683 /* 0x36 */ x86emuOp2_illegal_op,
2684 /* 0x37 */ x86emuOp2_illegal_op,
2685 /* 0x38 */ x86emuOp2_illegal_op,
2686 /* 0x39 */ x86emuOp2_illegal_op,
2687 /* 0x3a */ x86emuOp2_illegal_op,
2688 /* 0x3b */ x86emuOp2_illegal_op,
2689 /* 0x3c */ x86emuOp2_illegal_op,
2690 /* 0x3d */ x86emuOp2_illegal_op,
2691 /* 0x3e */ x86emuOp2_illegal_op,
2692 /* 0x3f */ x86emuOp2_illegal_op,
2694 /* 0x40 */ x86emuOp2_illegal_op,
2695 /* 0x41 */ x86emuOp2_illegal_op,
2696 /* 0x42 */ x86emuOp2_illegal_op,
2697 /* 0x43 */ x86emuOp2_illegal_op,
2698 /* 0x44 */ x86emuOp2_illegal_op,
2699 /* 0x45 */ x86emuOp2_illegal_op,
2700 /* 0x46 */ x86emuOp2_illegal_op,
2701 /* 0x47 */ x86emuOp2_illegal_op,
2702 /* 0x48 */ x86emuOp2_illegal_op,
2703 /* 0x49 */ x86emuOp2_illegal_op,
2704 /* 0x4a */ x86emuOp2_illegal_op,
2705 /* 0x4b */ x86emuOp2_illegal_op,
2706 /* 0x4c */ x86emuOp2_illegal_op,
2707 /* 0x4d */ x86emuOp2_illegal_op,
2708 /* 0x4e */ x86emuOp2_illegal_op,
2709 /* 0x4f */ x86emuOp2_illegal_op,
2711 /* 0x50 */ x86emuOp2_illegal_op,
2712 /* 0x51 */ x86emuOp2_illegal_op,
2713 /* 0x52 */ x86emuOp2_illegal_op,
2714 /* 0x53 */ x86emuOp2_illegal_op,
2715 /* 0x54 */ x86emuOp2_illegal_op,
2716 /* 0x55 */ x86emuOp2_illegal_op,
2717 /* 0x56 */ x86emuOp2_illegal_op,
2718 /* 0x57 */ x86emuOp2_illegal_op,
2719 /* 0x58 */ x86emuOp2_illegal_op,
2720 /* 0x59 */ x86emuOp2_illegal_op,
2721 /* 0x5a */ x86emuOp2_illegal_op,
2722 /* 0x5b */ x86emuOp2_illegal_op,
2723 /* 0x5c */ x86emuOp2_illegal_op,
2724 /* 0x5d */ x86emuOp2_illegal_op,
2725 /* 0x5e */ x86emuOp2_illegal_op,
2726 /* 0x5f */ x86emuOp2_illegal_op,
2728 /* 0x60 */ x86emuOp2_illegal_op,
2729 /* 0x61 */ x86emuOp2_illegal_op,
2730 /* 0x62 */ x86emuOp2_illegal_op,
2731 /* 0x63 */ x86emuOp2_illegal_op,
2732 /* 0x64 */ x86emuOp2_illegal_op,
2733 /* 0x65 */ x86emuOp2_illegal_op,
2734 /* 0x66 */ x86emuOp2_illegal_op,
2735 /* 0x67 */ x86emuOp2_illegal_op,
2736 /* 0x68 */ x86emuOp2_illegal_op,
2737 /* 0x69 */ x86emuOp2_illegal_op,
2738 /* 0x6a */ x86emuOp2_illegal_op,
2739 /* 0x6b */ x86emuOp2_illegal_op,
2740 /* 0x6c */ x86emuOp2_illegal_op,
2741 /* 0x6d */ x86emuOp2_illegal_op,
2742 /* 0x6e */ x86emuOp2_illegal_op,
2743 /* 0x6f */ x86emuOp2_illegal_op,
2745 /* 0x70 */ x86emuOp2_illegal_op,
2746 /* 0x71 */ x86emuOp2_illegal_op,
2747 /* 0x72 */ x86emuOp2_illegal_op,
2748 /* 0x73 */ x86emuOp2_illegal_op,
2749 /* 0x74 */ x86emuOp2_illegal_op,
2750 /* 0x75 */ x86emuOp2_illegal_op,
2751 /* 0x76 */ x86emuOp2_illegal_op,
2752 /* 0x77 */ x86emuOp2_illegal_op,
2753 /* 0x78 */ x86emuOp2_illegal_op,
2754 /* 0x79 */ x86emuOp2_illegal_op,
2755 /* 0x7a */ x86emuOp2_illegal_op,
2756 /* 0x7b */ x86emuOp2_illegal_op,
2757 /* 0x7c */ x86emuOp2_illegal_op,
2758 /* 0x7d */ x86emuOp2_illegal_op,
2759 /* 0x7e */ x86emuOp2_illegal_op,
2760 /* 0x7f */ x86emuOp2_illegal_op,
2762 /* 0x80 */ x86emuOp2_long_jump,
2763 /* 0x81 */ x86emuOp2_long_jump,
2764 /* 0x82 */ x86emuOp2_long_jump,
2765 /* 0x83 */ x86emuOp2_long_jump,
2766 /* 0x84 */ x86emuOp2_long_jump,
2767 /* 0x85 */ x86emuOp2_long_jump,
2768 /* 0x86 */ x86emuOp2_long_jump,
2769 /* 0x87 */ x86emuOp2_long_jump,
2770 /* 0x88 */ x86emuOp2_long_jump,
2771 /* 0x89 */ x86emuOp2_long_jump,
2772 /* 0x8a */ x86emuOp2_long_jump,
2773 /* 0x8b */ x86emuOp2_long_jump,
2774 /* 0x8c */ x86emuOp2_long_jump,
2775 /* 0x8d */ x86emuOp2_long_jump,
2776 /* 0x8e */ x86emuOp2_long_jump,
2777 /* 0x8f */ x86emuOp2_long_jump,
2779 /* 0x90 */ x86emuOp2_set_byte,
2780 /* 0x91 */ x86emuOp2_set_byte,
2781 /* 0x92 */ x86emuOp2_set_byte,
2782 /* 0x93 */ x86emuOp2_set_byte,
2783 /* 0x94 */ x86emuOp2_set_byte,
2784 /* 0x95 */ x86emuOp2_set_byte,
2785 /* 0x96 */ x86emuOp2_set_byte,
2786 /* 0x97 */ x86emuOp2_set_byte,
2787 /* 0x98 */ x86emuOp2_set_byte,
2788 /* 0x99 */ x86emuOp2_set_byte,
2789 /* 0x9a */ x86emuOp2_set_byte,
2790 /* 0x9b */ x86emuOp2_set_byte,
2791 /* 0x9c */ x86emuOp2_set_byte,
2792 /* 0x9d */ x86emuOp2_set_byte,
2793 /* 0x9e */ x86emuOp2_set_byte,
2794 /* 0x9f */ x86emuOp2_set_byte,
2796 /* 0xa0 */ x86emuOp2_push_FS,
2797 /* 0xa1 */ x86emuOp2_pop_FS,
2798 /* 0xa2 */ x86emuOp2_cpuid,
2799 /* 0xa3 */ x86emuOp2_bt_R,
2800 /* 0xa4 */ x86emuOp2_shld_IMM,
2801 /* 0xa5 */ x86emuOp2_shld_CL,
2802 /* 0xa6 */ x86emuOp2_illegal_op,
2803 /* 0xa7 */ x86emuOp2_illegal_op,
2804 /* 0xa8 */ x86emuOp2_push_GS,
2805 /* 0xa9 */ x86emuOp2_pop_GS,
2806 /* 0xaa */ x86emuOp2_illegal_op,
2807 /* 0xab */ x86emuOp2_bts_R,
2808 /* 0xac */ x86emuOp2_shrd_IMM,
2809 /* 0xad */ x86emuOp2_shrd_CL,
2810 /* 0xae */ x86emuOp2_illegal_op,
2811 /* 0xaf */ x86emuOp2_imul_R_RM,
2813 /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
2814 /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
2815 /* 0xb2 */ x86emuOp2_lss_R_IMM,
2816 /* 0xb3 */ x86emuOp2_btr_R,
2817 /* 0xb4 */ x86emuOp2_lfs_R_IMM,
2818 /* 0xb5 */ x86emuOp2_lgs_R_IMM,
2819 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
2820 /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
2821 /* 0xb8 */ x86emuOp2_illegal_op,
2822 /* 0xb9 */ x86emuOp2_illegal_op,
2823 /* 0xba */ x86emuOp2_btX_I,
2824 /* 0xbb */ x86emuOp2_btc_R,
2825 /* 0xbc */ x86emuOp2_bsf,
2826 /* 0xbd */ x86emuOp2_bsr,
2827 /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
2828 /* 0xbf */ x86emuOp2_movsx_word_R_RM,
2830 /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
2831 /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
2832 /* 0xc2 */ x86emuOp2_illegal_op,
2833 /* 0xc3 */ x86emuOp2_illegal_op,
2834 /* 0xc4 */ x86emuOp2_illegal_op,
2835 /* 0xc5 */ x86emuOp2_illegal_op,
2836 /* 0xc6 */ x86emuOp2_illegal_op,
2837 /* 0xc7 */ x86emuOp2_illegal_op,
2838 /* 0xc8 */ x86emuOp2_bswap,
2839 /* 0xc9 */ x86emuOp2_bswap,
2840 /* 0xca */ x86emuOp2_bswap,
2841 /* 0xcb */ x86emuOp2_bswap,
2842 /* 0xcc */ x86emuOp2_bswap,
2843 /* 0xcd */ x86emuOp2_bswap,
2844 /* 0xce */ x86emuOp2_bswap,
2845 /* 0xcf */ x86emuOp2_bswap,
2847 /* 0xd0 */ x86emuOp2_illegal_op,
2848 /* 0xd1 */ x86emuOp2_illegal_op,
2849 /* 0xd2 */ x86emuOp2_illegal_op,
2850 /* 0xd3 */ x86emuOp2_illegal_op,
2851 /* 0xd4 */ x86emuOp2_illegal_op,
2852 /* 0xd5 */ x86emuOp2_illegal_op,
2853 /* 0xd6 */ x86emuOp2_illegal_op,
2854 /* 0xd7 */ x86emuOp2_illegal_op,
2855 /* 0xd8 */ x86emuOp2_illegal_op,
2856 /* 0xd9 */ x86emuOp2_illegal_op,
2857 /* 0xda */ x86emuOp2_illegal_op,
2858 /* 0xdb */ x86emuOp2_illegal_op,
2859 /* 0xdc */ x86emuOp2_illegal_op,
2860 /* 0xdd */ x86emuOp2_illegal_op,
2861 /* 0xde */ x86emuOp2_illegal_op,
2862 /* 0xdf */ x86emuOp2_illegal_op,
2864 /* 0xe0 */ x86emuOp2_illegal_op,
2865 /* 0xe1 */ x86emuOp2_illegal_op,
2866 /* 0xe2 */ x86emuOp2_illegal_op,
2867 /* 0xe3 */ x86emuOp2_illegal_op,
2868 /* 0xe4 */ x86emuOp2_illegal_op,
2869 /* 0xe5 */ x86emuOp2_illegal_op,
2870 /* 0xe6 */ x86emuOp2_illegal_op,
2871 /* 0xe7 */ x86emuOp2_illegal_op,
2872 /* 0xe8 */ x86emuOp2_illegal_op,
2873 /* 0xe9 */ x86emuOp2_illegal_op,
2874 /* 0xea */ x86emuOp2_illegal_op,
2875 /* 0xeb */ x86emuOp2_illegal_op,
2876 /* 0xec */ x86emuOp2_illegal_op,
2877 /* 0xed */ x86emuOp2_illegal_op,
2878 /* 0xee */ x86emuOp2_illegal_op,
2879 /* 0xef */ x86emuOp2_illegal_op,
2881 /* 0xf0 */ x86emuOp2_illegal_op,
2882 /* 0xf1 */ x86emuOp2_illegal_op,
2883 /* 0xf2 */ x86emuOp2_illegal_op,
2884 /* 0xf3 */ x86emuOp2_illegal_op,
2885 /* 0xf4 */ x86emuOp2_illegal_op,
2886 /* 0xf5 */ x86emuOp2_illegal_op,
2887 /* 0xf6 */ x86emuOp2_illegal_op,
2888 /* 0xf7 */ x86emuOp2_illegal_op,
2889 /* 0xf8 */ x86emuOp2_illegal_op,
2890 /* 0xf9 */ x86emuOp2_illegal_op,
2891 /* 0xfa */ x86emuOp2_illegal_op,
2892 /* 0xfb */ x86emuOp2_illegal_op,
2893 /* 0xfc */ x86emuOp2_illegal_op,
2894 /* 0xfd */ x86emuOp2_illegal_op,
2895 /* 0xfe */ x86emuOp2_illegal_op,
2896 /* 0xff */ x86emuOp2_illegal_op,