From 0214b6b4deb87d70bfc5fb00ba62f85fcf06f8ab Mon Sep 17 00:00:00 2001 From: Matthew Ogilvie Date: Thu, 23 Aug 2012 00:24:39 -0600 Subject: target-i386/translate.c: mov to/from crN/drN: ignore mod bits > This instruction is always treated as a register-to-register (MOD = 11) > instruction, regardless of the encoding of the MOD field in the MODR/M > byte. Also, Microport UNIX System V/386 v 2.1 (ca 1987) runs fine on real Intel 386 and 486 CPU's (at least), but does not run in qemu without this patch. Signed-off-by: Matthew Ogilvie Signed-off-by: malc (cherry picked from commit 5c73b757e3aa80dc84352b2ede0d8bdea5419f6d) Conflicts: target-i386/translate.c Signed-off-by: Michael Roth --- target-i386/translate.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index c1ede1a75..c792e7ace 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7409,8 +7409,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { modrm = ldub_code(s->pc++); - if ((modrm & 0xc0) != 0xc0) - goto illegal_op; + /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). + * AMD documentation (24594.pdf) and testing of + * intel 386 and 486 processors all show that the mod bits + * are assumed to be 1's, regardless of actual values. + */ rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (CODE64(s)) @@ -7451,8 +7454,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { modrm = ldub_code(s->pc++); - if ((modrm & 0xc0) != 0xc0) - goto illegal_op; + /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). + * AMD documentation (24594.pdf) and testing of + * intel 386 and 486 processors all show that the mod bits + * are assumed to be 1's, regardless of actual values. + */ rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (CODE64(s)) -- cgit v1.2.3