Fix concurrent build by properly specifying all dependencies.
[v86d.git] / libs / x86emu / ops2.c
blob06b7f5652416930dcd302b6507c721545faf884b
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 int mod, rl, rh;
62 START_OF_INSTR();
63 FETCH_DECODE_MODRM(mod, rh, rl);
64 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
65 TRACE_REGS();
66 printk("%04x:%04x: %02X /%d ILLEGAL EXTENDED X86 OPCODE! (mod=%d rl=%d)\n",
67 M.x86.R_CS, M.x86.R_IP-2,op2, rh, mod, rl);
68 HALT_SYS();
69 END_OF_INSTR();
72 #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
74 /****************************************************************************
75 REMARKS:
76 Handles opcode 0x0f,0x01
77 ****************************************************************************/
78 static void x86emuOp2_group_g(u8 X86EMU_UNUSED(op2))
80 int mod, rl, rh;
81 u16 *destreg;
82 uint destoffset;
84 START_OF_INSTR();
85 FETCH_DECODE_MODRM(mod, rh, rl);
86 switch (rh) {
87 case 4: // SMSW (Store Machine Status Word)
88 // Decode the mod byte to find the addressing
89 // Always returns 0x10 (initial value as per intel manual volume 3, figure 8-1
90 switch (mod) {
91 case 0:
92 destoffset = decode_rm00_address(rl);
93 store_data_word(destoffset, 0x10);
94 break;
95 case 1:
96 destoffset = decode_rm01_address(rl);
97 store_data_word(destoffset, 0x10);
98 break;
99 case 2:
100 destoffset = decode_rm10_address(rl);
101 store_data_word(destoffset, 0x10);
102 break;
103 case 3:
104 destreg = DECODE_RM_WORD_REGISTER(rl);
105 *destreg = 0x10;
106 break;
108 break;
109 default:
110 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE IN 0F 01\n");
111 TRACE_REGS();
112 printk("%04x:%04x: 0F %02X /%d ILLEGAL EXTENDED X86 OPCODE! (mod=%d rl=%d)\n",
113 M.x86.R_CS, M.x86.R_IP-2,op2, rh, mod, rl);
114 HALT_SYS();
115 break;
117 END_OF_INSTR();
120 /****************************************************************************
121 REMARKS:
122 Handles opcode 0x0f,0x31
123 ****************************************************************************/
124 static void x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
126 #ifdef __HAS_LONG_LONG__
127 static u64 counter = 0;
128 #else
129 static u32 counter = 0;
130 #endif
132 counter += 0x10000;
134 /* read timestamp counter */
136 * Note that instead of actually trying to accurately measure this, we just
137 * increase the counter by a fixed amount every time we hit one of these
138 * instructions. Feel free to come up with a better method.
140 START_OF_INSTR();
141 DECODE_PRINTF("RDTSC\n");
142 TRACE_AND_STEP();
143 #ifdef __HAS_LONG_LONG__
144 M.x86.R_EAX = counter & 0xffffffff;
145 M.x86.R_EDX = counter >> 32;
146 #else
147 M.x86.R_EAX = counter;
148 M.x86.R_EDX = 0;
149 #endif
150 DECODE_CLEAR_SEGOVR();
151 END_OF_INSTR();
154 /****************************************************************************
155 REMARKS:
156 Handles opcode 0x0f,0x80-0x8F
157 ****************************************************************************/
158 static void x86emuOp2_long_jump(u8 op2)
160 s32 target;
161 char *name = 0;
162 int cond = 0;
164 /* conditional jump to word offset. */
165 START_OF_INSTR();
166 switch (op2) {
167 case 0x80:
168 name = "JO\t";
169 cond = ACCESS_FLAG(F_OF);
170 break;
171 case 0x81:
172 name = "JNO\t";
173 cond = !ACCESS_FLAG(F_OF);
174 break;
175 case 0x82:
176 name = "JB\t";
177 cond = ACCESS_FLAG(F_CF);
178 break;
179 case 0x83:
180 name = "JNB\t";
181 cond = !ACCESS_FLAG(F_CF);
182 break;
183 case 0x84:
184 name = "JZ\t";
185 cond = ACCESS_FLAG(F_ZF);
186 break;
187 case 0x85:
188 name = "JNZ\t";
189 cond = !ACCESS_FLAG(F_ZF);
190 break;
191 case 0x86:
192 name = "JBE\t";
193 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
194 break;
195 case 0x87:
196 name = "JNBE\t";
197 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
198 break;
199 case 0x88:
200 name = "JS\t";
201 cond = ACCESS_FLAG(F_SF);
202 break;
203 case 0x89:
204 name = "JNS\t";
205 cond = !ACCESS_FLAG(F_SF);
206 break;
207 case 0x8a:
208 name = "JP\t";
209 cond = ACCESS_FLAG(F_PF);
210 break;
211 case 0x8b:
212 name = "JNP\t";
213 cond = !ACCESS_FLAG(F_PF);
214 break;
215 case 0x8c:
216 name = "JL\t";
217 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
218 break;
219 case 0x8d:
220 name = "JNL\t";
221 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
222 break;
223 case 0x8e:
224 name = "JLE\t";
225 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
226 ACCESS_FLAG(F_ZF));
227 break;
228 case 0x8f:
229 name = "JNLE\t";
230 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
231 ACCESS_FLAG(F_ZF));
232 break;
234 DECODE_PRINTF(name);
235 (void)name;
236 target = (s16) fetch_word_imm();
237 target += (s16) M.x86.R_IP;
238 DECODE_PRINTF2("%04x\n", target);
239 TRACE_AND_STEP();
240 if (cond)
241 M.x86.R_IP = (u16)target;
242 DECODE_CLEAR_SEGOVR();
243 END_OF_INSTR();
246 /****************************************************************************
247 REMARKS:
248 Handles opcode 0x0f,0x90-0x9F
249 ****************************************************************************/
250 static void x86emuOp2_set_byte(u8 op2)
252 int mod, rl, rh;
253 uint destoffset;
254 u8 *destreg;
255 char *name = 0;
256 int cond = 0;
258 START_OF_INSTR();
259 switch (op2) {
260 case 0x90:
261 name = "SETO\t";
262 cond = ACCESS_FLAG(F_OF);
263 break;
264 case 0x91:
265 name = "SETNO\t";
266 cond = !ACCESS_FLAG(F_OF);
267 break;
268 case 0x92:
269 name = "SETB\t";
270 cond = ACCESS_FLAG(F_CF);
271 break;
272 case 0x93:
273 name = "SETNB\t";
274 cond = !ACCESS_FLAG(F_CF);
275 break;
276 case 0x94:
277 name = "SETZ\t";
278 cond = ACCESS_FLAG(F_ZF);
279 break;
280 case 0x95:
281 name = "SETNZ\t";
282 cond = !ACCESS_FLAG(F_ZF);
283 break;
284 case 0x96:
285 name = "SETBE\t";
286 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
287 break;
288 case 0x97:
289 name = "SETNBE\t";
290 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
291 break;
292 case 0x98:
293 name = "SETS\t";
294 cond = ACCESS_FLAG(F_SF);
295 break;
296 case 0x99:
297 name = "SETNS\t";
298 cond = !ACCESS_FLAG(F_SF);
299 break;
300 case 0x9a:
301 name = "SETP\t";
302 cond = ACCESS_FLAG(F_PF);
303 break;
304 case 0x9b:
305 name = "SETNP\t";
306 cond = !ACCESS_FLAG(F_PF);
307 break;
308 case 0x9c:
309 name = "SETL\t";
310 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
311 break;
312 case 0x9d:
313 name = "SETNL\t";
314 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
315 break;
316 case 0x9e:
317 name = "SETLE\t";
318 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
319 ACCESS_FLAG(F_ZF));
320 break;
321 case 0x9f:
322 name = "SETNLE\t";
323 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
324 ACCESS_FLAG(F_ZF));
325 break;
327 DECODE_PRINTF(name);
328 (void)name;
329 FETCH_DECODE_MODRM(mod, rh, rl);
330 switch (mod) {
331 case 0:
332 destoffset = decode_rm00_address(rl);
333 TRACE_AND_STEP();
334 store_data_byte(destoffset, cond ? 0x01 : 0x00);
335 break;
336 case 1:
337 destoffset = decode_rm01_address(rl);
338 TRACE_AND_STEP();
339 store_data_byte(destoffset, cond ? 0x01 : 0x00);
340 break;
341 case 2:
342 destoffset = decode_rm10_address(rl);
343 TRACE_AND_STEP();
344 store_data_byte(destoffset, cond ? 0x01 : 0x00);
345 break;
346 case 3: /* register to register */
347 destreg = DECODE_RM_BYTE_REGISTER(rl);
348 TRACE_AND_STEP();
349 *destreg = cond ? 0x01 : 0x00;
350 break;
352 DECODE_CLEAR_SEGOVR();
353 END_OF_INSTR();
356 /****************************************************************************
357 REMARKS:
358 Handles opcode 0x0f,0xa0
359 ****************************************************************************/
360 static void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
362 START_OF_INSTR();
363 DECODE_PRINTF("PUSH\tFS\n");
364 TRACE_AND_STEP();
365 push_word(M.x86.R_FS);
366 DECODE_CLEAR_SEGOVR();
367 END_OF_INSTR();
370 /****************************************************************************
371 REMARKS:
372 Handles opcode 0x0f,0xa1
373 ****************************************************************************/
374 static void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
376 START_OF_INSTR();
377 DECODE_PRINTF("POP\tFS\n");
378 TRACE_AND_STEP();
379 M.x86.R_FS = pop_word();
380 DECODE_CLEAR_SEGOVR();
381 END_OF_INSTR();
384 /****************************************************************************
385 REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
386 Handles opcode 0x0f,0xa2
387 ****************************************************************************/
388 static void x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
390 START_OF_INSTR();
391 DECODE_PRINTF("CPUID\n");
392 TRACE_AND_STEP();
393 cpuid();
394 DECODE_CLEAR_SEGOVR();
395 END_OF_INSTR();
398 /****************************************************************************
399 REMARKS:
400 Handles opcode 0x0f,0xa3
401 ****************************************************************************/
402 static void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
404 int mod, rl, rh;
405 uint srcoffset;
406 int bit,disp;
408 START_OF_INSTR();
409 DECODE_PRINTF("BT\t");
410 FETCH_DECODE_MODRM(mod, rh, rl);
411 switch (mod) {
412 case 0:
413 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
414 u32 srcval;
415 u32 *shiftreg;
417 srcoffset = decode_rm00_address(rl);
418 DECODE_PRINTF(",");
419 shiftreg = DECODE_RM_LONG_REGISTER(rh);
420 TRACE_AND_STEP();
421 bit = *shiftreg & 0x1F;
422 disp = (s16)*shiftreg >> 5;
423 srcval = fetch_data_long(srcoffset+disp);
424 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
425 } else {
426 u16 srcval;
427 u16 *shiftreg;
429 srcoffset = decode_rm00_address(rl);
430 DECODE_PRINTF(",");
431 shiftreg = DECODE_RM_WORD_REGISTER(rh);
432 TRACE_AND_STEP();
433 bit = *shiftreg & 0xF;
434 disp = (s16)*shiftreg >> 4;
435 srcval = fetch_data_word(srcoffset+disp);
436 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
438 break;
439 case 1:
440 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
441 u32 srcval;
442 u32 *shiftreg;
444 srcoffset = decode_rm01_address(rl);
445 DECODE_PRINTF(",");
446 shiftreg = DECODE_RM_LONG_REGISTER(rh);
447 TRACE_AND_STEP();
448 bit = *shiftreg & 0x1F;
449 disp = (s16)*shiftreg >> 5;
450 srcval = fetch_data_long(srcoffset+disp);
451 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
452 } else {
453 u16 srcval;
454 u16 *shiftreg;
456 srcoffset = decode_rm01_address(rl);
457 DECODE_PRINTF(",");
458 shiftreg = DECODE_RM_WORD_REGISTER(rh);
459 TRACE_AND_STEP();
460 bit = *shiftreg & 0xF;
461 disp = (s16)*shiftreg >> 4;
462 srcval = fetch_data_word(srcoffset+disp);
463 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
465 break;
466 case 2:
467 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
468 u32 srcval;
469 u32 *shiftreg;
471 srcoffset = decode_rm10_address(rl);
472 DECODE_PRINTF(",");
473 shiftreg = DECODE_RM_LONG_REGISTER(rh);
474 TRACE_AND_STEP();
475 bit = *shiftreg & 0x1F;
476 disp = (s16)*shiftreg >> 5;
477 srcval = fetch_data_long(srcoffset+disp);
478 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
479 } else {
480 u16 srcval;
481 u16 *shiftreg;
483 srcoffset = decode_rm10_address(rl);
484 DECODE_PRINTF(",");
485 shiftreg = DECODE_RM_WORD_REGISTER(rh);
486 TRACE_AND_STEP();
487 bit = *shiftreg & 0xF;
488 disp = (s16)*shiftreg >> 4;
489 srcval = fetch_data_word(srcoffset+disp);
490 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
492 break;
493 case 3: /* register to register */
494 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
495 u32 *srcreg,*shiftreg;
497 srcreg = DECODE_RM_LONG_REGISTER(rl);
498 DECODE_PRINTF(",");
499 shiftreg = DECODE_RM_LONG_REGISTER(rh);
500 TRACE_AND_STEP();
501 bit = *shiftreg & 0x1F;
502 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
503 } else {
504 u16 *srcreg,*shiftreg;
506 srcreg = DECODE_RM_WORD_REGISTER(rl);
507 DECODE_PRINTF(",");
508 shiftreg = DECODE_RM_WORD_REGISTER(rh);
509 TRACE_AND_STEP();
510 bit = *shiftreg & 0xF;
511 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
513 break;
515 DECODE_CLEAR_SEGOVR();
516 END_OF_INSTR();
519 /****************************************************************************
520 REMARKS:
521 Handles opcode 0x0f,0xa4
522 ****************************************************************************/
523 static void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
525 int mod, rl, rh;
526 uint destoffset;
527 u8 shift;
529 START_OF_INSTR();
530 DECODE_PRINTF("SHLD\t");
531 FETCH_DECODE_MODRM(mod, rh, rl);
532 switch (mod) {
533 case 0:
534 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
535 u32 destval;
536 u32 *shiftreg;
538 destoffset = decode_rm00_address(rl);
539 DECODE_PRINTF(",");
540 shiftreg = DECODE_RM_LONG_REGISTER(rh);
541 DECODE_PRINTF(",");
542 shift = fetch_byte_imm();
543 DECODE_PRINTF2("%d\n", shift);
544 TRACE_AND_STEP();
545 destval = fetch_data_long(destoffset);
546 destval = shld_long(destval,*shiftreg,shift);
547 store_data_long(destoffset, destval);
548 } else {
549 u16 destval;
550 u16 *shiftreg;
552 destoffset = decode_rm00_address(rl);
553 DECODE_PRINTF(",");
554 shiftreg = DECODE_RM_WORD_REGISTER(rh);
555 DECODE_PRINTF(",");
556 shift = fetch_byte_imm();
557 DECODE_PRINTF2("%d\n", shift);
558 TRACE_AND_STEP();
559 destval = fetch_data_word(destoffset);
560 destval = shld_word(destval,*shiftreg,shift);
561 store_data_word(destoffset, destval);
563 break;
564 case 1:
565 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
566 u32 destval;
567 u32 *shiftreg;
569 destoffset = decode_rm01_address(rl);
570 DECODE_PRINTF(",");
571 shiftreg = DECODE_RM_LONG_REGISTER(rh);
572 DECODE_PRINTF(",");
573 shift = fetch_byte_imm();
574 DECODE_PRINTF2("%d\n", shift);
575 TRACE_AND_STEP();
576 destval = fetch_data_long(destoffset);
577 destval = shld_long(destval,*shiftreg,shift);
578 store_data_long(destoffset, destval);
579 } else {
580 u16 destval;
581 u16 *shiftreg;
583 destoffset = decode_rm01_address(rl);
584 DECODE_PRINTF(",");
585 shiftreg = DECODE_RM_WORD_REGISTER(rh);
586 DECODE_PRINTF(",");
587 shift = fetch_byte_imm();
588 DECODE_PRINTF2("%d\n", shift);
589 TRACE_AND_STEP();
590 destval = fetch_data_word(destoffset);
591 destval = shld_word(destval,*shiftreg,shift);
592 store_data_word(destoffset, destval);
594 break;
595 case 2:
596 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
597 u32 destval;
598 u32 *shiftreg;
600 destoffset = decode_rm10_address(rl);
601 DECODE_PRINTF(",");
602 shiftreg = DECODE_RM_LONG_REGISTER(rh);
603 DECODE_PRINTF(",");
604 shift = fetch_byte_imm();
605 DECODE_PRINTF2("%d\n", shift);
606 TRACE_AND_STEP();
607 destval = fetch_data_long(destoffset);
608 destval = shld_long(destval,*shiftreg,shift);
609 store_data_long(destoffset, destval);
610 } else {
611 u16 destval;
612 u16 *shiftreg;
614 destoffset = decode_rm10_address(rl);
615 DECODE_PRINTF(",");
616 shiftreg = DECODE_RM_WORD_REGISTER(rh);
617 DECODE_PRINTF(",");
618 shift = fetch_byte_imm();
619 DECODE_PRINTF2("%d\n", shift);
620 TRACE_AND_STEP();
621 destval = fetch_data_word(destoffset);
622 destval = shld_word(destval,*shiftreg,shift);
623 store_data_word(destoffset, destval);
625 break;
626 case 3: /* register to register */
627 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
628 u32 *destreg,*shiftreg;
630 destreg = DECODE_RM_LONG_REGISTER(rl);
631 DECODE_PRINTF(",");
632 shiftreg = DECODE_RM_LONG_REGISTER(rh);
633 DECODE_PRINTF(",");
634 shift = fetch_byte_imm();
635 DECODE_PRINTF2("%d\n", shift);
636 TRACE_AND_STEP();
637 *destreg = shld_long(*destreg,*shiftreg,shift);
638 } else {
639 u16 *destreg,*shiftreg;
641 destreg = DECODE_RM_WORD_REGISTER(rl);
642 DECODE_PRINTF(",");
643 shiftreg = DECODE_RM_WORD_REGISTER(rh);
644 DECODE_PRINTF(",");
645 shift = fetch_byte_imm();
646 DECODE_PRINTF2("%d\n", shift);
647 TRACE_AND_STEP();
648 *destreg = shld_word(*destreg,*shiftreg,shift);
650 break;
652 DECODE_CLEAR_SEGOVR();
653 END_OF_INSTR();
656 /****************************************************************************
657 REMARKS:
658 Handles opcode 0x0f,0xa5
659 ****************************************************************************/
660 static void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
662 int mod, rl, rh;
663 uint destoffset;
665 START_OF_INSTR();
666 DECODE_PRINTF("SHLD\t");
667 FETCH_DECODE_MODRM(mod, rh, rl);
668 switch (mod) {
669 case 0:
670 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
671 u32 destval;
672 u32 *shiftreg;
674 destoffset = decode_rm00_address(rl);
675 DECODE_PRINTF(",");
676 shiftreg = DECODE_RM_LONG_REGISTER(rh);
677 DECODE_PRINTF(",CL\n");
678 TRACE_AND_STEP();
679 destval = fetch_data_long(destoffset);
680 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
681 store_data_long(destoffset, destval);
682 } else {
683 u16 destval;
684 u16 *shiftreg;
686 destoffset = decode_rm00_address(rl);
687 DECODE_PRINTF(",");
688 shiftreg = DECODE_RM_WORD_REGISTER(rh);
689 DECODE_PRINTF(",CL\n");
690 TRACE_AND_STEP();
691 destval = fetch_data_word(destoffset);
692 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
693 store_data_word(destoffset, destval);
695 break;
696 case 1:
697 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
698 u32 destval;
699 u32 *shiftreg;
701 destoffset = decode_rm01_address(rl);
702 DECODE_PRINTF(",");
703 shiftreg = DECODE_RM_LONG_REGISTER(rh);
704 DECODE_PRINTF(",CL\n");
705 TRACE_AND_STEP();
706 destval = fetch_data_long(destoffset);
707 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
708 store_data_long(destoffset, destval);
709 } else {
710 u16 destval;
711 u16 *shiftreg;
713 destoffset = decode_rm01_address(rl);
714 DECODE_PRINTF(",");
715 shiftreg = DECODE_RM_WORD_REGISTER(rh);
716 DECODE_PRINTF(",CL\n");
717 TRACE_AND_STEP();
718 destval = fetch_data_word(destoffset);
719 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
720 store_data_word(destoffset, destval);
722 break;
723 case 2:
724 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
725 u32 destval;
726 u32 *shiftreg;
728 destoffset = decode_rm10_address(rl);
729 DECODE_PRINTF(",");
730 shiftreg = DECODE_RM_LONG_REGISTER(rh);
731 DECODE_PRINTF(",CL\n");
732 TRACE_AND_STEP();
733 destval = fetch_data_long(destoffset);
734 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
735 store_data_long(destoffset, destval);
736 } else {
737 u16 destval;
738 u16 *shiftreg;
740 destoffset = decode_rm10_address(rl);
741 DECODE_PRINTF(",");
742 shiftreg = DECODE_RM_WORD_REGISTER(rh);
743 DECODE_PRINTF(",CL\n");
744 TRACE_AND_STEP();
745 destval = fetch_data_word(destoffset);
746 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
747 store_data_word(destoffset, destval);
749 break;
750 case 3: /* register to register */
751 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
752 u32 *destreg,*shiftreg;
754 destreg = DECODE_RM_LONG_REGISTER(rl);
755 DECODE_PRINTF(",");
756 shiftreg = DECODE_RM_LONG_REGISTER(rh);
757 DECODE_PRINTF(",CL\n");
758 TRACE_AND_STEP();
759 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
760 } else {
761 u16 *destreg,*shiftreg;
763 destreg = DECODE_RM_WORD_REGISTER(rl);
764 DECODE_PRINTF(",");
765 shiftreg = DECODE_RM_WORD_REGISTER(rh);
766 DECODE_PRINTF(",CL\n");
767 TRACE_AND_STEP();
768 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
770 break;
772 DECODE_CLEAR_SEGOVR();
773 END_OF_INSTR();
776 /****************************************************************************
777 REMARKS:
778 Handles opcode 0x0f,0xa8
779 ****************************************************************************/
780 static void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
782 START_OF_INSTR();
783 DECODE_PRINTF("PUSH\tGS\n");
784 TRACE_AND_STEP();
785 push_word(M.x86.R_GS);
786 DECODE_CLEAR_SEGOVR();
787 END_OF_INSTR();
790 /****************************************************************************
791 REMARKS:
792 Handles opcode 0x0f,0xa9
793 ****************************************************************************/
794 static void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
796 START_OF_INSTR();
797 DECODE_PRINTF("POP\tGS\n");
798 TRACE_AND_STEP();
799 M.x86.R_GS = pop_word();
800 DECODE_CLEAR_SEGOVR();
801 END_OF_INSTR();
804 /****************************************************************************
805 REMARKS:
806 Handles opcode 0x0f,0xab
807 ****************************************************************************/
808 static void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
810 int mod, rl, rh;
811 uint srcoffset;
812 int bit,disp;
814 START_OF_INSTR();
815 DECODE_PRINTF("BTS\t");
816 FETCH_DECODE_MODRM(mod, rh, rl);
817 switch (mod) {
818 case 0:
819 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
820 u32 srcval,mask;
821 u32 *shiftreg;
823 srcoffset = decode_rm00_address(rl);
824 DECODE_PRINTF(",");
825 shiftreg = DECODE_RM_LONG_REGISTER(rh);
826 TRACE_AND_STEP();
827 bit = *shiftreg & 0x1F;
828 disp = (s16)*shiftreg >> 5;
829 srcval = fetch_data_long(srcoffset+disp);
830 mask = (0x1 << bit);
831 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
832 store_data_long(srcoffset+disp, srcval | mask);
833 } else {
834 u16 srcval,mask;
835 u16 *shiftreg;
837 srcoffset = decode_rm00_address(rl);
838 DECODE_PRINTF(",");
839 shiftreg = DECODE_RM_WORD_REGISTER(rh);
840 TRACE_AND_STEP();
841 bit = *shiftreg & 0xF;
842 disp = (s16)*shiftreg >> 4;
843 srcval = fetch_data_word(srcoffset+disp);
844 mask = (u16)(0x1 << bit);
845 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
846 store_data_word(srcoffset+disp, srcval | mask);
848 break;
849 case 1:
850 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
851 u32 srcval,mask;
852 u32 *shiftreg;
854 srcoffset = decode_rm01_address(rl);
855 DECODE_PRINTF(",");
856 shiftreg = DECODE_RM_LONG_REGISTER(rh);
857 TRACE_AND_STEP();
858 bit = *shiftreg & 0x1F;
859 disp = (s16)*shiftreg >> 5;
860 srcval = fetch_data_long(srcoffset+disp);
861 mask = (0x1 << bit);
862 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
863 store_data_long(srcoffset+disp, srcval | mask);
864 } else {
865 u16 srcval,mask;
866 u16 *shiftreg;
868 srcoffset = decode_rm01_address(rl);
869 DECODE_PRINTF(",");
870 shiftreg = DECODE_RM_WORD_REGISTER(rh);
871 TRACE_AND_STEP();
872 bit = *shiftreg & 0xF;
873 disp = (s16)*shiftreg >> 4;
874 srcval = fetch_data_word(srcoffset+disp);
875 mask = (u16)(0x1 << bit);
876 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
877 store_data_word(srcoffset+disp, srcval | mask);
879 break;
880 case 2:
881 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
882 u32 srcval,mask;
883 u32 *shiftreg;
885 srcoffset = decode_rm10_address(rl);
886 DECODE_PRINTF(",");
887 shiftreg = DECODE_RM_LONG_REGISTER(rh);
888 TRACE_AND_STEP();
889 bit = *shiftreg & 0x1F;
890 disp = (s16)*shiftreg >> 5;
891 srcval = fetch_data_long(srcoffset+disp);
892 mask = (0x1 << bit);
893 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
894 store_data_long(srcoffset+disp, srcval | mask);
895 } else {
896 u16 srcval,mask;
897 u16 *shiftreg;
899 srcoffset = decode_rm10_address(rl);
900 DECODE_PRINTF(",");
901 shiftreg = DECODE_RM_WORD_REGISTER(rh);
902 TRACE_AND_STEP();
903 bit = *shiftreg & 0xF;
904 disp = (s16)*shiftreg >> 4;
905 srcval = fetch_data_word(srcoffset+disp);
906 mask = (u16)(0x1 << bit);
907 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
908 store_data_word(srcoffset+disp, srcval | mask);
910 break;
911 case 3: /* register to register */
912 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
913 u32 *srcreg,*shiftreg;
914 u32 mask;
916 srcreg = DECODE_RM_LONG_REGISTER(rl);
917 DECODE_PRINTF(",");
918 shiftreg = DECODE_RM_LONG_REGISTER(rh);
919 TRACE_AND_STEP();
920 bit = *shiftreg & 0x1F;
921 mask = (0x1 << bit);
922 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
923 *srcreg |= mask;
924 } else {
925 u16 *srcreg,*shiftreg;
926 u16 mask;
928 srcreg = DECODE_RM_WORD_REGISTER(rl);
929 DECODE_PRINTF(",");
930 shiftreg = DECODE_RM_WORD_REGISTER(rh);
931 TRACE_AND_STEP();
932 bit = *shiftreg & 0xF;
933 mask = (u16)(0x1 << bit);
934 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
935 *srcreg |= mask;
937 break;
939 DECODE_CLEAR_SEGOVR();
940 END_OF_INSTR();
943 /****************************************************************************
944 REMARKS:
945 Handles opcode 0x0f,0xac
946 ****************************************************************************/
947 static void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
949 int mod, rl, rh;
950 uint destoffset;
951 u8 shift;
953 START_OF_INSTR();
954 DECODE_PRINTF("SHLD\t");
955 FETCH_DECODE_MODRM(mod, rh, rl);
956 switch (mod) {
957 case 0:
958 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
959 u32 destval;
960 u32 *shiftreg;
962 destoffset = decode_rm00_address(rl);
963 DECODE_PRINTF(",");
964 shiftreg = DECODE_RM_LONG_REGISTER(rh);
965 DECODE_PRINTF(",");
966 shift = fetch_byte_imm();
967 DECODE_PRINTF2("%d\n", shift);
968 TRACE_AND_STEP();
969 destval = fetch_data_long(destoffset);
970 destval = shrd_long(destval,*shiftreg,shift);
971 store_data_long(destoffset, destval);
972 } else {
973 u16 destval;
974 u16 *shiftreg;
976 destoffset = decode_rm00_address(rl);
977 DECODE_PRINTF(",");
978 shiftreg = DECODE_RM_WORD_REGISTER(rh);
979 DECODE_PRINTF(",");
980 shift = fetch_byte_imm();
981 DECODE_PRINTF2("%d\n", shift);
982 TRACE_AND_STEP();
983 destval = fetch_data_word(destoffset);
984 destval = shrd_word(destval,*shiftreg,shift);
985 store_data_word(destoffset, destval);
987 break;
988 case 1:
989 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
990 u32 destval;
991 u32 *shiftreg;
993 destoffset = decode_rm01_address(rl);
994 DECODE_PRINTF(",");
995 shiftreg = DECODE_RM_LONG_REGISTER(rh);
996 DECODE_PRINTF(",");
997 shift = fetch_byte_imm();
998 DECODE_PRINTF2("%d\n", shift);
999 TRACE_AND_STEP();
1000 destval = fetch_data_long(destoffset);
1001 destval = shrd_long(destval,*shiftreg,shift);
1002 store_data_long(destoffset, destval);
1003 } else {
1004 u16 destval;
1005 u16 *shiftreg;
1007 destoffset = decode_rm01_address(rl);
1008 DECODE_PRINTF(",");
1009 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1010 DECODE_PRINTF(",");
1011 shift = fetch_byte_imm();
1012 DECODE_PRINTF2("%d\n", shift);
1013 TRACE_AND_STEP();
1014 destval = fetch_data_word(destoffset);
1015 destval = shrd_word(destval,*shiftreg,shift);
1016 store_data_word(destoffset, destval);
1018 break;
1019 case 2:
1020 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1021 u32 destval;
1022 u32 *shiftreg;
1024 destoffset = decode_rm10_address(rl);
1025 DECODE_PRINTF(",");
1026 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1027 DECODE_PRINTF(",");
1028 shift = fetch_byte_imm();
1029 DECODE_PRINTF2("%d\n", shift);
1030 TRACE_AND_STEP();
1031 destval = fetch_data_long(destoffset);
1032 destval = shrd_long(destval,*shiftreg,shift);
1033 store_data_long(destoffset, destval);
1034 } else {
1035 u16 destval;
1036 u16 *shiftreg;
1038 destoffset = decode_rm10_address(rl);
1039 DECODE_PRINTF(",");
1040 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1041 DECODE_PRINTF(",");
1042 shift = fetch_byte_imm();
1043 DECODE_PRINTF2("%d\n", shift);
1044 TRACE_AND_STEP();
1045 destval = fetch_data_word(destoffset);
1046 destval = shrd_word(destval,*shiftreg,shift);
1047 store_data_word(destoffset, destval);
1049 break;
1050 case 3: /* register to register */
1051 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1052 u32 *destreg,*shiftreg;
1054 destreg = DECODE_RM_LONG_REGISTER(rl);
1055 DECODE_PRINTF(",");
1056 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1057 DECODE_PRINTF(",");
1058 shift = fetch_byte_imm();
1059 DECODE_PRINTF2("%d\n", shift);
1060 TRACE_AND_STEP();
1061 *destreg = shrd_long(*destreg,*shiftreg,shift);
1062 } else {
1063 u16 *destreg,*shiftreg;
1065 destreg = DECODE_RM_WORD_REGISTER(rl);
1066 DECODE_PRINTF(",");
1067 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1068 DECODE_PRINTF(",");
1069 shift = fetch_byte_imm();
1070 DECODE_PRINTF2("%d\n", shift);
1071 TRACE_AND_STEP();
1072 *destreg = shrd_word(*destreg,*shiftreg,shift);
1074 break;
1076 DECODE_CLEAR_SEGOVR();
1077 END_OF_INSTR();
1080 /****************************************************************************
1081 REMARKS:
1082 Handles opcode 0x0f,0xad
1083 ****************************************************************************/
1084 static void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
1086 int mod, rl, rh;
1087 uint destoffset;
1089 START_OF_INSTR();
1090 DECODE_PRINTF("SHLD\t");
1091 FETCH_DECODE_MODRM(mod, rh, rl);
1092 switch (mod) {
1093 case 0:
1094 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1095 u32 destval;
1096 u32 *shiftreg;
1098 destoffset = decode_rm00_address(rl);
1099 DECODE_PRINTF(",");
1100 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1101 DECODE_PRINTF(",CL\n");
1102 TRACE_AND_STEP();
1103 destval = fetch_data_long(destoffset);
1104 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1105 store_data_long(destoffset, destval);
1106 } else {
1107 u16 destval;
1108 u16 *shiftreg;
1110 destoffset = decode_rm00_address(rl);
1111 DECODE_PRINTF(",");
1112 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1113 DECODE_PRINTF(",CL\n");
1114 TRACE_AND_STEP();
1115 destval = fetch_data_word(destoffset);
1116 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1117 store_data_word(destoffset, destval);
1119 break;
1120 case 1:
1121 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1122 u32 destval;
1123 u32 *shiftreg;
1125 destoffset = decode_rm01_address(rl);
1126 DECODE_PRINTF(",");
1127 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1128 DECODE_PRINTF(",CL\n");
1129 TRACE_AND_STEP();
1130 destval = fetch_data_long(destoffset);
1131 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1132 store_data_long(destoffset, destval);
1133 } else {
1134 u16 destval;
1135 u16 *shiftreg;
1137 destoffset = decode_rm01_address(rl);
1138 DECODE_PRINTF(",");
1139 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1140 DECODE_PRINTF(",CL\n");
1141 TRACE_AND_STEP();
1142 destval = fetch_data_word(destoffset);
1143 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1144 store_data_word(destoffset, destval);
1146 break;
1147 case 2:
1148 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1149 u32 destval;
1150 u32 *shiftreg;
1152 destoffset = decode_rm10_address(rl);
1153 DECODE_PRINTF(",");
1154 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1155 DECODE_PRINTF(",CL\n");
1156 TRACE_AND_STEP();
1157 destval = fetch_data_long(destoffset);
1158 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
1159 store_data_long(destoffset, destval);
1160 } else {
1161 u16 destval;
1162 u16 *shiftreg;
1164 destoffset = decode_rm10_address(rl);
1165 DECODE_PRINTF(",");
1166 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1167 DECODE_PRINTF(",CL\n");
1168 TRACE_AND_STEP();
1169 destval = fetch_data_word(destoffset);
1170 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
1171 store_data_word(destoffset, destval);
1173 break;
1174 case 3: /* register to register */
1175 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1176 u32 *destreg,*shiftreg;
1178 destreg = DECODE_RM_LONG_REGISTER(rl);
1179 DECODE_PRINTF(",");
1180 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1181 DECODE_PRINTF(",CL\n");
1182 TRACE_AND_STEP();
1183 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
1184 } else {
1185 u16 *destreg,*shiftreg;
1187 destreg = DECODE_RM_WORD_REGISTER(rl);
1188 DECODE_PRINTF(",");
1189 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1190 DECODE_PRINTF(",CL\n");
1191 TRACE_AND_STEP();
1192 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
1194 break;
1196 DECODE_CLEAR_SEGOVR();
1197 END_OF_INSTR();
1200 /****************************************************************************
1201 REMARKS:
1202 Handles opcode 0x0f,0xaf
1203 ****************************************************************************/
1204 static void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
1206 int mod, rl, rh;
1207 uint srcoffset;
1209 START_OF_INSTR();
1210 DECODE_PRINTF("IMUL\t");
1211 FETCH_DECODE_MODRM(mod, rh, rl);
1212 switch (mod) {
1213 case 0:
1214 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1215 u32 *destreg;
1216 u32 srcval;
1217 u32 res_lo,res_hi;
1219 destreg = DECODE_RM_LONG_REGISTER(rh);
1220 DECODE_PRINTF(",");
1221 srcoffset = decode_rm00_address(rl);
1222 srcval = fetch_data_long(srcoffset);
1223 TRACE_AND_STEP();
1224 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1225 if (res_hi != 0) {
1226 SET_FLAG(F_CF);
1227 SET_FLAG(F_OF);
1228 } else {
1229 CLEAR_FLAG(F_CF);
1230 CLEAR_FLAG(F_OF);
1232 *destreg = (u32)res_lo;
1233 } else {
1234 u16 *destreg;
1235 u16 srcval;
1236 u32 res;
1238 destreg = DECODE_RM_WORD_REGISTER(rh);
1239 DECODE_PRINTF(",");
1240 srcoffset = decode_rm00_address(rl);
1241 srcval = fetch_data_word(srcoffset);
1242 TRACE_AND_STEP();
1243 res = (s16)*destreg * (s16)srcval;
1244 if (res > 0xFFFF) {
1245 SET_FLAG(F_CF);
1246 SET_FLAG(F_OF);
1247 } else {
1248 CLEAR_FLAG(F_CF);
1249 CLEAR_FLAG(F_OF);
1251 *destreg = (u16)res;
1253 break;
1254 case 1:
1255 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1256 u32 *destreg;
1257 u32 srcval;
1258 u32 res_lo,res_hi;
1260 destreg = DECODE_RM_LONG_REGISTER(rh);
1261 DECODE_PRINTF(",");
1262 srcoffset = decode_rm01_address(rl);
1263 srcval = fetch_data_long(srcoffset);
1264 TRACE_AND_STEP();
1265 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1266 if (res_hi != 0) {
1267 SET_FLAG(F_CF);
1268 SET_FLAG(F_OF);
1269 } else {
1270 CLEAR_FLAG(F_CF);
1271 CLEAR_FLAG(F_OF);
1273 *destreg = (u32)res_lo;
1274 } else {
1275 u16 *destreg;
1276 u16 srcval;
1277 u32 res;
1279 destreg = DECODE_RM_WORD_REGISTER(rh);
1280 DECODE_PRINTF(",");
1281 srcoffset = decode_rm01_address(rl);
1282 srcval = fetch_data_word(srcoffset);
1283 TRACE_AND_STEP();
1284 res = (s16)*destreg * (s16)srcval;
1285 if (res > 0xFFFF) {
1286 SET_FLAG(F_CF);
1287 SET_FLAG(F_OF);
1288 } else {
1289 CLEAR_FLAG(F_CF);
1290 CLEAR_FLAG(F_OF);
1292 *destreg = (u16)res;
1294 break;
1295 case 2:
1296 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1297 u32 *destreg;
1298 u32 srcval;
1299 u32 res_lo,res_hi;
1301 destreg = DECODE_RM_LONG_REGISTER(rh);
1302 DECODE_PRINTF(",");
1303 srcoffset = decode_rm10_address(rl);
1304 srcval = fetch_data_long(srcoffset);
1305 TRACE_AND_STEP();
1306 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
1307 if (res_hi != 0) {
1308 SET_FLAG(F_CF);
1309 SET_FLAG(F_OF);
1310 } else {
1311 CLEAR_FLAG(F_CF);
1312 CLEAR_FLAG(F_OF);
1314 *destreg = (u32)res_lo;
1315 } else {
1316 u16 *destreg;
1317 u16 srcval;
1318 u32 res;
1320 destreg = DECODE_RM_WORD_REGISTER(rh);
1321 DECODE_PRINTF(",");
1322 srcoffset = decode_rm10_address(rl);
1323 srcval = fetch_data_word(srcoffset);
1324 TRACE_AND_STEP();
1325 res = (s16)*destreg * (s16)srcval;
1326 if (res > 0xFFFF) {
1327 SET_FLAG(F_CF);
1328 SET_FLAG(F_OF);
1329 } else {
1330 CLEAR_FLAG(F_CF);
1331 CLEAR_FLAG(F_OF);
1333 *destreg = (u16)res;
1335 break;
1336 case 3: /* register to register */
1337 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1338 u32 *destreg,*srcreg;
1339 u32 res_lo,res_hi;
1341 destreg = DECODE_RM_LONG_REGISTER(rh);
1342 DECODE_PRINTF(",");
1343 srcreg = DECODE_RM_LONG_REGISTER(rl);
1344 TRACE_AND_STEP();
1345 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
1346 if (res_hi != 0) {
1347 SET_FLAG(F_CF);
1348 SET_FLAG(F_OF);
1349 } else {
1350 CLEAR_FLAG(F_CF);
1351 CLEAR_FLAG(F_OF);
1353 *destreg = (u32)res_lo;
1354 } else {
1355 u16 *destreg,*srcreg;
1356 u32 res;
1358 destreg = DECODE_RM_WORD_REGISTER(rh);
1359 DECODE_PRINTF(",");
1360 srcreg = DECODE_RM_WORD_REGISTER(rl);
1361 res = (s16)*destreg * (s16)*srcreg;
1362 if (res > 0xFFFF) {
1363 SET_FLAG(F_CF);
1364 SET_FLAG(F_OF);
1365 } else {
1366 CLEAR_FLAG(F_CF);
1367 CLEAR_FLAG(F_OF);
1369 *destreg = (u16)res;
1371 break;
1373 DECODE_CLEAR_SEGOVR();
1374 END_OF_INSTR();
1377 /****************************************************************************
1378 REMARKS:
1379 Handles opcode 0x0f,0xb2
1380 ****************************************************************************/
1381 static void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
1383 int mod, rh, rl;
1384 u16 *dstreg;
1385 uint srcoffset;
1387 START_OF_INSTR();
1388 DECODE_PRINTF("LSS\t");
1389 FETCH_DECODE_MODRM(mod, rh, rl);
1390 switch (mod) {
1391 case 0:
1392 dstreg = DECODE_RM_WORD_REGISTER(rh);
1393 DECODE_PRINTF(",");
1394 srcoffset = decode_rm00_address(rl);
1395 DECODE_PRINTF("\n");
1396 TRACE_AND_STEP();
1397 *dstreg = fetch_data_word(srcoffset);
1398 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1399 break;
1400 case 1:
1401 dstreg = DECODE_RM_WORD_REGISTER(rh);
1402 DECODE_PRINTF(",");
1403 srcoffset = decode_rm01_address(rl);
1404 DECODE_PRINTF("\n");
1405 TRACE_AND_STEP();
1406 *dstreg = fetch_data_word(srcoffset);
1407 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1408 break;
1409 case 2:
1410 dstreg = DECODE_RM_WORD_REGISTER(rh);
1411 DECODE_PRINTF(",");
1412 srcoffset = decode_rm10_address(rl);
1413 DECODE_PRINTF("\n");
1414 TRACE_AND_STEP();
1415 *dstreg = fetch_data_word(srcoffset);
1416 M.x86.R_SS = fetch_data_word(srcoffset + 2);
1417 break;
1418 case 3: /* register to register */
1419 /* UNDEFINED! */
1420 TRACE_AND_STEP();
1422 DECODE_CLEAR_SEGOVR();
1423 END_OF_INSTR();
1426 /****************************************************************************
1427 REMARKS:
1428 Handles opcode 0x0f,0xb3
1429 ****************************************************************************/
1430 static void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
1432 int mod, rl, rh;
1433 uint srcoffset;
1434 int bit,disp;
1436 START_OF_INSTR();
1437 DECODE_PRINTF("BTR\t");
1438 FETCH_DECODE_MODRM(mod, rh, rl);
1439 switch (mod) {
1440 case 0:
1441 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1442 u32 srcval,mask;
1443 u32 *shiftreg;
1445 srcoffset = decode_rm00_address(rl);
1446 DECODE_PRINTF(",");
1447 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1448 TRACE_AND_STEP();
1449 bit = *shiftreg & 0x1F;
1450 disp = (s16)*shiftreg >> 5;
1451 srcval = fetch_data_long(srcoffset+disp);
1452 mask = (0x1 << bit);
1453 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1454 store_data_long(srcoffset+disp, srcval & ~mask);
1455 } else {
1456 u16 srcval,mask;
1457 u16 *shiftreg;
1459 srcoffset = decode_rm00_address(rl);
1460 DECODE_PRINTF(",");
1461 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1462 TRACE_AND_STEP();
1463 bit = *shiftreg & 0xF;
1464 disp = (s16)*shiftreg >> 4;
1465 srcval = fetch_data_word(srcoffset+disp);
1466 mask = (u16)(0x1 << bit);
1467 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1468 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1470 break;
1471 case 1:
1472 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1473 u32 srcval,mask;
1474 u32 *shiftreg;
1476 srcoffset = decode_rm01_address(rl);
1477 DECODE_PRINTF(",");
1478 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1479 TRACE_AND_STEP();
1480 bit = *shiftreg & 0x1F;
1481 disp = (s16)*shiftreg >> 5;
1482 srcval = fetch_data_long(srcoffset+disp);
1483 mask = (0x1 << bit);
1484 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1485 store_data_long(srcoffset+disp, srcval & ~mask);
1486 } else {
1487 u16 srcval,mask;
1488 u16 *shiftreg;
1490 srcoffset = decode_rm01_address(rl);
1491 DECODE_PRINTF(",");
1492 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1493 TRACE_AND_STEP();
1494 bit = *shiftreg & 0xF;
1495 disp = (s16)*shiftreg >> 4;
1496 srcval = fetch_data_word(srcoffset+disp);
1497 mask = (u16)(0x1 << bit);
1498 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1499 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1501 break;
1502 case 2:
1503 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1504 u32 srcval,mask;
1505 u32 *shiftreg;
1507 srcoffset = decode_rm10_address(rl);
1508 DECODE_PRINTF(",");
1509 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1510 TRACE_AND_STEP();
1511 bit = *shiftreg & 0x1F;
1512 disp = (s16)*shiftreg >> 5;
1513 srcval = fetch_data_long(srcoffset+disp);
1514 mask = (0x1 << bit);
1515 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1516 store_data_long(srcoffset+disp, srcval & ~mask);
1517 } else {
1518 u16 srcval,mask;
1519 u16 *shiftreg;
1521 srcoffset = decode_rm10_address(rl);
1522 DECODE_PRINTF(",");
1523 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1524 TRACE_AND_STEP();
1525 bit = *shiftreg & 0xF;
1526 disp = (s16)*shiftreg >> 4;
1527 srcval = fetch_data_word(srcoffset+disp);
1528 mask = (u16)(0x1 << bit);
1529 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1530 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
1532 break;
1533 case 3: /* register to register */
1534 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1535 u32 *srcreg,*shiftreg;
1536 u32 mask;
1538 srcreg = DECODE_RM_LONG_REGISTER(rl);
1539 DECODE_PRINTF(",");
1540 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1541 TRACE_AND_STEP();
1542 bit = *shiftreg & 0x1F;
1543 mask = (0x1 << bit);
1544 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1545 *srcreg &= ~mask;
1546 } else {
1547 u16 *srcreg,*shiftreg;
1548 u16 mask;
1550 srcreg = DECODE_RM_WORD_REGISTER(rl);
1551 DECODE_PRINTF(",");
1552 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1553 TRACE_AND_STEP();
1554 bit = *shiftreg & 0xF;
1555 mask = (u16)(0x1 << bit);
1556 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1557 *srcreg &= ~mask;
1559 break;
1561 DECODE_CLEAR_SEGOVR();
1562 END_OF_INSTR();
1565 /****************************************************************************
1566 REMARKS:
1567 Handles opcode 0x0f,0xb4
1568 ****************************************************************************/
1569 static void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
1571 int mod, rh, rl;
1572 u16 *dstreg;
1573 uint srcoffset;
1575 START_OF_INSTR();
1576 DECODE_PRINTF("LFS\t");
1577 FETCH_DECODE_MODRM(mod, rh, rl);
1578 switch (mod) {
1579 case 0:
1580 dstreg = DECODE_RM_WORD_REGISTER(rh);
1581 DECODE_PRINTF(",");
1582 srcoffset = decode_rm00_address(rl);
1583 DECODE_PRINTF("\n");
1584 TRACE_AND_STEP();
1585 *dstreg = fetch_data_word(srcoffset);
1586 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1587 break;
1588 case 1:
1589 dstreg = DECODE_RM_WORD_REGISTER(rh);
1590 DECODE_PRINTF(",");
1591 srcoffset = decode_rm01_address(rl);
1592 DECODE_PRINTF("\n");
1593 TRACE_AND_STEP();
1594 *dstreg = fetch_data_word(srcoffset);
1595 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1596 break;
1597 case 2:
1598 dstreg = DECODE_RM_WORD_REGISTER(rh);
1599 DECODE_PRINTF(",");
1600 srcoffset = decode_rm10_address(rl);
1601 DECODE_PRINTF("\n");
1602 TRACE_AND_STEP();
1603 *dstreg = fetch_data_word(srcoffset);
1604 M.x86.R_FS = fetch_data_word(srcoffset + 2);
1605 break;
1606 case 3: /* register to register */
1607 /* UNDEFINED! */
1608 TRACE_AND_STEP();
1610 DECODE_CLEAR_SEGOVR();
1611 END_OF_INSTR();
1614 /****************************************************************************
1615 REMARKS:
1616 Handles opcode 0x0f,0xb5
1617 ****************************************************************************/
1618 static void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
1620 int mod, rh, rl;
1621 u16 *dstreg;
1622 uint srcoffset;
1624 START_OF_INSTR();
1625 DECODE_PRINTF("LGS\t");
1626 FETCH_DECODE_MODRM(mod, rh, rl);
1627 switch (mod) {
1628 case 0:
1629 dstreg = DECODE_RM_WORD_REGISTER(rh);
1630 DECODE_PRINTF(",");
1631 srcoffset = decode_rm00_address(rl);
1632 DECODE_PRINTF("\n");
1633 TRACE_AND_STEP();
1634 *dstreg = fetch_data_word(srcoffset);
1635 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1636 break;
1637 case 1:
1638 dstreg = DECODE_RM_WORD_REGISTER(rh);
1639 DECODE_PRINTF(",");
1640 srcoffset = decode_rm01_address(rl);
1641 DECODE_PRINTF("\n");
1642 TRACE_AND_STEP();
1643 *dstreg = fetch_data_word(srcoffset);
1644 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1645 break;
1646 case 2:
1647 dstreg = DECODE_RM_WORD_REGISTER(rh);
1648 DECODE_PRINTF(",");
1649 srcoffset = decode_rm10_address(rl);
1650 DECODE_PRINTF("\n");
1651 TRACE_AND_STEP();
1652 *dstreg = fetch_data_word(srcoffset);
1653 M.x86.R_GS = fetch_data_word(srcoffset + 2);
1654 break;
1655 case 3: /* register to register */
1656 /* UNDEFINED! */
1657 TRACE_AND_STEP();
1659 DECODE_CLEAR_SEGOVR();
1660 END_OF_INSTR();
1663 /****************************************************************************
1664 REMARKS:
1665 Handles opcode 0x0f,0xb6
1666 ****************************************************************************/
1667 static void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1669 int mod, rl, rh;
1670 uint srcoffset;
1672 START_OF_INSTR();
1673 DECODE_PRINTF("MOVZX\t");
1674 FETCH_DECODE_MODRM(mod, rh, rl);
1675 switch (mod) {
1676 case 0:
1677 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1678 u32 *destreg;
1679 u32 srcval;
1681 destreg = DECODE_RM_LONG_REGISTER(rh);
1682 DECODE_PRINTF(",");
1683 srcoffset = decode_rm00_address(rl);
1684 srcval = fetch_data_byte(srcoffset);
1685 DECODE_PRINTF("\n");
1686 TRACE_AND_STEP();
1687 *destreg = srcval;
1688 } else {
1689 u16 *destreg;
1690 u16 srcval;
1692 destreg = DECODE_RM_WORD_REGISTER(rh);
1693 DECODE_PRINTF(",");
1694 srcoffset = decode_rm00_address(rl);
1695 srcval = fetch_data_byte(srcoffset);
1696 DECODE_PRINTF("\n");
1697 TRACE_AND_STEP();
1698 *destreg = srcval;
1700 break;
1701 case 1:
1702 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1703 u32 *destreg;
1704 u32 srcval;
1706 destreg = DECODE_RM_LONG_REGISTER(rh);
1707 DECODE_PRINTF(",");
1708 srcoffset = decode_rm01_address(rl);
1709 srcval = fetch_data_byte(srcoffset);
1710 DECODE_PRINTF("\n");
1711 TRACE_AND_STEP();
1712 *destreg = srcval;
1713 } else {
1714 u16 *destreg;
1715 u16 srcval;
1717 destreg = DECODE_RM_WORD_REGISTER(rh);
1718 DECODE_PRINTF(",");
1719 srcoffset = decode_rm01_address(rl);
1720 srcval = fetch_data_byte(srcoffset);
1721 DECODE_PRINTF("\n");
1722 TRACE_AND_STEP();
1723 *destreg = srcval;
1725 break;
1726 case 2:
1727 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1728 u32 *destreg;
1729 u32 srcval;
1731 destreg = DECODE_RM_LONG_REGISTER(rh);
1732 DECODE_PRINTF(",");
1733 srcoffset = decode_rm10_address(rl);
1734 srcval = fetch_data_byte(srcoffset);
1735 DECODE_PRINTF("\n");
1736 TRACE_AND_STEP();
1737 *destreg = srcval;
1738 } else {
1739 u16 *destreg;
1740 u16 srcval;
1742 destreg = DECODE_RM_WORD_REGISTER(rh);
1743 DECODE_PRINTF(",");
1744 srcoffset = decode_rm10_address(rl);
1745 srcval = fetch_data_byte(srcoffset);
1746 DECODE_PRINTF("\n");
1747 TRACE_AND_STEP();
1748 *destreg = srcval;
1750 break;
1751 case 3: /* register to register */
1752 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1753 u32 *destreg;
1754 u8 *srcreg;
1756 destreg = DECODE_RM_LONG_REGISTER(rh);
1757 DECODE_PRINTF(",");
1758 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1759 DECODE_PRINTF("\n");
1760 TRACE_AND_STEP();
1761 *destreg = *srcreg;
1762 } else {
1763 u16 *destreg;
1764 u8 *srcreg;
1766 destreg = DECODE_RM_WORD_REGISTER(rh);
1767 DECODE_PRINTF(",");
1768 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1769 DECODE_PRINTF("\n");
1770 TRACE_AND_STEP();
1771 *destreg = *srcreg;
1773 break;
1775 DECODE_CLEAR_SEGOVR();
1776 END_OF_INSTR();
1779 /****************************************************************************
1780 REMARKS:
1781 Handles opcode 0x0f,0xb7
1782 ****************************************************************************/
1783 static void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1785 int mod, rl, rh;
1786 uint srcoffset;
1787 u32 *destreg;
1788 u32 srcval;
1789 u16 *srcreg;
1791 START_OF_INSTR();
1792 DECODE_PRINTF("MOVZX\t");
1793 FETCH_DECODE_MODRM(mod, rh, rl);
1794 switch (mod) {
1795 case 0:
1796 destreg = DECODE_RM_LONG_REGISTER(rh);
1797 DECODE_PRINTF(",");
1798 srcoffset = decode_rm00_address(rl);
1799 srcval = fetch_data_word(srcoffset);
1800 DECODE_PRINTF("\n");
1801 TRACE_AND_STEP();
1802 *destreg = srcval;
1803 break;
1804 case 1:
1805 destreg = DECODE_RM_LONG_REGISTER(rh);
1806 DECODE_PRINTF(",");
1807 srcoffset = decode_rm01_address(rl);
1808 srcval = fetch_data_word(srcoffset);
1809 DECODE_PRINTF("\n");
1810 TRACE_AND_STEP();
1811 *destreg = srcval;
1812 break;
1813 case 2:
1814 destreg = DECODE_RM_LONG_REGISTER(rh);
1815 DECODE_PRINTF(",");
1816 srcoffset = decode_rm10_address(rl);
1817 srcval = fetch_data_word(srcoffset);
1818 DECODE_PRINTF("\n");
1819 TRACE_AND_STEP();
1820 *destreg = srcval;
1821 break;
1822 case 3: /* register to register */
1823 destreg = DECODE_RM_LONG_REGISTER(rh);
1824 DECODE_PRINTF(",");
1825 srcreg = DECODE_RM_WORD_REGISTER(rl);
1826 DECODE_PRINTF("\n");
1827 TRACE_AND_STEP();
1828 *destreg = *srcreg;
1829 break;
1831 DECODE_CLEAR_SEGOVR();
1832 END_OF_INSTR();
1835 /****************************************************************************
1836 REMARKS:
1837 Handles opcode 0x0f,0xba
1838 ****************************************************************************/
1839 static void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1841 int mod, rl, rh;
1842 uint srcoffset;
1843 int bit;
1845 START_OF_INSTR();
1846 FETCH_DECODE_MODRM(mod, rh, rl);
1847 switch (rh) {
1848 case 4:
1849 DECODE_PRINTF("BT\t");
1850 break;
1851 case 5:
1852 DECODE_PRINTF("BTS\t");
1853 break;
1854 case 6:
1855 DECODE_PRINTF("BTR\t");
1856 break;
1857 case 7:
1858 DECODE_PRINTF("BTC\t");
1859 break;
1860 default:
1861 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1862 TRACE_REGS();
1863 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1864 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1865 HALT_SYS();
1867 switch (mod) {
1868 case 0:
1869 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1870 u32 srcval, mask;
1871 u8 shift;
1873 srcoffset = decode_rm00_address(rl);
1874 DECODE_PRINTF(",");
1875 shift = fetch_byte_imm();
1876 TRACE_AND_STEP();
1877 bit = shift & 0x1F;
1878 srcval = fetch_data_long(srcoffset);
1879 mask = (0x1 << bit);
1880 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1881 switch (rh) {
1882 case 5:
1883 store_data_long(srcoffset, srcval | mask);
1884 break;
1885 case 6:
1886 store_data_long(srcoffset, srcval & ~mask);
1887 break;
1888 case 7:
1889 store_data_long(srcoffset, srcval ^ mask);
1890 break;
1891 default:
1892 break;
1894 } else {
1895 u16 srcval, mask;
1896 u8 shift;
1898 srcoffset = decode_rm00_address(rl);
1899 DECODE_PRINTF(",");
1900 shift = fetch_byte_imm();
1901 TRACE_AND_STEP();
1902 bit = shift & 0xF;
1903 srcval = fetch_data_word(srcoffset);
1904 mask = (0x1 << bit);
1905 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1906 switch (rh) {
1907 case 5:
1908 store_data_word(srcoffset, srcval | mask);
1909 break;
1910 case 6:
1911 store_data_word(srcoffset, srcval & ~mask);
1912 break;
1913 case 7:
1914 store_data_word(srcoffset, srcval ^ mask);
1915 break;
1916 default:
1917 break;
1920 break;
1921 case 1:
1922 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1923 u32 srcval, mask;
1924 u8 shift;
1926 srcoffset = decode_rm01_address(rl);
1927 DECODE_PRINTF(",");
1928 shift = fetch_byte_imm();
1929 TRACE_AND_STEP();
1930 bit = shift & 0x1F;
1931 srcval = fetch_data_long(srcoffset);
1932 mask = (0x1 << bit);
1933 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1934 switch (rh) {
1935 case 5:
1936 store_data_long(srcoffset, srcval | mask);
1937 break;
1938 case 6:
1939 store_data_long(srcoffset, srcval & ~mask);
1940 break;
1941 case 7:
1942 store_data_long(srcoffset, srcval ^ mask);
1943 break;
1944 default:
1945 break;
1947 } else {
1948 u16 srcval, mask;
1949 u8 shift;
1951 srcoffset = decode_rm01_address(rl);
1952 DECODE_PRINTF(",");
1953 shift = fetch_byte_imm();
1954 TRACE_AND_STEP();
1955 bit = shift & 0xF;
1956 srcval = fetch_data_word(srcoffset);
1957 mask = (0x1 << bit);
1958 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1959 switch (rh) {
1960 case 5:
1961 store_data_word(srcoffset, srcval | mask);
1962 break;
1963 case 6:
1964 store_data_word(srcoffset, srcval & ~mask);
1965 break;
1966 case 7:
1967 store_data_word(srcoffset, srcval ^ mask);
1968 break;
1969 default:
1970 break;
1973 break;
1974 case 2:
1975 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1976 u32 srcval, mask;
1977 u8 shift;
1979 srcoffset = decode_rm10_address(rl);
1980 DECODE_PRINTF(",");
1981 shift = fetch_byte_imm();
1982 TRACE_AND_STEP();
1983 bit = shift & 0x1F;
1984 srcval = fetch_data_long(srcoffset);
1985 mask = (0x1 << bit);
1986 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1987 switch (rh) {
1988 case 5:
1989 store_data_long(srcoffset, srcval | mask);
1990 break;
1991 case 6:
1992 store_data_long(srcoffset, srcval & ~mask);
1993 break;
1994 case 7:
1995 store_data_long(srcoffset, srcval ^ mask);
1996 break;
1997 default:
1998 break;
2000 } else {
2001 u16 srcval, mask;
2002 u8 shift;
2004 srcoffset = decode_rm10_address(rl);
2005 DECODE_PRINTF(",");
2006 shift = fetch_byte_imm();
2007 TRACE_AND_STEP();
2008 bit = shift & 0xF;
2009 srcval = fetch_data_word(srcoffset);
2010 mask = (0x1 << bit);
2011 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2012 switch (rh) {
2013 case 5:
2014 store_data_word(srcoffset, srcval | mask);
2015 break;
2016 case 6:
2017 store_data_word(srcoffset, srcval & ~mask);
2018 break;
2019 case 7:
2020 store_data_word(srcoffset, srcval ^ mask);
2021 break;
2022 default:
2023 break;
2026 break;
2027 case 3: /* register to register */
2028 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2029 u32 *srcreg;
2030 u32 mask;
2031 u8 shift;
2033 srcreg = DECODE_RM_LONG_REGISTER(rl);
2034 DECODE_PRINTF(",");
2035 shift = fetch_byte_imm();
2036 TRACE_AND_STEP();
2037 bit = shift & 0x1F;
2038 mask = (0x1 << bit);
2039 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2040 switch (rh) {
2041 case 5:
2042 *srcreg |= mask;
2043 break;
2044 case 6:
2045 *srcreg &= ~mask;
2046 break;
2047 case 7:
2048 *srcreg ^= mask;
2049 break;
2050 default:
2051 break;
2053 } else {
2054 u16 *srcreg;
2055 u16 mask;
2056 u8 shift;
2058 srcreg = DECODE_RM_WORD_REGISTER(rl);
2059 DECODE_PRINTF(",");
2060 shift = fetch_byte_imm();
2061 TRACE_AND_STEP();
2062 bit = shift & 0xF;
2063 mask = (0x1 << bit);
2064 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2065 switch (rh) {
2066 case 5:
2067 *srcreg |= mask;
2068 break;
2069 case 6:
2070 *srcreg &= ~mask;
2071 break;
2072 case 7:
2073 *srcreg ^= mask;
2074 break;
2075 default:
2076 break;
2079 break;
2081 DECODE_CLEAR_SEGOVR();
2082 END_OF_INSTR();
2085 /****************************************************************************
2086 REMARKS:
2087 Handles opcode 0x0f,0xbb
2088 ****************************************************************************/
2089 static void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
2091 int mod, rl, rh;
2092 uint srcoffset;
2093 int bit,disp;
2095 START_OF_INSTR();
2096 DECODE_PRINTF("BTC\t");
2097 FETCH_DECODE_MODRM(mod, rh, rl);
2098 switch (mod) {
2099 case 0:
2100 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2101 u32 srcval,mask;
2102 u32 *shiftreg;
2104 srcoffset = decode_rm00_address(rl);
2105 DECODE_PRINTF(",");
2106 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2107 TRACE_AND_STEP();
2108 bit = *shiftreg & 0x1F;
2109 disp = (s16)*shiftreg >> 5;
2110 srcval = fetch_data_long(srcoffset+disp);
2111 mask = (0x1 << bit);
2112 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2113 store_data_long(srcoffset+disp, srcval ^ mask);
2114 } else {
2115 u16 srcval,mask;
2116 u16 *shiftreg;
2118 srcoffset = decode_rm00_address(rl);
2119 DECODE_PRINTF(",");
2120 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2121 TRACE_AND_STEP();
2122 bit = *shiftreg & 0xF;
2123 disp = (s16)*shiftreg >> 4;
2124 srcval = fetch_data_word(srcoffset+disp);
2125 mask = (u16)(0x1 << bit);
2126 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2127 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2129 break;
2130 case 1:
2131 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2132 u32 srcval,mask;
2133 u32 *shiftreg;
2135 srcoffset = decode_rm01_address(rl);
2136 DECODE_PRINTF(",");
2137 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2138 TRACE_AND_STEP();
2139 bit = *shiftreg & 0x1F;
2140 disp = (s16)*shiftreg >> 5;
2141 srcval = fetch_data_long(srcoffset+disp);
2142 mask = (0x1 << bit);
2143 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2144 store_data_long(srcoffset+disp, srcval ^ mask);
2145 } else {
2146 u16 srcval,mask;
2147 u16 *shiftreg;
2149 srcoffset = decode_rm01_address(rl);
2150 DECODE_PRINTF(",");
2151 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2152 TRACE_AND_STEP();
2153 bit = *shiftreg & 0xF;
2154 disp = (s16)*shiftreg >> 4;
2155 srcval = fetch_data_word(srcoffset+disp);
2156 mask = (u16)(0x1 << bit);
2157 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2158 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2160 break;
2161 case 2:
2162 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2163 u32 srcval,mask;
2164 u32 *shiftreg;
2166 srcoffset = decode_rm10_address(rl);
2167 DECODE_PRINTF(",");
2168 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2169 TRACE_AND_STEP();
2170 bit = *shiftreg & 0x1F;
2171 disp = (s16)*shiftreg >> 5;
2172 srcval = fetch_data_long(srcoffset+disp);
2173 mask = (0x1 << bit);
2174 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2175 store_data_long(srcoffset+disp, srcval ^ mask);
2176 } else {
2177 u16 srcval,mask;
2178 u16 *shiftreg;
2180 srcoffset = decode_rm10_address(rl);
2181 DECODE_PRINTF(",");
2182 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2183 TRACE_AND_STEP();
2184 bit = *shiftreg & 0xF;
2185 disp = (s16)*shiftreg >> 4;
2186 srcval = fetch_data_word(srcoffset+disp);
2187 mask = (u16)(0x1 << bit);
2188 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
2189 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
2191 break;
2192 case 3: /* register to register */
2193 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2194 u32 *srcreg,*shiftreg;
2195 u32 mask;
2197 srcreg = DECODE_RM_LONG_REGISTER(rl);
2198 DECODE_PRINTF(",");
2199 shiftreg = DECODE_RM_LONG_REGISTER(rh);
2200 TRACE_AND_STEP();
2201 bit = *shiftreg & 0x1F;
2202 mask = (0x1 << bit);
2203 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2204 *srcreg ^= mask;
2205 } else {
2206 u16 *srcreg,*shiftreg;
2207 u16 mask;
2209 srcreg = DECODE_RM_WORD_REGISTER(rl);
2210 DECODE_PRINTF(",");
2211 shiftreg = DECODE_RM_WORD_REGISTER(rh);
2212 TRACE_AND_STEP();
2213 bit = *shiftreg & 0xF;
2214 mask = (u16)(0x1 << bit);
2215 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
2216 *srcreg ^= mask;
2218 break;
2220 DECODE_CLEAR_SEGOVR();
2221 END_OF_INSTR();
2224 /****************************************************************************
2225 REMARKS:
2226 Handles opcode 0x0f,0xbc
2227 ****************************************************************************/
2228 static void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
2230 int mod, rl, rh;
2231 uint srcoffset;
2233 START_OF_INSTR();
2234 DECODE_PRINTF("BSF\t");
2235 FETCH_DECODE_MODRM(mod, rh, rl);
2236 switch(mod) {
2237 case 0:
2238 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2239 u32 srcval, *dstreg;
2241 srcoffset = decode_rm00_address(rl);
2242 DECODE_PRINTF(",");
2243 dstreg = DECODE_RM_LONG_REGISTER(rh);
2244 TRACE_AND_STEP();
2245 srcval = fetch_data_long(srcoffset);
2246 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2247 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2248 if ((srcval >> *dstreg) & 1) break;
2249 } else {
2250 u16 srcval, *dstreg;
2252 srcoffset = decode_rm00_address(rl);
2253 DECODE_PRINTF(",");
2254 dstreg = DECODE_RM_WORD_REGISTER(rh);
2255 TRACE_AND_STEP();
2256 srcval = fetch_data_word(srcoffset);
2257 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2258 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2259 if ((srcval >> *dstreg) & 1) break;
2261 break;
2262 case 1:
2263 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2264 u32 srcval, *dstreg;
2266 srcoffset = decode_rm01_address(rl);
2267 DECODE_PRINTF(",");
2268 dstreg = DECODE_RM_LONG_REGISTER(rh);
2269 TRACE_AND_STEP();
2270 srcval = fetch_data_long(srcoffset);
2271 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2272 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2273 if ((srcval >> *dstreg) & 1) break;
2274 } else {
2275 u16 srcval, *dstreg;
2277 srcoffset = decode_rm01_address(rl);
2278 DECODE_PRINTF(",");
2279 dstreg = DECODE_RM_WORD_REGISTER(rh);
2280 TRACE_AND_STEP();
2281 srcval = fetch_data_word(srcoffset);
2282 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2283 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2284 if ((srcval >> *dstreg) & 1) break;
2286 break;
2287 case 2:
2288 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2289 u32 srcval, *dstreg;
2291 srcoffset = decode_rm10_address(rl);
2292 DECODE_PRINTF(",");
2293 dstreg = DECODE_RM_LONG_REGISTER(rh);
2294 TRACE_AND_STEP();
2295 srcval = fetch_data_long(srcoffset);
2296 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2297 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2298 if ((srcval >> *dstreg) & 1) break;
2299 } else {
2300 u16 srcval, *dstreg;
2302 srcoffset = decode_rm10_address(rl);
2303 DECODE_PRINTF(",");
2304 dstreg = DECODE_RM_WORD_REGISTER(rh);
2305 TRACE_AND_STEP();
2306 srcval = fetch_data_word(srcoffset);
2307 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2308 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2309 if ((srcval >> *dstreg) & 1) break;
2311 break;
2312 case 3: /* register to register */
2313 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2314 u32 srcval, *dstreg;
2316 srcval = *DECODE_RM_LONG_REGISTER(rl);
2317 DECODE_PRINTF(",");
2318 dstreg = DECODE_RM_LONG_REGISTER(rh);
2319 TRACE_AND_STEP();
2320 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2321 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
2322 if ((srcval >> *dstreg) & 1) break;
2323 } else {
2324 u16 srcval, *dstreg;
2326 srcval = *DECODE_RM_WORD_REGISTER(rl);
2327 DECODE_PRINTF(",");
2328 dstreg = DECODE_RM_WORD_REGISTER(rh);
2329 TRACE_AND_STEP();
2330 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2331 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
2332 if ((srcval >> *dstreg) & 1) break;
2334 break;
2336 DECODE_CLEAR_SEGOVR();
2337 END_OF_INSTR();
2340 /****************************************************************************
2341 REMARKS:
2342 Handles opcode 0x0f,0xbd
2343 ****************************************************************************/
2344 static void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
2346 int mod, rl, rh;
2347 uint srcoffset;
2349 START_OF_INSTR();
2350 DECODE_PRINTF("BSR\t");
2351 FETCH_DECODE_MODRM(mod, rh, rl);
2352 switch(mod) {
2353 case 0:
2354 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2355 u32 srcval, *dstreg;
2357 srcoffset = decode_rm00_address(rl);
2358 DECODE_PRINTF(",");
2359 dstreg = DECODE_RM_LONG_REGISTER(rh);
2360 TRACE_AND_STEP();
2361 srcval = fetch_data_long(srcoffset);
2362 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2363 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2364 if ((srcval >> *dstreg) & 1) break;
2365 } else {
2366 u16 srcval, *dstreg;
2368 srcoffset = decode_rm00_address(rl);
2369 DECODE_PRINTF(",");
2370 dstreg = DECODE_RM_WORD_REGISTER(rh);
2371 TRACE_AND_STEP();
2372 srcval = fetch_data_word(srcoffset);
2373 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2374 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2375 if ((srcval >> *dstreg) & 1) break;
2377 break;
2378 case 1:
2379 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2380 u32 srcval, *dstreg;
2382 srcoffset = decode_rm01_address(rl);
2383 DECODE_PRINTF(",");
2384 dstreg = DECODE_RM_LONG_REGISTER(rh);
2385 TRACE_AND_STEP();
2386 srcval = fetch_data_long(srcoffset);
2387 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2388 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2389 if ((srcval >> *dstreg) & 1) break;
2390 } else {
2391 u16 srcval, *dstreg;
2393 srcoffset = decode_rm01_address(rl);
2394 DECODE_PRINTF(",");
2395 dstreg = DECODE_RM_WORD_REGISTER(rh);
2396 TRACE_AND_STEP();
2397 srcval = fetch_data_word(srcoffset);
2398 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2399 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2400 if ((srcval >> *dstreg) & 1) break;
2402 break;
2403 case 2:
2404 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2405 u32 srcval, *dstreg;
2407 srcoffset = decode_rm10_address(rl);
2408 DECODE_PRINTF(",");
2409 dstreg = DECODE_RM_LONG_REGISTER(rh);
2410 TRACE_AND_STEP();
2411 srcval = fetch_data_long(srcoffset);
2412 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2413 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2414 if ((srcval >> *dstreg) & 1) break;
2415 } else {
2416 u16 srcval, *dstreg;
2418 srcoffset = decode_rm10_address(rl);
2419 DECODE_PRINTF(",");
2420 dstreg = DECODE_RM_WORD_REGISTER(rh);
2421 TRACE_AND_STEP();
2422 srcval = fetch_data_word(srcoffset);
2423 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2424 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2425 if ((srcval >> *dstreg) & 1) break;
2427 break;
2428 case 3: /* register to register */
2429 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2430 u32 srcval, *dstreg;
2432 srcval = *DECODE_RM_LONG_REGISTER(rl);
2433 DECODE_PRINTF(",");
2434 dstreg = DECODE_RM_LONG_REGISTER(rh);
2435 TRACE_AND_STEP();
2436 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2437 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
2438 if ((srcval >> *dstreg) & 1) break;
2439 } else {
2440 u16 srcval, *dstreg;
2442 srcval = *DECODE_RM_WORD_REGISTER(rl);
2443 DECODE_PRINTF(",");
2444 dstreg = DECODE_RM_WORD_REGISTER(rh);
2445 TRACE_AND_STEP();
2446 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2447 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
2448 if ((srcval >> *dstreg) & 1) break;
2450 break;
2452 DECODE_CLEAR_SEGOVR();
2453 END_OF_INSTR();
2456 /****************************************************************************
2457 REMARKS:
2458 Handles opcode 0x0f,0xbe
2459 ****************************************************************************/
2460 static void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
2462 int mod, rl, rh;
2463 uint srcoffset;
2465 START_OF_INSTR();
2466 DECODE_PRINTF("MOVSX\t");
2467 FETCH_DECODE_MODRM(mod, rh, rl);
2468 switch (mod) {
2469 case 0:
2470 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2471 u32 *destreg;
2472 u32 srcval;
2474 destreg = DECODE_RM_LONG_REGISTER(rh);
2475 DECODE_PRINTF(",");
2476 srcoffset = decode_rm00_address(rl);
2477 srcval = (s32)((s8)fetch_data_byte(srcoffset));
2478 DECODE_PRINTF("\n");
2479 TRACE_AND_STEP();
2480 *destreg = srcval;
2481 } else {
2482 u16 *destreg;
2483 u16 srcval;
2485 destreg = DECODE_RM_WORD_REGISTER(rh);
2486 DECODE_PRINTF(",");
2487 srcoffset = decode_rm00_address(rl);
2488 srcval = (s16)((s8)fetch_data_byte(srcoffset));
2489 DECODE_PRINTF("\n");
2490 TRACE_AND_STEP();
2491 *destreg = srcval;
2493 break;
2494 case 1:
2495 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2496 u32 *destreg;
2497 u32 srcval;
2499 destreg = DECODE_RM_LONG_REGISTER(rh);
2500 DECODE_PRINTF(",");
2501 srcoffset = decode_rm01_address(rl);
2502 srcval = (s32)((s8)fetch_data_byte(srcoffset));
2503 DECODE_PRINTF("\n");
2504 TRACE_AND_STEP();
2505 *destreg = srcval;
2506 } else {
2507 u16 *destreg;
2508 u16 srcval;
2510 destreg = DECODE_RM_WORD_REGISTER(rh);
2511 DECODE_PRINTF(",");
2512 srcoffset = decode_rm01_address(rl);
2513 srcval = (s16)((s8)fetch_data_byte(srcoffset));
2514 DECODE_PRINTF("\n");
2515 TRACE_AND_STEP();
2516 *destreg = srcval;
2518 break;
2519 case 2:
2520 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2521 u32 *destreg;
2522 u32 srcval;
2524 destreg = DECODE_RM_LONG_REGISTER(rh);
2525 DECODE_PRINTF(",");
2526 srcoffset = decode_rm10_address(rl);
2527 srcval = (s32)((s8)fetch_data_byte(srcoffset));
2528 DECODE_PRINTF("\n");
2529 TRACE_AND_STEP();
2530 *destreg = srcval;
2531 } else {
2532 u16 *destreg;
2533 u16 srcval;
2535 destreg = DECODE_RM_WORD_REGISTER(rh);
2536 DECODE_PRINTF(",");
2537 srcoffset = decode_rm10_address(rl);
2538 srcval = (s16)((s8)fetch_data_byte(srcoffset));
2539 DECODE_PRINTF("\n");
2540 TRACE_AND_STEP();
2541 *destreg = srcval;
2543 break;
2544 case 3: /* register to register */
2545 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2546 u32 *destreg;
2547 u8 *srcreg;
2549 destreg = DECODE_RM_LONG_REGISTER(rh);
2550 DECODE_PRINTF(",");
2551 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2552 DECODE_PRINTF("\n");
2553 TRACE_AND_STEP();
2554 *destreg = (s32)((s8)*srcreg);
2555 } else {
2556 u16 *destreg;
2557 u8 *srcreg;
2559 destreg = DECODE_RM_WORD_REGISTER(rh);
2560 DECODE_PRINTF(",");
2561 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2562 DECODE_PRINTF("\n");
2563 TRACE_AND_STEP();
2564 *destreg = (s16)((s8)*srcreg);
2566 break;
2568 DECODE_CLEAR_SEGOVR();
2569 END_OF_INSTR();
2572 /****************************************************************************
2573 REMARKS:
2574 Handles opcode 0x0f,0xbf
2575 ****************************************************************************/
2576 static void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
2578 int mod, rl, rh;
2579 uint srcoffset;
2580 u32 *destreg;
2581 u32 srcval;
2582 u16 *srcreg;
2584 START_OF_INSTR();
2585 DECODE_PRINTF("MOVSX\t");
2586 FETCH_DECODE_MODRM(mod, rh, rl);
2587 switch (mod) {
2588 case 0:
2589 destreg = DECODE_RM_LONG_REGISTER(rh);
2590 DECODE_PRINTF(",");
2591 srcoffset = decode_rm00_address(rl);
2592 srcval = (s32)((s16)fetch_data_word(srcoffset));
2593 DECODE_PRINTF("\n");
2594 TRACE_AND_STEP();
2595 *destreg = srcval;
2596 break;
2597 case 1:
2598 destreg = DECODE_RM_LONG_REGISTER(rh);
2599 DECODE_PRINTF(",");
2600 srcoffset = decode_rm01_address(rl);
2601 srcval = (s32)((s16)fetch_data_word(srcoffset));
2602 DECODE_PRINTF("\n");
2603 TRACE_AND_STEP();
2604 *destreg = srcval;
2605 break;
2606 case 2:
2607 destreg = DECODE_RM_LONG_REGISTER(rh);
2608 DECODE_PRINTF(",");
2609 srcoffset = decode_rm10_address(rl);
2610 srcval = (s32)((s16)fetch_data_word(srcoffset));
2611 DECODE_PRINTF("\n");
2612 TRACE_AND_STEP();
2613 *destreg = srcval;
2614 break;
2615 case 3: /* register to register */
2616 destreg = DECODE_RM_LONG_REGISTER(rh);
2617 DECODE_PRINTF(",");
2618 srcreg = DECODE_RM_WORD_REGISTER(rl);
2619 DECODE_PRINTF("\n");
2620 TRACE_AND_STEP();
2621 *destreg = (s32)((s16)*srcreg);
2622 break;
2624 DECODE_CLEAR_SEGOVR();
2625 END_OF_INSTR();
2628 /* Handles opcodes 0xc8-0xcf */
2629 static void x86emuOp2_bswap(u8 X86EMU_UNUSED(op2))
2631 START_OF_INSTR();
2632 DECODE_PRINTF("BSWAP\n");
2633 TRACE_AND_STEP();
2635 switch (op2) {
2636 case 0xc8:
2637 M.x86.R_EAX = bswap_32(M.x86.R_EAX);
2638 break;
2639 case 0xc9:
2640 M.x86.R_ECX = bswap_32(M.x86.R_ECX);
2641 break;
2642 case 0xca:
2643 M.x86.R_EDX = bswap_32(M.x86.R_EDX);
2644 break;
2645 case 0xcb:
2646 M.x86.R_EBX = bswap_32(M.x86.R_EBX);
2647 break;
2648 case 0xcc:
2649 M.x86.R_ESP = bswap_32(M.x86.R_ESP);
2650 break;
2651 case 0xcd:
2652 M.x86.R_EBP = bswap_32(M.x86.R_EBP);
2653 break;
2654 case 0xce:
2655 M.x86.R_ESI = bswap_32(M.x86.R_ESI);
2656 break;
2657 case 0xcf:
2658 M.x86.R_EDI = bswap_32(M.x86.R_EDI);
2659 break;
2660 default:
2661 /* can't happen */
2662 break;
2665 DECODE_CLEAR_SEGOVR();
2666 END_OF_INSTR();
2669 /***************************************************************************
2670 * Double byte operation code table:
2671 **************************************************************************/
2672 void (*x86emu_optab2[256])(u8) =
2674 /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
2675 /* 0x01 */ x86emuOp2_group_g, /* Group G (ring 0 PM) */
2676 /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
2677 /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
2678 /* 0x04 */ x86emuOp2_illegal_op,
2679 /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
2680 /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
2681 /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
2682 /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */
2683 /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */
2684 /* 0x0a */ x86emuOp2_illegal_op,
2685 /* 0x0b */ x86emuOp2_illegal_op,
2686 /* 0x0c */ x86emuOp2_illegal_op,
2687 /* 0x0d */ x86emuOp2_illegal_op,
2688 /* 0x0e */ x86emuOp2_illegal_op,
2689 /* 0x0f */ x86emuOp2_illegal_op,
2691 /* 0x10 */ x86emuOp2_illegal_op,
2692 /* 0x11 */ x86emuOp2_illegal_op,
2693 /* 0x12 */ x86emuOp2_illegal_op,
2694 /* 0x13 */ x86emuOp2_illegal_op,
2695 /* 0x14 */ x86emuOp2_illegal_op,
2696 /* 0x15 */ x86emuOp2_illegal_op,
2697 /* 0x16 */ x86emuOp2_illegal_op,
2698 /* 0x17 */ x86emuOp2_illegal_op,
2699 /* 0x18 */ x86emuOp2_illegal_op,
2700 /* 0x19 */ x86emuOp2_illegal_op,
2701 /* 0x1a */ x86emuOp2_illegal_op,
2702 /* 0x1b */ x86emuOp2_illegal_op,
2703 /* 0x1c */ x86emuOp2_illegal_op,
2704 /* 0x1d */ x86emuOp2_illegal_op,
2705 /* 0x1e */ x86emuOp2_illegal_op,
2706 /* 0x1f */ x86emuOp2_illegal_op,
2708 /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
2709 /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
2710 /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
2711 /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
2712 /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
2713 /* 0x25 */ x86emuOp2_illegal_op,
2714 /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
2715 /* 0x27 */ x86emuOp2_illegal_op,
2716 /* 0x28 */ x86emuOp2_illegal_op,
2717 /* 0x29 */ x86emuOp2_illegal_op,
2718 /* 0x2a */ x86emuOp2_illegal_op,
2719 /* 0x2b */ x86emuOp2_illegal_op,
2720 /* 0x2c */ x86emuOp2_illegal_op,
2721 /* 0x2d */ x86emuOp2_illegal_op,
2722 /* 0x2e */ x86emuOp2_illegal_op,
2723 /* 0x2f */ x86emuOp2_illegal_op,
2725 /* 0x30 */ x86emuOp2_illegal_op,
2726 /* 0x31 */ x86emuOp2_rdtsc,
2727 /* 0x32 */ x86emuOp2_illegal_op,
2728 /* 0x33 */ x86emuOp2_illegal_op,
2729 /* 0x34 */ x86emuOp2_illegal_op,
2730 /* 0x35 */ x86emuOp2_illegal_op,
2731 /* 0x36 */ x86emuOp2_illegal_op,
2732 /* 0x37 */ x86emuOp2_illegal_op,
2733 /* 0x38 */ x86emuOp2_illegal_op,
2734 /* 0x39 */ x86emuOp2_illegal_op,
2735 /* 0x3a */ x86emuOp2_illegal_op,
2736 /* 0x3b */ x86emuOp2_illegal_op,
2737 /* 0x3c */ x86emuOp2_illegal_op,
2738 /* 0x3d */ x86emuOp2_illegal_op,
2739 /* 0x3e */ x86emuOp2_illegal_op,
2740 /* 0x3f */ x86emuOp2_illegal_op,
2742 /* 0x40 */ x86emuOp2_illegal_op,
2743 /* 0x41 */ x86emuOp2_illegal_op,
2744 /* 0x42 */ x86emuOp2_illegal_op,
2745 /* 0x43 */ x86emuOp2_illegal_op,
2746 /* 0x44 */ x86emuOp2_illegal_op,
2747 /* 0x45 */ x86emuOp2_illegal_op,
2748 /* 0x46 */ x86emuOp2_illegal_op,
2749 /* 0x47 */ x86emuOp2_illegal_op,
2750 /* 0x48 */ x86emuOp2_illegal_op,
2751 /* 0x49 */ x86emuOp2_illegal_op,
2752 /* 0x4a */ x86emuOp2_illegal_op,
2753 /* 0x4b */ x86emuOp2_illegal_op,
2754 /* 0x4c */ x86emuOp2_illegal_op,
2755 /* 0x4d */ x86emuOp2_illegal_op,
2756 /* 0x4e */ x86emuOp2_illegal_op,
2757 /* 0x4f */ x86emuOp2_illegal_op,
2759 /* 0x50 */ x86emuOp2_illegal_op,
2760 /* 0x51 */ x86emuOp2_illegal_op,
2761 /* 0x52 */ x86emuOp2_illegal_op,
2762 /* 0x53 */ x86emuOp2_illegal_op,
2763 /* 0x54 */ x86emuOp2_illegal_op,
2764 /* 0x55 */ x86emuOp2_illegal_op,
2765 /* 0x56 */ x86emuOp2_illegal_op,
2766 /* 0x57 */ x86emuOp2_illegal_op,
2767 /* 0x58 */ x86emuOp2_illegal_op,
2768 /* 0x59 */ x86emuOp2_illegal_op,
2769 /* 0x5a */ x86emuOp2_illegal_op,
2770 /* 0x5b */ x86emuOp2_illegal_op,
2771 /* 0x5c */ x86emuOp2_illegal_op,
2772 /* 0x5d */ x86emuOp2_illegal_op,
2773 /* 0x5e */ x86emuOp2_illegal_op,
2774 /* 0x5f */ x86emuOp2_illegal_op,
2776 /* 0x60 */ x86emuOp2_illegal_op,
2777 /* 0x61 */ x86emuOp2_illegal_op,
2778 /* 0x62 */ x86emuOp2_illegal_op,
2779 /* 0x63 */ x86emuOp2_illegal_op,
2780 /* 0x64 */ x86emuOp2_illegal_op,
2781 /* 0x65 */ x86emuOp2_illegal_op,
2782 /* 0x66 */ x86emuOp2_illegal_op,
2783 /* 0x67 */ x86emuOp2_illegal_op,
2784 /* 0x68 */ x86emuOp2_illegal_op,
2785 /* 0x69 */ x86emuOp2_illegal_op,
2786 /* 0x6a */ x86emuOp2_illegal_op,
2787 /* 0x6b */ x86emuOp2_illegal_op,
2788 /* 0x6c */ x86emuOp2_illegal_op,
2789 /* 0x6d */ x86emuOp2_illegal_op,
2790 /* 0x6e */ x86emuOp2_illegal_op,
2791 /* 0x6f */ x86emuOp2_illegal_op,
2793 /* 0x70 */ x86emuOp2_illegal_op,
2794 /* 0x71 */ x86emuOp2_illegal_op,
2795 /* 0x72 */ x86emuOp2_illegal_op,
2796 /* 0x73 */ x86emuOp2_illegal_op,
2797 /* 0x74 */ x86emuOp2_illegal_op,
2798 /* 0x75 */ x86emuOp2_illegal_op,
2799 /* 0x76 */ x86emuOp2_illegal_op,
2800 /* 0x77 */ x86emuOp2_illegal_op,
2801 /* 0x78 */ x86emuOp2_illegal_op,
2802 /* 0x79 */ x86emuOp2_illegal_op,
2803 /* 0x7a */ x86emuOp2_illegal_op,
2804 /* 0x7b */ x86emuOp2_illegal_op,
2805 /* 0x7c */ x86emuOp2_illegal_op,
2806 /* 0x7d */ x86emuOp2_illegal_op,
2807 /* 0x7e */ x86emuOp2_illegal_op,
2808 /* 0x7f */ x86emuOp2_illegal_op,
2810 /* 0x80 */ x86emuOp2_long_jump,
2811 /* 0x81 */ x86emuOp2_long_jump,
2812 /* 0x82 */ x86emuOp2_long_jump,
2813 /* 0x83 */ x86emuOp2_long_jump,
2814 /* 0x84 */ x86emuOp2_long_jump,
2815 /* 0x85 */ x86emuOp2_long_jump,
2816 /* 0x86 */ x86emuOp2_long_jump,
2817 /* 0x87 */ x86emuOp2_long_jump,
2818 /* 0x88 */ x86emuOp2_long_jump,
2819 /* 0x89 */ x86emuOp2_long_jump,
2820 /* 0x8a */ x86emuOp2_long_jump,
2821 /* 0x8b */ x86emuOp2_long_jump,
2822 /* 0x8c */ x86emuOp2_long_jump,
2823 /* 0x8d */ x86emuOp2_long_jump,
2824 /* 0x8e */ x86emuOp2_long_jump,
2825 /* 0x8f */ x86emuOp2_long_jump,
2827 /* 0x90 */ x86emuOp2_set_byte,
2828 /* 0x91 */ x86emuOp2_set_byte,
2829 /* 0x92 */ x86emuOp2_set_byte,
2830 /* 0x93 */ x86emuOp2_set_byte,
2831 /* 0x94 */ x86emuOp2_set_byte,
2832 /* 0x95 */ x86emuOp2_set_byte,
2833 /* 0x96 */ x86emuOp2_set_byte,
2834 /* 0x97 */ x86emuOp2_set_byte,
2835 /* 0x98 */ x86emuOp2_set_byte,
2836 /* 0x99 */ x86emuOp2_set_byte,
2837 /* 0x9a */ x86emuOp2_set_byte,
2838 /* 0x9b */ x86emuOp2_set_byte,
2839 /* 0x9c */ x86emuOp2_set_byte,
2840 /* 0x9d */ x86emuOp2_set_byte,
2841 /* 0x9e */ x86emuOp2_set_byte,
2842 /* 0x9f */ x86emuOp2_set_byte,
2844 /* 0xa0 */ x86emuOp2_push_FS,
2845 /* 0xa1 */ x86emuOp2_pop_FS,
2846 /* 0xa2 */ x86emuOp2_cpuid,
2847 /* 0xa3 */ x86emuOp2_bt_R,
2848 /* 0xa4 */ x86emuOp2_shld_IMM,
2849 /* 0xa5 */ x86emuOp2_shld_CL,
2850 /* 0xa6 */ x86emuOp2_illegal_op,
2851 /* 0xa7 */ x86emuOp2_illegal_op,
2852 /* 0xa8 */ x86emuOp2_push_GS,
2853 /* 0xa9 */ x86emuOp2_pop_GS,
2854 /* 0xaa */ x86emuOp2_illegal_op,
2855 /* 0xab */ x86emuOp2_bts_R,
2856 /* 0xac */ x86emuOp2_shrd_IMM,
2857 /* 0xad */ x86emuOp2_shrd_CL,
2858 /* 0xae */ x86emuOp2_illegal_op,
2859 /* 0xaf */ x86emuOp2_imul_R_RM,
2861 /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
2862 /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
2863 /* 0xb2 */ x86emuOp2_lss_R_IMM,
2864 /* 0xb3 */ x86emuOp2_btr_R,
2865 /* 0xb4 */ x86emuOp2_lfs_R_IMM,
2866 /* 0xb5 */ x86emuOp2_lgs_R_IMM,
2867 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
2868 /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
2869 /* 0xb8 */ x86emuOp2_illegal_op,
2870 /* 0xb9 */ x86emuOp2_illegal_op,
2871 /* 0xba */ x86emuOp2_btX_I,
2872 /* 0xbb */ x86emuOp2_btc_R,
2873 /* 0xbc */ x86emuOp2_bsf,
2874 /* 0xbd */ x86emuOp2_bsr,
2875 /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
2876 /* 0xbf */ x86emuOp2_movsx_word_R_RM,
2878 /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
2879 /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
2880 /* 0xc2 */ x86emuOp2_illegal_op,
2881 /* 0xc3 */ x86emuOp2_illegal_op,
2882 /* 0xc4 */ x86emuOp2_illegal_op,
2883 /* 0xc5 */ x86emuOp2_illegal_op,
2884 /* 0xc6 */ x86emuOp2_illegal_op,
2885 /* 0xc7 */ x86emuOp2_illegal_op,
2886 /* 0xc8 */ x86emuOp2_bswap,
2887 /* 0xc9 */ x86emuOp2_bswap,
2888 /* 0xca */ x86emuOp2_bswap,
2889 /* 0xcb */ x86emuOp2_bswap,
2890 /* 0xcc */ x86emuOp2_bswap,
2891 /* 0xcd */ x86emuOp2_bswap,
2892 /* 0xce */ x86emuOp2_bswap,
2893 /* 0xcf */ x86emuOp2_bswap,
2895 /* 0xd0 */ x86emuOp2_illegal_op,
2896 /* 0xd1 */ x86emuOp2_illegal_op,
2897 /* 0xd2 */ x86emuOp2_illegal_op,
2898 /* 0xd3 */ x86emuOp2_illegal_op,
2899 /* 0xd4 */ x86emuOp2_illegal_op,
2900 /* 0xd5 */ x86emuOp2_illegal_op,
2901 /* 0xd6 */ x86emuOp2_illegal_op,
2902 /* 0xd7 */ x86emuOp2_illegal_op,
2903 /* 0xd8 */ x86emuOp2_illegal_op,
2904 /* 0xd9 */ x86emuOp2_illegal_op,
2905 /* 0xda */ x86emuOp2_illegal_op,
2906 /* 0xdb */ x86emuOp2_illegal_op,
2907 /* 0xdc */ x86emuOp2_illegal_op,
2908 /* 0xdd */ x86emuOp2_illegal_op,
2909 /* 0xde */ x86emuOp2_illegal_op,
2910 /* 0xdf */ x86emuOp2_illegal_op,
2912 /* 0xe0 */ x86emuOp2_illegal_op,
2913 /* 0xe1 */ x86emuOp2_illegal_op,
2914 /* 0xe2 */ x86emuOp2_illegal_op,
2915 /* 0xe3 */ x86emuOp2_illegal_op,
2916 /* 0xe4 */ x86emuOp2_illegal_op,
2917 /* 0xe5 */ x86emuOp2_illegal_op,
2918 /* 0xe6 */ x86emuOp2_illegal_op,
2919 /* 0xe7 */ x86emuOp2_illegal_op,
2920 /* 0xe8 */ x86emuOp2_illegal_op,
2921 /* 0xe9 */ x86emuOp2_illegal_op,
2922 /* 0xea */ x86emuOp2_illegal_op,
2923 /* 0xeb */ x86emuOp2_illegal_op,
2924 /* 0xec */ x86emuOp2_illegal_op,
2925 /* 0xed */ x86emuOp2_illegal_op,
2926 /* 0xee */ x86emuOp2_illegal_op,
2927 /* 0xef */ x86emuOp2_illegal_op,
2929 /* 0xf0 */ x86emuOp2_illegal_op,
2930 /* 0xf1 */ x86emuOp2_illegal_op,
2931 /* 0xf2 */ x86emuOp2_illegal_op,
2932 /* 0xf3 */ x86emuOp2_illegal_op,
2933 /* 0xf4 */ x86emuOp2_illegal_op,
2934 /* 0xf5 */ x86emuOp2_illegal_op,
2935 /* 0xf6 */ x86emuOp2_illegal_op,
2936 /* 0xf7 */ x86emuOp2_illegal_op,
2937 /* 0xf8 */ x86emuOp2_illegal_op,
2938 /* 0xf9 */ x86emuOp2_illegal_op,
2939 /* 0xfa */ x86emuOp2_illegal_op,
2940 /* 0xfb */ x86emuOp2_illegal_op,
2941 /* 0xfc */ x86emuOp2_illegal_op,
2942 /* 0xfd */ x86emuOp2_illegal_op,
2943 /* 0xfe */ x86emuOp2_illegal_op,
2944 /* 0xff */ x86emuOp2_illegal_op,