Commit e17a36ce41bc76abecebb434850ba619f5182ba8
1 parent
03c18475
multi byte nop support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2145 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
57 additions
and
2 deletions
target-i386/translate.c
... | ... | @@ -1615,6 +1615,56 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ |
1615 | 1615 | *offset_ptr = disp; |
1616 | 1616 | } |
1617 | 1617 | |
1618 | +static void gen_nop_modrm(DisasContext *s, int modrm) | |
1619 | +{ | |
1620 | + int mod, rm, base, code; | |
1621 | + | |
1622 | + mod = (modrm >> 6) & 3; | |
1623 | + if (mod == 3) | |
1624 | + return; | |
1625 | + rm = modrm & 7; | |
1626 | + | |
1627 | + if (s->aflag) { | |
1628 | + | |
1629 | + base = rm; | |
1630 | + | |
1631 | + if (base == 4) { | |
1632 | + code = ldub_code(s->pc++); | |
1633 | + base = (code & 7); | |
1634 | + } | |
1635 | + | |
1636 | + switch (mod) { | |
1637 | + case 0: | |
1638 | + if (base == 5) { | |
1639 | + s->pc += 4; | |
1640 | + } | |
1641 | + break; | |
1642 | + case 1: | |
1643 | + s->pc++; | |
1644 | + break; | |
1645 | + default: | |
1646 | + case 2: | |
1647 | + s->pc += 4; | |
1648 | + break; | |
1649 | + } | |
1650 | + } else { | |
1651 | + switch (mod) { | |
1652 | + case 0: | |
1653 | + if (rm == 6) { | |
1654 | + s->pc += 2; | |
1655 | + } | |
1656 | + break; | |
1657 | + case 1: | |
1658 | + s->pc++; | |
1659 | + break; | |
1660 | + default: | |
1661 | + case 2: | |
1662 | + s->pc += 2; | |
1663 | + break; | |
1664 | + } | |
1665 | + } | |
1666 | +} | |
1667 | + | |
1618 | 1668 | /* used for LEA and MOV AX, mem */ |
1619 | 1669 | static void gen_add_A0_ds_seg(DisasContext *s) |
1620 | 1670 | { |
... | ... | @@ -5791,10 +5841,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
5791 | 5841 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
5792 | 5842 | /* nothing more to do */ |
5793 | 5843 | break; |
5794 | - default: | |
5795 | - goto illegal_op; | |
5844 | + default: /* nop (multi byte) */ | |
5845 | + gen_nop_modrm(s, modrm); | |
5846 | + break; | |
5796 | 5847 | } |
5797 | 5848 | break; |
5849 | + case 0x119 ... 0x11f: /* nop (multi byte) */ | |
5850 | + modrm = ldub_code(s->pc++); | |
5851 | + gen_nop_modrm(s, modrm); | |
5852 | + break; | |
5798 | 5853 | case 0x120: /* mov reg, crN */ |
5799 | 5854 | case 0x122: /* mov crN, reg */ |
5800 | 5855 | if (s->cpl != 0) { | ... | ... |