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