Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / x86emu / ops2.c
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 /****************************************************************************
52 PARAMETERS:
53 op1 - Instruction op code
54
55 REMARKS:
56 Handles illegal opcodes.
57 ****************************************************************************/
58 static void
59 x86emuOp2_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 /****************************************************************************
73 REMARKS:
74 Handles opcode 0x0f,0x31
75 ****************************************************************************/
76 static void
77 x86emuOp2_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 /****************************************************************************
108 REMARKS:
109 Handles opcode 0x0f,0x80-0x8F
110 ****************************************************************************/
111 static void
112 x86emuOp2_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 /****************************************************************************
201 REMARKS:
202 Handles opcode 0x0f,0x90-0x9F
203 ****************************************************************************/
204 static void
205 x86emuOp2_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 /****************************************************************************
312 REMARKS:
313 Handles opcode 0x0f,0xa0
314 ****************************************************************************/
315 static void
316 x86emuOp2_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 /****************************************************************************
327 REMARKS:
328 Handles opcode 0x0f,0xa1
329 ****************************************************************************/
330 static void
331 x86emuOp2_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 /****************************************************************************
342 REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
343 Handles opcode 0x0f,0xa2
344 ****************************************************************************/
345 static void
346 x86emuOp2_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 /****************************************************************************
357 REMARKS:
358 Handles opcode 0x0f,0xa3
359 ****************************************************************************/
360 static void
361 x86emuOp2_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 /****************************************************************************
483 REMARKS:
484 Handles opcode 0x0f,0xa4
485 ****************************************************************************/
486 static void
487 x86emuOp2_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 /****************************************************************************
625 REMARKS:
626 Handles opcode 0x0f,0xa5
627 ****************************************************************************/
628 static void
629 x86emuOp2_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 /****************************************************************************
750 REMARKS:
751 Handles opcode 0x0f,0xa8
752 ****************************************************************************/
753 static void
754 x86emuOp2_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 /****************************************************************************
765 REMARKS:
766 Handles opcode 0x0f,0xa9
767 ****************************************************************************/
768 static void
769 x86emuOp2_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 /****************************************************************************
780 REMARKS:
781 Handles opcode 0x0f,0xab
782 ****************************************************************************/
783 static void
784 x86emuOp2_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 /****************************************************************************
924 REMARKS:
925 Handles opcode 0x0f,0xac
926 ****************************************************************************/
927 static void
928 x86emuOp2_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 /****************************************************************************
1066 REMARKS:
1067 Handles opcode 0x0f,0xad
1068 ****************************************************************************/
1069 static void
1070 x86emuOp2_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 /****************************************************************************
1191 REMARKS:
1192 Handles opcode 0x0f,0xaf
1193 ****************************************************************************/
1194 static void
1195 x86emuOp2_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 /****************************************************************************
1381 REMARKS:
1382 Handles opcode 0x0f,0xb2
1383 ****************************************************************************/
1384 static void
1385 x86emuOp2_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 /****************************************************************************
1431 REMARKS:
1432 Handles opcode 0x0f,0xb3
1433 ****************************************************************************/
1434 static void
1435 x86emuOp2_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 /****************************************************************************
1575 REMARKS:
1576 Handles opcode 0x0f,0xb4
1577 ****************************************************************************/
1578 static void
1579 x86emuOp2_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 /****************************************************************************
1625 REMARKS:
1626 Handles opcode 0x0f,0xb5
1627 ****************************************************************************/
1628 static void
1629 x86emuOp2_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 /****************************************************************************
1675 REMARKS:
1676 Handles opcode 0x0f,0xb6
1677 ****************************************************************************/
1678 static void
1679 x86emuOp2_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 /****************************************************************************
1796 REMARKS:
1797 Handles opcode 0x0f,0xb7
1798 ****************************************************************************/
1799 static void
1800 x86emuOp2_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 /****************************************************************************
1853 REMARKS:
1854 Handles opcode 0x0f,0xba
1855 ****************************************************************************/
1856 static void
1857 x86emuOp2_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 /****************************************************************************
2108 REMARKS:
2109 Handles opcode 0x0f,0xbb
2110 ****************************************************************************/
2111 static void
2112 x86emuOp2_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 /****************************************************************************
2252 REMARKS:
2253 Handles opcode 0x0f,0xbc
2254 ****************************************************************************/
2255 static void
2256 x86emuOp2_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 /****************************************************************************
2381 REMARKS:
2382 Handles opcode 0x0f,0xbd
2383 ****************************************************************************/
2384 static void
2385 x86emuOp2_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 /****************************************************************************
2510 REMARKS:
2511 Handles opcode 0x0f,0xbe
2512 ****************************************************************************/
2513 static void
2514 x86emuOp2_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 /****************************************************************************
2631 REMARKS:
2632 Handles opcode 0x0f,0xbf
2633 ****************************************************************************/
2634 static void
2635 x86emuOp2_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 */
2688 static void
2689 x86emuOp2_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 **************************************************************************/
2732 void (*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 };