1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <common.h>
45#include <linux/compiler.h>
46#include "x86emu/x86emui.h"
47
48
49
50
51
52
53
54
55
56
57void x86emuOp2_illegal_op(
58 u8 op2)
59{
60 START_OF_INSTR();
61 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
62 TRACE_REGS();
63 printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
64 M.x86.R_CS, M.x86.R_IP-2,op2);
65 HALT_SYS();
66 END_OF_INSTR();
67}
68
69#define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
70
71
72
73
74
75int x86emu_check_jump_condition(u8 op)
76{
77 switch (op) {
78 case 0x0:
79 DECODE_PRINTF("JO\t");
80 return ACCESS_FLAG(F_OF);
81 case 0x1:
82 DECODE_PRINTF("JNO\t");
83 return !ACCESS_FLAG(F_OF);
84 break;
85 case 0x2:
86 DECODE_PRINTF("JB\t");
87 return ACCESS_FLAG(F_CF);
88 break;
89 case 0x3:
90 DECODE_PRINTF("JNB\t");
91 return !ACCESS_FLAG(F_CF);
92 break;
93 case 0x4:
94 DECODE_PRINTF("JZ\t");
95 return ACCESS_FLAG(F_ZF);
96 break;
97 case 0x5:
98 DECODE_PRINTF("JNZ\t");
99 return !ACCESS_FLAG(F_ZF);
100 break;
101 case 0x6:
102 DECODE_PRINTF("JBE\t");
103 return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
104 break;
105 case 0x7:
106 DECODE_PRINTF("JNBE\t");
107 return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
108 break;
109 case 0x8:
110 DECODE_PRINTF("JS\t");
111 return ACCESS_FLAG(F_SF);
112 break;
113 case 0x9:
114 DECODE_PRINTF("JNS\t");
115 return !ACCESS_FLAG(F_SF);
116 break;
117 case 0xa:
118 DECODE_PRINTF("JP\t");
119 return ACCESS_FLAG(F_PF);
120 break;
121 case 0xb:
122 DECODE_PRINTF("JNP\t");
123 return !ACCESS_FLAG(F_PF);
124 break;
125 case 0xc:
126 DECODE_PRINTF("JL\t");
127 return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
128 break;
129 case 0xd:
130 DECODE_PRINTF("JNL\t");
131 return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
132 break;
133 case 0xe:
134 DECODE_PRINTF("JLE\t");
135 return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
136 ACCESS_FLAG(F_ZF));
137 break;
138 default:
139 DECODE_PRINTF("JNLE\t");
140 return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
141 ACCESS_FLAG(F_ZF));
142 }
143}
144
145void x86emuOp2_long_jump(u8 op2)
146{
147 s32 target;
148 int cond;
149
150
151 START_OF_INSTR();
152 cond = x86emu_check_jump_condition(op2 & 0xF);
153 target = (s16) fetch_word_imm();
154 target += (s16) M.x86.R_IP;
155 DECODE_PRINTF2("%04x\n", target);
156 TRACE_AND_STEP();
157 if (cond)
158 M.x86.R_IP = (u16)target;
159 DECODE_CLEAR_SEGOVR();
160 END_OF_INSTR();
161}
162
163
164
165
166
167void x86emuOp2_set_byte(u8 op2)
168{
169 int mod, rl, rh;
170 uint destoffset;
171 u8 *destreg;
172 __maybe_unused char *name = 0;
173 int cond = 0;
174
175 START_OF_INSTR();
176 switch (op2) {
177 case 0x90:
178 name = "SETO\t";
179 cond = ACCESS_FLAG(F_OF);
180 break;
181 case 0x91:
182 name = "SETNO\t";
183 cond = !ACCESS_FLAG(F_OF);
184 break;
185 case 0x92:
186 name = "SETB\t";
187 cond = ACCESS_FLAG(F_CF);
188 break;
189 case 0x93:
190 name = "SETNB\t";
191 cond = !ACCESS_FLAG(F_CF);
192 break;
193 case 0x94:
194 name = "SETZ\t";
195 cond = ACCESS_FLAG(F_ZF);
196 break;
197 case 0x95:
198 name = "SETNZ\t";
199 cond = !ACCESS_FLAG(F_ZF);
200 break;
201 case 0x96:
202 name = "SETBE\t";
203 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
204 break;
205 case 0x97:
206 name = "SETNBE\t";
207 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
208 break;
209 case 0x98:
210 name = "SETS\t";
211 cond = ACCESS_FLAG(F_SF);
212 break;
213 case 0x99:
214 name = "SETNS\t";
215 cond = !ACCESS_FLAG(F_SF);
216 break;
217 case 0x9a:
218 name = "SETP\t";
219 cond = ACCESS_FLAG(F_PF);
220 break;
221 case 0x9b:
222 name = "SETNP\t";
223 cond = !ACCESS_FLAG(F_PF);
224 break;
225 case 0x9c:
226 name = "SETL\t";
227 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
228 break;
229 case 0x9d:
230 name = "SETNL\t";
231 cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
232 break;
233 case 0x9e:
234 name = "SETLE\t";
235 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
236 ACCESS_FLAG(F_ZF));
237 break;
238 case 0x9f:
239 name = "SETNLE\t";
240 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
241 ACCESS_FLAG(F_ZF));
242 break;
243 }
244 DECODE_PRINTF(name);
245 FETCH_DECODE_MODRM(mod, rh, rl);
246 if (mod < 3) {
247 destoffset = decode_rmXX_address(mod, rl);
248 TRACE_AND_STEP();
249 store_data_byte(destoffset, cond ? 0x01 : 0x00);
250 } else {
251 destreg = DECODE_RM_BYTE_REGISTER(rl);
252 TRACE_AND_STEP();
253 *destreg = cond ? 0x01 : 0x00;
254 }
255 DECODE_CLEAR_SEGOVR();
256 END_OF_INSTR();
257}
258
259
260
261
262
263void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
264{
265 START_OF_INSTR();
266 DECODE_PRINTF("PUSH\tFS\n");
267 TRACE_AND_STEP();
268 push_word(M.x86.R_FS);
269 DECODE_CLEAR_SEGOVR();
270 END_OF_INSTR();
271}
272
273
274
275
276
277void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
278{
279 START_OF_INSTR();
280 DECODE_PRINTF("POP\tFS\n");
281 TRACE_AND_STEP();
282 M.x86.R_FS = pop_word();
283 DECODE_CLEAR_SEGOVR();
284 END_OF_INSTR();
285}
286
287
288
289
290
291void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
292{
293 int mod, rl, rh;
294 uint srcoffset;
295 int bit,disp;
296
297 START_OF_INSTR();
298 DECODE_PRINTF("BT\t");
299 FETCH_DECODE_MODRM(mod, rh, rl);
300 if (mod < 3) {
301 srcoffset = decode_rmXX_address(mod, rl);
302 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
303 u32 srcval;
304 u32 *shiftreg;
305
306 DECODE_PRINTF(",");
307 shiftreg = DECODE_RM_LONG_REGISTER(rh);
308 TRACE_AND_STEP();
309 bit = *shiftreg & 0x1F;
310 disp = (s16)*shiftreg >> 5;
311 srcval = fetch_data_long(srcoffset+disp);
312 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
313 } else {
314 u16 srcval;
315 u16 *shiftreg;
316
317 DECODE_PRINTF(",");
318 shiftreg = DECODE_RM_WORD_REGISTER(rh);
319 TRACE_AND_STEP();
320 bit = *shiftreg & 0xF;
321 disp = (s16)*shiftreg >> 4;
322 srcval = fetch_data_word(srcoffset+disp);
323 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
324 }
325 } else {
326 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
327 u32 *srcreg,*shiftreg;
328
329 srcreg = DECODE_RM_LONG_REGISTER(rl);
330 DECODE_PRINTF(",");
331 shiftreg = DECODE_RM_LONG_REGISTER(rh);
332 TRACE_AND_STEP();
333 bit = *shiftreg & 0x1F;
334 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
335 } else {
336 u16 *srcreg,*shiftreg;
337
338 srcreg = DECODE_RM_WORD_REGISTER(rl);
339 DECODE_PRINTF(",");
340 shiftreg = DECODE_RM_WORD_REGISTER(rh);
341 TRACE_AND_STEP();
342 bit = *shiftreg & 0xF;
343 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
344 }
345 }
346 DECODE_CLEAR_SEGOVR();
347 END_OF_INSTR();
348}
349
350
351
352
353
354void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
355{
356 int mod, rl, rh;
357 uint destoffset;
358 u8 shift;
359
360 START_OF_INSTR();
361 DECODE_PRINTF("SHLD\t");
362 FETCH_DECODE_MODRM(mod, rh, rl);
363 if (mod < 3) {
364 destoffset = decode_rmXX_address(mod, rl);
365 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
366 u32 destval;
367 u32 *shiftreg;
368
369 DECODE_PRINTF(",");
370 shiftreg = DECODE_RM_LONG_REGISTER(rh);
371 DECODE_PRINTF(",");
372 shift = fetch_byte_imm();
373 DECODE_PRINTF2("%d\n", shift);
374 TRACE_AND_STEP();
375 destval = fetch_data_long(destoffset);
376 destval = shld_long(destval,*shiftreg,shift);
377 store_data_long(destoffset, destval);
378 } else {
379 u16 destval;
380 u16 *shiftreg;
381
382 DECODE_PRINTF(",");
383 shiftreg = DECODE_RM_WORD_REGISTER(rh);
384 DECODE_PRINTF(",");
385 shift = fetch_byte_imm();
386 DECODE_PRINTF2("%d\n", shift);
387 TRACE_AND_STEP();
388 destval = fetch_data_word(destoffset);
389 destval = shld_word(destval,*shiftreg,shift);
390 store_data_word(destoffset, destval);
391 }
392 } else {
393 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
394 u32 *destreg,*shiftreg;
395
396 destreg = DECODE_RM_LONG_REGISTER(rl);
397 DECODE_PRINTF(",");
398 shiftreg = DECODE_RM_LONG_REGISTER(rh);
399 DECODE_PRINTF(",");
400 shift = fetch_byte_imm();
401 DECODE_PRINTF2("%d\n", shift);
402 TRACE_AND_STEP();
403 *destreg = shld_long(*destreg,*shiftreg,shift);
404 } else {
405 u16 *destreg,*shiftreg;
406
407 destreg = DECODE_RM_WORD_REGISTER(rl);
408 DECODE_PRINTF(",");
409 shiftreg = DECODE_RM_WORD_REGISTER(rh);
410 DECODE_PRINTF(",");
411 shift = fetch_byte_imm();
412 DECODE_PRINTF2("%d\n", shift);
413 TRACE_AND_STEP();
414 *destreg = shld_word(*destreg,*shiftreg,shift);
415 }
416 }
417 DECODE_CLEAR_SEGOVR();
418 END_OF_INSTR();
419}
420
421
422
423
424
425void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
426{
427 int mod, rl, rh;
428 uint destoffset;
429
430 START_OF_INSTR();
431 DECODE_PRINTF("SHLD\t");
432 FETCH_DECODE_MODRM(mod, rh, rl);
433 if (mod < 3) {
434 destoffset = decode_rmXX_address(mod, rl);
435 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
436 u32 destval;
437 u32 *shiftreg;
438
439 DECODE_PRINTF(",");
440 shiftreg = DECODE_RM_LONG_REGISTER(rh);
441 DECODE_PRINTF(",CL\n");
442 TRACE_AND_STEP();
443 destval = fetch_data_long(destoffset);
444 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
445 store_data_long(destoffset, destval);
446 } else {
447 u16 destval;
448 u16 *shiftreg;
449
450 DECODE_PRINTF(",");
451 shiftreg = DECODE_RM_WORD_REGISTER(rh);
452 DECODE_PRINTF(",CL\n");
453 TRACE_AND_STEP();
454 destval = fetch_data_word(destoffset);
455 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
456 store_data_word(destoffset, destval);
457 }
458 } else {
459 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
460 u32 *destreg,*shiftreg;
461
462 destreg = DECODE_RM_LONG_REGISTER(rl);
463 DECODE_PRINTF(",");
464 shiftreg = DECODE_RM_LONG_REGISTER(rh);
465 DECODE_PRINTF(",CL\n");
466 TRACE_AND_STEP();
467 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
468 } else {
469 u16 *destreg,*shiftreg;
470
471 destreg = DECODE_RM_WORD_REGISTER(rl);
472 DECODE_PRINTF(",");
473 shiftreg = DECODE_RM_WORD_REGISTER(rh);
474 DECODE_PRINTF(",CL\n");
475 TRACE_AND_STEP();
476 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
477 }
478 }
479 DECODE_CLEAR_SEGOVR();
480 END_OF_INSTR();
481}
482
483
484
485
486
487void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
488{
489 START_OF_INSTR();
490 DECODE_PRINTF("PUSH\tGS\n");
491 TRACE_AND_STEP();
492 push_word(M.x86.R_GS);
493 DECODE_CLEAR_SEGOVR();
494 END_OF_INSTR();
495}
496
497
498
499
500
501void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
502{
503 START_OF_INSTR();
504 DECODE_PRINTF("POP\tGS\n");
505 TRACE_AND_STEP();
506 M.x86.R_GS = pop_word();
507 DECODE_CLEAR_SEGOVR();
508 END_OF_INSTR();
509}
510
511
512
513
514
515void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
516{
517 int mod, rl, rh;
518 uint srcoffset;
519 int bit,disp;
520
521 START_OF_INSTR();
522 DECODE_PRINTF("BTS\t");
523 FETCH_DECODE_MODRM(mod, rh, rl);
524 if (mod < 3) {
525 srcoffset = decode_rmXX_address(mod, rl);
526 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
527 u32 srcval,mask;
528 u32 *shiftreg;
529
530 DECODE_PRINTF(",");
531 shiftreg = DECODE_RM_LONG_REGISTER(rh);
532 TRACE_AND_STEP();
533 bit = *shiftreg & 0x1F;
534 disp = (s16)*shiftreg >> 5;
535 srcval = fetch_data_long(srcoffset+disp);
536 mask = (0x1 << bit);
537 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
538 store_data_long(srcoffset+disp, srcval | mask);
539 } else {
540 u16 srcval,mask;
541 u16 *shiftreg;
542
543 DECODE_PRINTF(",");
544 shiftreg = DECODE_RM_WORD_REGISTER(rh);
545 TRACE_AND_STEP();
546 bit = *shiftreg & 0xF;
547 disp = (s16)*shiftreg >> 4;
548 srcval = fetch_data_word(srcoffset+disp);
549 mask = (u16)(0x1 << bit);
550 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
551 store_data_word(srcoffset+disp, srcval | mask);
552 }
553 } else {
554 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
555 u32 *srcreg,*shiftreg;
556 u32 mask;
557
558 srcreg = DECODE_RM_LONG_REGISTER(rl);
559 DECODE_PRINTF(",");
560 shiftreg = DECODE_RM_LONG_REGISTER(rh);
561 TRACE_AND_STEP();
562 bit = *shiftreg & 0x1F;
563 mask = (0x1 << bit);
564 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
565 *srcreg |= mask;
566 } else {
567 u16 *srcreg,*shiftreg;
568 u16 mask;
569
570 srcreg = DECODE_RM_WORD_REGISTER(rl);
571 DECODE_PRINTF(",");
572 shiftreg = DECODE_RM_WORD_REGISTER(rh);
573 TRACE_AND_STEP();
574 bit = *shiftreg & 0xF;
575 mask = (u16)(0x1 << bit);
576 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
577 *srcreg |= mask;
578 }
579 }
580 DECODE_CLEAR_SEGOVR();
581 END_OF_INSTR();
582}
583
584
585
586
587
588void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
589{
590 int mod, rl, rh;
591 uint destoffset;
592 u8 shift;
593
594 START_OF_INSTR();
595 DECODE_PRINTF("SHLD\t");
596 FETCH_DECODE_MODRM(mod, rh, rl);
597 if (mod < 3) {
598 destoffset = decode_rmXX_address(mod, rl);
599 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
600 u32 destval;
601 u32 *shiftreg;
602
603 DECODE_PRINTF(",");
604 shiftreg = DECODE_RM_LONG_REGISTER(rh);
605 DECODE_PRINTF(",");
606 shift = fetch_byte_imm();
607 DECODE_PRINTF2("%d\n", shift);
608 TRACE_AND_STEP();
609 destval = fetch_data_long(destoffset);
610 destval = shrd_long(destval,*shiftreg,shift);
611 store_data_long(destoffset, destval);
612 } else {
613 u16 destval;
614 u16 *shiftreg;
615
616 DECODE_PRINTF(",");
617 shiftreg = DECODE_RM_WORD_REGISTER(rh);
618 DECODE_PRINTF(",");
619 shift = fetch_byte_imm();
620 DECODE_PRINTF2("%d\n", shift);
621 TRACE_AND_STEP();
622 destval = fetch_data_word(destoffset);
623 destval = shrd_word(destval,*shiftreg,shift);
624 store_data_word(destoffset, destval);
625 }
626 } else {
627 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
628 u32 *destreg,*shiftreg;
629
630 destreg = DECODE_RM_LONG_REGISTER(rl);
631 DECODE_PRINTF(",");
632 shiftreg = DECODE_RM_LONG_REGISTER(rh);
633 DECODE_PRINTF(",");
634 shift = fetch_byte_imm();
635 DECODE_PRINTF2("%d\n", shift);
636 TRACE_AND_STEP();
637 *destreg = shrd_long(*destreg,*shiftreg,shift);
638 } else {
639 u16 *destreg,*shiftreg;
640
641 destreg = DECODE_RM_WORD_REGISTER(rl);
642 DECODE_PRINTF(",");
643 shiftreg = DECODE_RM_WORD_REGISTER(rh);
644 DECODE_PRINTF(",");
645 shift = fetch_byte_imm();
646 DECODE_PRINTF2("%d\n", shift);
647 TRACE_AND_STEP();
648 *destreg = shrd_word(*destreg,*shiftreg,shift);
649 }
650 }
651 DECODE_CLEAR_SEGOVR();
652 END_OF_INSTR();
653}
654
655
656
657
658
659void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
660{
661 int mod, rl, rh;
662 uint destoffset;
663
664 START_OF_INSTR();
665 DECODE_PRINTF("SHLD\t");
666 FETCH_DECODE_MODRM(mod, rh, rl);
667 if (mod < 3) {
668 destoffset = decode_rmXX_address(mod, rl);
669 DECODE_PRINTF(",");
670 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
671 u32 destval;
672 u32 *shiftreg;
673
674 shiftreg = DECODE_RM_LONG_REGISTER(rh);
675 DECODE_PRINTF(",CL\n");
676 TRACE_AND_STEP();
677 destval = fetch_data_long(destoffset);
678 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
679 store_data_long(destoffset, destval);
680 } else {
681 u16 destval;
682 u16 *shiftreg;
683
684 shiftreg = DECODE_RM_WORD_REGISTER(rh);
685 DECODE_PRINTF(",CL\n");
686 TRACE_AND_STEP();
687 destval = fetch_data_word(destoffset);
688 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
689 store_data_word(destoffset, destval);
690 }
691 } else {
692 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
693 u32 *destreg,*shiftreg;
694
695 destreg = DECODE_RM_LONG_REGISTER(rl);
696 DECODE_PRINTF(",");
697 shiftreg = DECODE_RM_LONG_REGISTER(rh);
698 DECODE_PRINTF(",CL\n");
699 TRACE_AND_STEP();
700 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
701 } else {
702 u16 *destreg,*shiftreg;
703
704 destreg = DECODE_RM_WORD_REGISTER(rl);
705 DECODE_PRINTF(",");
706 shiftreg = DECODE_RM_WORD_REGISTER(rh);
707 DECODE_PRINTF(",CL\n");
708 TRACE_AND_STEP();
709 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
710 }
711 }
712 DECODE_CLEAR_SEGOVR();
713 END_OF_INSTR();
714}
715
716
717
718
719
720void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
721{
722 int mod, rl, rh;
723 uint srcoffset;
724
725 START_OF_INSTR();
726 DECODE_PRINTF("IMUL\t");
727 FETCH_DECODE_MODRM(mod, rh, rl);
728 if (mod < 3) {
729 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
730 u32 *destreg;
731 u32 srcval;
732 u32 res_lo,res_hi;
733
734 destreg = DECODE_RM_LONG_REGISTER(rh);
735 DECODE_PRINTF(",");
736 srcoffset = decode_rmXX_address(mod, rl);
737 srcval = fetch_data_long(srcoffset);
738 TRACE_AND_STEP();
739 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
740 if (res_hi != 0) {
741 SET_FLAG(F_CF);
742 SET_FLAG(F_OF);
743 } else {
744 CLEAR_FLAG(F_CF);
745 CLEAR_FLAG(F_OF);
746 }
747 *destreg = (u32)res_lo;
748 } else {
749 u16 *destreg;
750 u16 srcval;
751 u32 res;
752
753 destreg = DECODE_RM_WORD_REGISTER(rh);
754 DECODE_PRINTF(",");
755 srcoffset = decode_rmXX_address(mod, rl);
756 srcval = fetch_data_word(srcoffset);
757 TRACE_AND_STEP();
758 res = (s16)*destreg * (s16)srcval;
759 if (res > 0xFFFF) {
760 SET_FLAG(F_CF);
761 SET_FLAG(F_OF);
762 } else {
763 CLEAR_FLAG(F_CF);
764 CLEAR_FLAG(F_OF);
765 }
766 *destreg = (u16)res;
767 }
768 } else {
769 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
770 u32 *destreg,*srcreg;
771 u32 res_lo,res_hi;
772
773 destreg = DECODE_RM_LONG_REGISTER(rh);
774 DECODE_PRINTF(",");
775 srcreg = DECODE_RM_LONG_REGISTER(rl);
776 TRACE_AND_STEP();
777 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
778 if (res_hi != 0) {
779 SET_FLAG(F_CF);
780 SET_FLAG(F_OF);
781 } else {
782 CLEAR_FLAG(F_CF);
783 CLEAR_FLAG(F_OF);
784 }
785 *destreg = (u32)res_lo;
786 } else {
787 u16 *destreg,*srcreg;
788 u32 res;
789
790 destreg = DECODE_RM_WORD_REGISTER(rh);
791 DECODE_PRINTF(",");
792 srcreg = DECODE_RM_WORD_REGISTER(rl);
793 res = (s16)*destreg * (s16)*srcreg;
794 if (res > 0xFFFF) {
795 SET_FLAG(F_CF);
796 SET_FLAG(F_OF);
797 } else {
798 CLEAR_FLAG(F_CF);
799 CLEAR_FLAG(F_OF);
800 }
801 *destreg = (u16)res;
802 }
803 }
804 DECODE_CLEAR_SEGOVR();
805 END_OF_INSTR();
806}
807
808
809
810
811
812void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
813{
814 int mod, rh, rl;
815 u16 *dstreg;
816 uint srcoffset;
817
818 START_OF_INSTR();
819 DECODE_PRINTF("LSS\t");
820 FETCH_DECODE_MODRM(mod, rh, rl);
821 if (mod < 3) {
822 dstreg = DECODE_RM_WORD_REGISTER(rh);
823 DECODE_PRINTF(",");
824 srcoffset = decode_rmXX_address(mod, rl);
825 DECODE_PRINTF("\n");
826 TRACE_AND_STEP();
827 *dstreg = fetch_data_word(srcoffset);
828 M.x86.R_SS = fetch_data_word(srcoffset + 2);
829 } else {
830
831 TRACE_AND_STEP();
832 }
833 DECODE_CLEAR_SEGOVR();
834 END_OF_INSTR();
835}
836
837
838
839
840
841void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
842{
843 int mod, rl, rh;
844 uint srcoffset;
845 int bit,disp;
846
847 START_OF_INSTR();
848 DECODE_PRINTF("BTR\t");
849 FETCH_DECODE_MODRM(mod, rh, rl);
850 if (mod < 3) {
851 srcoffset = decode_rmXX_address(mod, rl);
852 DECODE_PRINTF(",");
853 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
854 u32 srcval,mask;
855 u32 *shiftreg;
856
857 shiftreg = DECODE_RM_LONG_REGISTER(rh);
858 TRACE_AND_STEP();
859 bit = *shiftreg & 0x1F;
860 disp = (s16)*shiftreg >> 5;
861 srcval = fetch_data_long(srcoffset+disp);
862 mask = (0x1 << bit);
863 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
864 store_data_long(srcoffset+disp, srcval & ~mask);
865 } else {
866 u16 srcval,mask;
867 u16 *shiftreg;
868
869 shiftreg = DECODE_RM_WORD_REGISTER(rh);
870 TRACE_AND_STEP();
871 bit = *shiftreg & 0xF;
872 disp = (s16)*shiftreg >> 4;
873 srcval = fetch_data_word(srcoffset+disp);
874 mask = (u16)(0x1 << bit);
875 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
876 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
877 }
878 } else {
879 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
880 u32 *srcreg,*shiftreg;
881 u32 mask;
882
883 srcreg = DECODE_RM_LONG_REGISTER(rl);
884 DECODE_PRINTF(",");
885 shiftreg = DECODE_RM_LONG_REGISTER(rh);
886 TRACE_AND_STEP();
887 bit = *shiftreg & 0x1F;
888 mask = (0x1 << bit);
889 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
890 *srcreg &= ~mask;
891 } else {
892 u16 *srcreg,*shiftreg;
893 u16 mask;
894
895 srcreg = DECODE_RM_WORD_REGISTER(rl);
896 DECODE_PRINTF(",");
897 shiftreg = DECODE_RM_WORD_REGISTER(rh);
898 TRACE_AND_STEP();
899 bit = *shiftreg & 0xF;
900 mask = (u16)(0x1 << bit);
901 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
902 *srcreg &= ~mask;
903 }
904 }
905 DECODE_CLEAR_SEGOVR();
906 END_OF_INSTR();
907}
908
909
910
911
912
913void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
914{
915 int mod, rh, rl;
916 u16 *dstreg;
917 uint srcoffset;
918
919 START_OF_INSTR();
920 DECODE_PRINTF("LFS\t");
921 FETCH_DECODE_MODRM(mod, rh, rl);
922 if (mod < 3) {
923 dstreg = DECODE_RM_WORD_REGISTER(rh);
924 DECODE_PRINTF(",");
925 srcoffset = decode_rmXX_address(mod, rl);
926 DECODE_PRINTF("\n");
927 TRACE_AND_STEP();
928 *dstreg = fetch_data_word(srcoffset);
929 M.x86.R_FS = fetch_data_word(srcoffset + 2);
930 } else {
931
932 TRACE_AND_STEP();
933 }
934 DECODE_CLEAR_SEGOVR();
935 END_OF_INSTR();
936}
937
938
939
940
941
942void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
943{
944 int mod, rh, rl;
945 u16 *dstreg;
946 uint srcoffset;
947
948 START_OF_INSTR();
949 DECODE_PRINTF("LGS\t");
950 FETCH_DECODE_MODRM(mod, rh, rl);
951 if (mod < 3) {
952 dstreg = DECODE_RM_WORD_REGISTER(rh);
953 DECODE_PRINTF(",");
954 srcoffset = decode_rmXX_address(mod, rl);
955 DECODE_PRINTF("\n");
956 TRACE_AND_STEP();
957 *dstreg = fetch_data_word(srcoffset);
958 M.x86.R_GS = fetch_data_word(srcoffset + 2);
959 } else {
960
961 TRACE_AND_STEP();
962 }
963 DECODE_CLEAR_SEGOVR();
964 END_OF_INSTR();
965}
966
967
968
969
970
971void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
972{
973 int mod, rl, rh;
974 uint srcoffset;
975
976 START_OF_INSTR();
977 DECODE_PRINTF("MOVZX\t");
978 FETCH_DECODE_MODRM(mod, rh, rl);
979 if (mod < 3) {
980 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
981 u32 *destreg;
982 u32 srcval;
983
984 destreg = DECODE_RM_LONG_REGISTER(rh);
985 DECODE_PRINTF(",");
986 srcoffset = decode_rmXX_address(mod, rl);
987 srcval = fetch_data_byte(srcoffset);
988 DECODE_PRINTF("\n");
989 TRACE_AND_STEP();
990 *destreg = srcval;
991 } else {
992 u16 *destreg;
993 u16 srcval;
994
995 destreg = DECODE_RM_WORD_REGISTER(rh);
996 DECODE_PRINTF(",");
997 srcoffset = decode_rmXX_address(mod, rl);
998 srcval = fetch_data_byte(srcoffset);
999 DECODE_PRINTF("\n");
1000 TRACE_AND_STEP();
1001 *destreg = srcval;
1002 }
1003 } else {
1004 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1005 u32 *destreg;
1006 u8 *srcreg;
1007
1008 destreg = DECODE_RM_LONG_REGISTER(rh);
1009 DECODE_PRINTF(",");
1010 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1011 DECODE_PRINTF("\n");
1012 TRACE_AND_STEP();
1013 *destreg = *srcreg;
1014 } else {
1015 u16 *destreg;
1016 u8 *srcreg;
1017
1018 destreg = DECODE_RM_WORD_REGISTER(rh);
1019 DECODE_PRINTF(",");
1020 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1021 DECODE_PRINTF("\n");
1022 TRACE_AND_STEP();
1023 *destreg = *srcreg;
1024 }
1025 }
1026 DECODE_CLEAR_SEGOVR();
1027 END_OF_INSTR();
1028}
1029
1030
1031
1032
1033
1034void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1035{
1036 int mod, rl, rh;
1037 uint srcoffset;
1038 u32 *destreg;
1039 u32 srcval;
1040 u16 *srcreg;
1041
1042 START_OF_INSTR();
1043 DECODE_PRINTF("MOVZX\t");
1044 FETCH_DECODE_MODRM(mod, rh, rl);
1045 if (mod < 3) {
1046 destreg = DECODE_RM_LONG_REGISTER(rh);
1047 DECODE_PRINTF(",");
1048 srcoffset = decode_rmXX_address(mod, rl);
1049 srcval = fetch_data_word(srcoffset);
1050 DECODE_PRINTF("\n");
1051 TRACE_AND_STEP();
1052 *destreg = srcval;
1053 } else {
1054 destreg = DECODE_RM_LONG_REGISTER(rh);
1055 DECODE_PRINTF(",");
1056 srcreg = DECODE_RM_WORD_REGISTER(rl);
1057 DECODE_PRINTF("\n");
1058 TRACE_AND_STEP();
1059 *destreg = *srcreg;
1060 }
1061 DECODE_CLEAR_SEGOVR();
1062 END_OF_INSTR();
1063}
1064
1065
1066
1067
1068
1069void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1070{
1071 int mod, rl, rh;
1072 uint srcoffset;
1073 u8 shift;
1074 int bit;
1075
1076 START_OF_INSTR();
1077 FETCH_DECODE_MODRM(mod, rh, rl);
1078 switch (rh) {
1079 case 4:
1080 DECODE_PRINTF("BT\t");
1081 break;
1082 case 5:
1083 DECODE_PRINTF("BTS\t");
1084 break;
1085 case 6:
1086 DECODE_PRINTF("BTR\t");
1087 break;
1088 case 7:
1089 DECODE_PRINTF("BTC\t");
1090 break;
1091 default:
1092 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1093 TRACE_REGS();
1094 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1095 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1096 HALT_SYS();
1097 }
1098 if (mod < 3) {
1099
1100 srcoffset = decode_rmXX_address(mod, rl);
1101 shift = fetch_byte_imm();
1102 DECODE_PRINTF2(",%d\n", shift);
1103 TRACE_AND_STEP();
1104
1105 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1106 u32 srcval, mask;
1107
1108 bit = shift & 0x1F;
1109 srcval = fetch_data_long(srcoffset);
1110 mask = (0x1 << bit);
1111 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1112 switch (rh) {
1113 case 5:
1114 store_data_long(srcoffset, srcval | mask);
1115 break;
1116 case 6:
1117 store_data_long(srcoffset, srcval & ~mask);
1118 break;
1119 case 7:
1120 store_data_long(srcoffset, srcval ^ mask);
1121 break;
1122 default:
1123 break;
1124 }
1125 } else {
1126 u16 srcval, mask;
1127
1128 bit = shift & 0xF;
1129 srcval = fetch_data_word(srcoffset);
1130 mask = (0x1 << bit);
1131 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1132 switch (rh) {
1133 case 5:
1134 store_data_word(srcoffset, srcval | mask);
1135 break;
1136 case 6:
1137 store_data_word(srcoffset, srcval & ~mask);
1138 break;
1139 case 7:
1140 store_data_word(srcoffset, srcval ^ mask);
1141 break;
1142 default:
1143 break;
1144 }
1145 }
1146 } else {
1147 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1148 u32 *srcreg;
1149 u32 mask;
1150
1151 srcreg = DECODE_RM_LONG_REGISTER(rl);
1152 shift = fetch_byte_imm();
1153 DECODE_PRINTF2(",%d\n", shift);
1154 TRACE_AND_STEP();
1155 bit = shift & 0x1F;
1156 mask = (0x1 << bit);
1157 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1158 switch (rh) {
1159 case 5:
1160 *srcreg |= mask;
1161 break;
1162 case 6:
1163 *srcreg &= ~mask;
1164 break;
1165 case 7:
1166 *srcreg ^= mask;
1167 break;
1168 default:
1169 break;
1170 }
1171 } else {
1172 u16 *srcreg;
1173 u16 mask;
1174
1175 srcreg = DECODE_RM_WORD_REGISTER(rl);
1176 shift = fetch_byte_imm();
1177 DECODE_PRINTF2(",%d\n", shift);
1178 TRACE_AND_STEP();
1179 bit = shift & 0xF;
1180 mask = (0x1 << bit);
1181 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1182 switch (rh) {
1183 case 5:
1184 *srcreg |= mask;
1185 break;
1186 case 6:
1187 *srcreg &= ~mask;
1188 break;
1189 case 7:
1190 *srcreg ^= mask;
1191 break;
1192 default:
1193 break;
1194 }
1195 }
1196 }
1197 DECODE_CLEAR_SEGOVR();
1198 END_OF_INSTR();
1199}
1200
1201
1202
1203
1204
1205void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
1206{
1207 int mod, rl, rh;
1208 uint srcoffset;
1209 int bit,disp;
1210
1211 START_OF_INSTR();
1212 DECODE_PRINTF("BTC\t");
1213 FETCH_DECODE_MODRM(mod, rh, rl);
1214 if (mod < 3) {
1215 srcoffset = decode_rmXX_address(mod, rl);
1216 DECODE_PRINTF(",");
1217 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1218 u32 srcval,mask;
1219 u32 *shiftreg;
1220
1221 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1222 TRACE_AND_STEP();
1223 bit = *shiftreg & 0x1F;
1224 disp = (s16)*shiftreg >> 5;
1225 srcval = fetch_data_long(srcoffset+disp);
1226 mask = (0x1 << bit);
1227 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1228 store_data_long(srcoffset+disp, srcval ^ mask);
1229 } else {
1230 u16 srcval,mask;
1231 u16 *shiftreg;
1232
1233 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1234 TRACE_AND_STEP();
1235 bit = *shiftreg & 0xF;
1236 disp = (s16)*shiftreg >> 4;
1237 srcval = fetch_data_word(srcoffset+disp);
1238 mask = (u16)(0x1 << bit);
1239 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1240 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
1241 }
1242 } else {
1243 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1244 u32 *srcreg,*shiftreg;
1245 u32 mask;
1246
1247 srcreg = DECODE_RM_LONG_REGISTER(rl);
1248 DECODE_PRINTF(",");
1249 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1250 TRACE_AND_STEP();
1251 bit = *shiftreg & 0x1F;
1252 mask = (0x1 << bit);
1253 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1254 *srcreg ^= mask;
1255 } else {
1256 u16 *srcreg,*shiftreg;
1257 u16 mask;
1258
1259 srcreg = DECODE_RM_WORD_REGISTER(rl);
1260 DECODE_PRINTF(",");
1261 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1262 TRACE_AND_STEP();
1263 bit = *shiftreg & 0xF;
1264 mask = (u16)(0x1 << bit);
1265 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1266 *srcreg ^= mask;
1267 }
1268 }
1269 DECODE_CLEAR_SEGOVR();
1270 END_OF_INSTR();
1271}
1272
1273
1274
1275
1276
1277void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
1278{
1279 int mod, rl, rh;
1280 uint srcoffset;
1281
1282 START_OF_INSTR();
1283 DECODE_PRINTF("BSF\n");
1284 FETCH_DECODE_MODRM(mod, rh, rl);
1285 if (mod < 3) {
1286 srcoffset = decode_rmXX_address(mod, rl);
1287 DECODE_PRINTF(",");
1288 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1289 u32 srcval, *dstreg;
1290
1291 dstreg = DECODE_RM_LONG_REGISTER(rh);
1292 TRACE_AND_STEP();
1293 srcval = fetch_data_long(srcoffset);
1294 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1295 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1296 if ((srcval >> *dstreg) & 1) break;
1297 } else {
1298 u16 srcval, *dstreg;
1299
1300 dstreg = DECODE_RM_WORD_REGISTER(rh);
1301 TRACE_AND_STEP();
1302 srcval = fetch_data_word(srcoffset);
1303 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1304 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1305 if ((srcval >> *dstreg) & 1) break;
1306 }
1307 } else {
1308 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1309 u32 *srcreg, *dstreg;
1310
1311 srcreg = DECODE_RM_LONG_REGISTER(rl);
1312 DECODE_PRINTF(",");
1313 dstreg = DECODE_RM_LONG_REGISTER(rh);
1314 TRACE_AND_STEP();
1315 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1316 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1317 if ((*srcreg >> *dstreg) & 1) break;
1318 } else {
1319 u16 *srcreg, *dstreg;
1320
1321 srcreg = DECODE_RM_WORD_REGISTER(rl);
1322 DECODE_PRINTF(",");
1323 dstreg = DECODE_RM_WORD_REGISTER(rh);
1324 TRACE_AND_STEP();
1325 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1326 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1327 if ((*srcreg >> *dstreg) & 1) break;
1328 }
1329 }
1330 DECODE_CLEAR_SEGOVR();
1331 END_OF_INSTR();
1332}
1333
1334
1335
1336
1337
1338void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
1339{
1340 int mod, rl, rh;
1341 uint srcoffset;
1342
1343 START_OF_INSTR();
1344 DECODE_PRINTF("BSF\n");
1345 FETCH_DECODE_MODRM(mod, rh, rl);
1346 if (mod < 3) {
1347 srcoffset = decode_rmXX_address(mod, rl);
1348 DECODE_PRINTF(",");
1349 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1350 u32 srcval, *dstreg;
1351
1352 dstreg = DECODE_RM_LONG_REGISTER(rh);
1353 TRACE_AND_STEP();
1354 srcval = fetch_data_long(srcoffset);
1355 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1356 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1357 if ((srcval >> *dstreg) & 1) break;
1358 } else {
1359 u16 srcval, *dstreg;
1360
1361 dstreg = DECODE_RM_WORD_REGISTER(rh);
1362 TRACE_AND_STEP();
1363 srcval = fetch_data_word(srcoffset);
1364 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1365 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1366 if ((srcval >> *dstreg) & 1) break;
1367 }
1368 } else {
1369 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1370 u32 *srcreg, *dstreg;
1371
1372 srcreg = DECODE_RM_LONG_REGISTER(rl);
1373 DECODE_PRINTF(",");
1374 dstreg = DECODE_RM_LONG_REGISTER(rh);
1375 TRACE_AND_STEP();
1376 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1377 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1378 if ((*srcreg >> *dstreg) & 1) break;
1379 } else {
1380 u16 *srcreg, *dstreg;
1381
1382 srcreg = DECODE_RM_WORD_REGISTER(rl);
1383 DECODE_PRINTF(",");
1384 dstreg = DECODE_RM_WORD_REGISTER(rh);
1385 TRACE_AND_STEP();
1386 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1387 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1388 if ((*srcreg >> *dstreg) & 1) break;
1389 }
1390 }
1391 DECODE_CLEAR_SEGOVR();
1392 END_OF_INSTR();
1393}
1394
1395
1396
1397
1398
1399void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1400{
1401 int mod, rl, rh;
1402 uint srcoffset;
1403
1404 START_OF_INSTR();
1405 DECODE_PRINTF("MOVSX\t");
1406 FETCH_DECODE_MODRM(mod, rh, rl);
1407 if (mod < 3) {
1408 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1409 u32 *destreg;
1410 u32 srcval;
1411
1412 destreg = DECODE_RM_LONG_REGISTER(rh);
1413 DECODE_PRINTF(",");
1414 srcoffset = decode_rmXX_address(mod, rl);
1415 srcval = (s32)((s8)fetch_data_byte(srcoffset));
1416 DECODE_PRINTF("\n");
1417 TRACE_AND_STEP();
1418 *destreg = srcval;
1419 } else {
1420 u16 *destreg;
1421 u16 srcval;
1422
1423 destreg = DECODE_RM_WORD_REGISTER(rh);
1424 DECODE_PRINTF(",");
1425 srcoffset = decode_rmXX_address(mod, rl);
1426 srcval = (s16)((s8)fetch_data_byte(srcoffset));
1427 DECODE_PRINTF("\n");
1428 TRACE_AND_STEP();
1429 *destreg = srcval;
1430 }
1431 } else {
1432 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1433 u32 *destreg;
1434 u8 *srcreg;
1435
1436 destreg = DECODE_RM_LONG_REGISTER(rh);
1437 DECODE_PRINTF(",");
1438 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1439 DECODE_PRINTF("\n");
1440 TRACE_AND_STEP();
1441 *destreg = (s32)((s8)*srcreg);
1442 } else {
1443 u16 *destreg;
1444 u8 *srcreg;
1445
1446 destreg = DECODE_RM_WORD_REGISTER(rh);
1447 DECODE_PRINTF(",");
1448 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1449 DECODE_PRINTF("\n");
1450 TRACE_AND_STEP();
1451 *destreg = (s16)((s8)*srcreg);
1452 }
1453 }
1454 DECODE_CLEAR_SEGOVR();
1455 END_OF_INSTR();
1456}
1457
1458
1459
1460
1461
1462void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
1463{
1464 int mod, rl, rh;
1465 uint srcoffset;
1466 u32 *destreg;
1467 u32 srcval;
1468 u16 *srcreg;
1469
1470 START_OF_INSTR();
1471 DECODE_PRINTF("MOVSX\t");
1472 FETCH_DECODE_MODRM(mod, rh, rl);
1473 if (mod < 3) {
1474 destreg = DECODE_RM_LONG_REGISTER(rh);
1475 DECODE_PRINTF(",");
1476 srcoffset = decode_rmXX_address(mod, rl);
1477 srcval = (s32)((s16)fetch_data_word(srcoffset));
1478 DECODE_PRINTF("\n");
1479 TRACE_AND_STEP();
1480 *destreg = srcval;
1481 } else {
1482 destreg = DECODE_RM_LONG_REGISTER(rh);
1483 DECODE_PRINTF(",");
1484 srcreg = DECODE_RM_WORD_REGISTER(rl);
1485 DECODE_PRINTF("\n");
1486 TRACE_AND_STEP();
1487 *destreg = (s32)((s16)*srcreg);
1488 }
1489 DECODE_CLEAR_SEGOVR();
1490 END_OF_INSTR();
1491}
1492
1493
1494
1495
1496void (*x86emu_optab2[256])(u8) =
1497{
1498 x86emuOp2_illegal_op,
1499 x86emuOp2_illegal_op,
1500 x86emuOp2_illegal_op,
1501 x86emuOp2_illegal_op,
1502 x86emuOp2_illegal_op,
1503 x86emuOp2_illegal_op,
1504 x86emuOp2_illegal_op,
1505 x86emuOp2_illegal_op,
1506 x86emuOp2_illegal_op,
1507 x86emuOp2_illegal_op,
1508 x86emuOp2_illegal_op,
1509 x86emuOp2_illegal_op,
1510 x86emuOp2_illegal_op,
1511 x86emuOp2_illegal_op,
1512 x86emuOp2_illegal_op,
1513 x86emuOp2_illegal_op,
1514
1515 x86emuOp2_illegal_op,
1516 x86emuOp2_illegal_op,
1517 x86emuOp2_illegal_op,
1518 x86emuOp2_illegal_op,
1519 x86emuOp2_illegal_op,
1520 x86emuOp2_illegal_op,
1521 x86emuOp2_illegal_op,
1522 x86emuOp2_illegal_op,
1523 x86emuOp2_illegal_op,
1524 x86emuOp2_illegal_op,
1525 x86emuOp2_illegal_op,
1526 x86emuOp2_illegal_op,
1527 x86emuOp2_illegal_op,
1528 x86emuOp2_illegal_op,
1529 x86emuOp2_illegal_op,
1530 x86emuOp2_illegal_op,
1531
1532 x86emuOp2_illegal_op,
1533 x86emuOp2_illegal_op,
1534 x86emuOp2_illegal_op,
1535 x86emuOp2_illegal_op,
1536 x86emuOp2_illegal_op,
1537 x86emuOp2_illegal_op,
1538 x86emuOp2_illegal_op,
1539 x86emuOp2_illegal_op,
1540 x86emuOp2_illegal_op,
1541 x86emuOp2_illegal_op,
1542 x86emuOp2_illegal_op,
1543 x86emuOp2_illegal_op,
1544 x86emuOp2_illegal_op,
1545 x86emuOp2_illegal_op,
1546 x86emuOp2_illegal_op,
1547 x86emuOp2_illegal_op,
1548
1549 x86emuOp2_illegal_op,
1550 x86emuOp2_illegal_op,
1551 x86emuOp2_illegal_op,
1552 x86emuOp2_illegal_op,
1553 x86emuOp2_illegal_op,
1554 x86emuOp2_illegal_op,
1555 x86emuOp2_illegal_op,
1556 x86emuOp2_illegal_op,
1557 x86emuOp2_illegal_op,
1558 x86emuOp2_illegal_op,
1559 x86emuOp2_illegal_op,
1560 x86emuOp2_illegal_op,
1561 x86emuOp2_illegal_op,
1562 x86emuOp2_illegal_op,
1563 x86emuOp2_illegal_op,
1564 x86emuOp2_illegal_op,
1565
1566 x86emuOp2_illegal_op,
1567 x86emuOp2_illegal_op,
1568 x86emuOp2_illegal_op,
1569 x86emuOp2_illegal_op,
1570 x86emuOp2_illegal_op,
1571 x86emuOp2_illegal_op,
1572 x86emuOp2_illegal_op,
1573 x86emuOp2_illegal_op,
1574 x86emuOp2_illegal_op,
1575 x86emuOp2_illegal_op,
1576 x86emuOp2_illegal_op,
1577 x86emuOp2_illegal_op,
1578 x86emuOp2_illegal_op,
1579 x86emuOp2_illegal_op,
1580 x86emuOp2_illegal_op,
1581 x86emuOp2_illegal_op,
1582
1583 x86emuOp2_illegal_op,
1584 x86emuOp2_illegal_op,
1585 x86emuOp2_illegal_op,
1586 x86emuOp2_illegal_op,
1587 x86emuOp2_illegal_op,
1588 x86emuOp2_illegal_op,
1589 x86emuOp2_illegal_op,
1590 x86emuOp2_illegal_op,
1591 x86emuOp2_illegal_op,
1592 x86emuOp2_illegal_op,
1593 x86emuOp2_illegal_op,
1594 x86emuOp2_illegal_op,
1595 x86emuOp2_illegal_op,
1596 x86emuOp2_illegal_op,
1597 x86emuOp2_illegal_op,
1598 x86emuOp2_illegal_op,
1599
1600 x86emuOp2_illegal_op,
1601 x86emuOp2_illegal_op,
1602 x86emuOp2_illegal_op,
1603 x86emuOp2_illegal_op,
1604 x86emuOp2_illegal_op,
1605 x86emuOp2_illegal_op,
1606 x86emuOp2_illegal_op,
1607 x86emuOp2_illegal_op,
1608 x86emuOp2_illegal_op,
1609 x86emuOp2_illegal_op,
1610 x86emuOp2_illegal_op,
1611 x86emuOp2_illegal_op,
1612 x86emuOp2_illegal_op,
1613 x86emuOp2_illegal_op,
1614 x86emuOp2_illegal_op,
1615 x86emuOp2_illegal_op,
1616
1617 x86emuOp2_illegal_op,
1618 x86emuOp2_illegal_op,
1619 x86emuOp2_illegal_op,
1620 x86emuOp2_illegal_op,
1621 x86emuOp2_illegal_op,
1622 x86emuOp2_illegal_op,
1623 x86emuOp2_illegal_op,
1624 x86emuOp2_illegal_op,
1625 x86emuOp2_illegal_op,
1626 x86emuOp2_illegal_op,
1627 x86emuOp2_illegal_op,
1628 x86emuOp2_illegal_op,
1629 x86emuOp2_illegal_op,
1630 x86emuOp2_illegal_op,
1631 x86emuOp2_illegal_op,
1632 x86emuOp2_illegal_op,
1633
1634 x86emuOp2_long_jump,
1635 x86emuOp2_long_jump,
1636 x86emuOp2_long_jump,
1637 x86emuOp2_long_jump,
1638 x86emuOp2_long_jump,
1639 x86emuOp2_long_jump,
1640 x86emuOp2_long_jump,
1641 x86emuOp2_long_jump,
1642 x86emuOp2_long_jump,
1643 x86emuOp2_long_jump,
1644 x86emuOp2_long_jump,
1645 x86emuOp2_long_jump,
1646 x86emuOp2_long_jump,
1647 x86emuOp2_long_jump,
1648 x86emuOp2_long_jump,
1649 x86emuOp2_long_jump,
1650
1651 x86emuOp2_set_byte,
1652 x86emuOp2_set_byte,
1653 x86emuOp2_set_byte,
1654 x86emuOp2_set_byte,
1655 x86emuOp2_set_byte,
1656 x86emuOp2_set_byte,
1657 x86emuOp2_set_byte,
1658 x86emuOp2_set_byte,
1659 x86emuOp2_set_byte,
1660 x86emuOp2_set_byte,
1661 x86emuOp2_set_byte,
1662 x86emuOp2_set_byte,
1663 x86emuOp2_set_byte,
1664 x86emuOp2_set_byte,
1665 x86emuOp2_set_byte,
1666 x86emuOp2_set_byte,
1667
1668 x86emuOp2_push_FS,
1669 x86emuOp2_pop_FS,
1670 x86emuOp2_illegal_op,
1671 x86emuOp2_bt_R,
1672 x86emuOp2_shld_IMM,
1673 x86emuOp2_shld_CL,
1674 x86emuOp2_illegal_op,
1675 x86emuOp2_illegal_op,
1676 x86emuOp2_push_GS,
1677 x86emuOp2_pop_GS,
1678 x86emuOp2_illegal_op,
1679 x86emuOp2_bt_R,
1680 x86emuOp2_shrd_IMM,
1681 x86emuOp2_shrd_CL,
1682 x86emuOp2_illegal_op,
1683 x86emuOp2_imul_R_RM,
1684
1685 x86emuOp2_illegal_op,
1686 x86emuOp2_illegal_op,
1687 x86emuOp2_lss_R_IMM,
1688 x86emuOp2_btr_R,
1689 x86emuOp2_lfs_R_IMM,
1690 x86emuOp2_lgs_R_IMM,
1691 x86emuOp2_movzx_byte_R_RM,
1692 x86emuOp2_movzx_word_R_RM,
1693 x86emuOp2_illegal_op,
1694 x86emuOp2_illegal_op,
1695 x86emuOp2_btX_I,
1696 x86emuOp2_btc_R,
1697 x86emuOp2_bsf,
1698 x86emuOp2_bsr,
1699 x86emuOp2_movsx_byte_R_RM,
1700 x86emuOp2_movsx_word_R_RM,
1701
1702 x86emuOp2_illegal_op,
1703 x86emuOp2_illegal_op,
1704 x86emuOp2_illegal_op,
1705 x86emuOp2_illegal_op,
1706 x86emuOp2_illegal_op,
1707 x86emuOp2_illegal_op,
1708 x86emuOp2_illegal_op,
1709 x86emuOp2_illegal_op,
1710 x86emuOp2_illegal_op,
1711 x86emuOp2_illegal_op,
1712 x86emuOp2_illegal_op,
1713 x86emuOp2_illegal_op,
1714 x86emuOp2_illegal_op,
1715 x86emuOp2_illegal_op,
1716 x86emuOp2_illegal_op,
1717 x86emuOp2_illegal_op,
1718
1719 x86emuOp2_illegal_op,
1720 x86emuOp2_illegal_op,
1721 x86emuOp2_illegal_op,
1722 x86emuOp2_illegal_op,
1723 x86emuOp2_illegal_op,
1724 x86emuOp2_illegal_op,
1725 x86emuOp2_illegal_op,
1726 x86emuOp2_illegal_op,
1727 x86emuOp2_illegal_op,
1728 x86emuOp2_illegal_op,
1729 x86emuOp2_illegal_op,
1730 x86emuOp2_illegal_op,
1731 x86emuOp2_illegal_op,
1732 x86emuOp2_illegal_op,
1733 x86emuOp2_illegal_op,
1734 x86emuOp2_illegal_op,
1735
1736 x86emuOp2_illegal_op,
1737 x86emuOp2_illegal_op,
1738 x86emuOp2_illegal_op,
1739 x86emuOp2_illegal_op,
1740 x86emuOp2_illegal_op,
1741 x86emuOp2_illegal_op,
1742 x86emuOp2_illegal_op,
1743 x86emuOp2_illegal_op,
1744 x86emuOp2_illegal_op,
1745 x86emuOp2_illegal_op,
1746 x86emuOp2_illegal_op,
1747 x86emuOp2_illegal_op,
1748 x86emuOp2_illegal_op,
1749 x86emuOp2_illegal_op,
1750 x86emuOp2_illegal_op,
1751 x86emuOp2_illegal_op,
1752
1753 x86emuOp2_illegal_op,
1754 x86emuOp2_illegal_op,
1755 x86emuOp2_illegal_op,
1756 x86emuOp2_illegal_op,
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770