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,6 +1615,56 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | ||
1615 | *offset_ptr = disp; | 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 | /* used for LEA and MOV AX, mem */ | 1668 | /* used for LEA and MOV AX, mem */ |
1619 | static void gen_add_A0_ds_seg(DisasContext *s) | 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,10 +5841,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
5791 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); | 5841 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
5792 | /* nothing more to do */ | 5842 | /* nothing more to do */ |
5793 | break; | 5843 | break; |
5794 | - default: | ||
5795 | - goto illegal_op; | 5844 | + default: /* nop (multi byte) */ |
5845 | + gen_nop_modrm(s, modrm); | ||
5846 | + break; | ||
5796 | } | 5847 | } |
5797 | break; | 5848 | break; |
5849 | + case 0x119 ... 0x11f: /* nop (multi byte) */ | ||
5850 | + modrm = ldub_code(s->pc++); | ||
5851 | + gen_nop_modrm(s, modrm); | ||
5852 | + break; | ||
5798 | case 0x120: /* mov reg, crN */ | 5853 | case 0x120: /* mov reg, crN */ |
5799 | case 0x122: /* mov crN, reg */ | 5854 | case 0x122: /* mov crN, reg */ |
5800 | if (s->cpl != 0) { | 5855 | if (s->cpl != 0) { |