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