diff options
author | Eduardo Habkost <ehabkost@redhat.com> | 2015-11-04 19:24:46 -0200 |
---|---|---|
committer | Eduardo Habkost <ehabkost@redhat.com> | 2015-11-06 12:03:12 -0200 |
commit | 891bc821a3ee462b09b1ec436f2891f00ab1f85b (patch) | |
tree | 2ba503cbbd58baf7315f091988ec2f7692c069c4 /target-i386/translate.c | |
parent | 5e1fac2dba7780e0cb2c022d4b39586af70bea0d (diff) |
target-i386: tcg: Check right CPUID bits for clflushopt/pcommit
Detect the clflushopt and pcommit instructions and check their
corresponding feature flags, instead of checking CPUID_SSE and
CPUID_CLFLUSH.
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Diffstat (limited to 'target-i386/translate.c')
-rw-r--r-- | target-i386/translate.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/target-i386/translate.c b/target-i386/translate.c index c6d9be6043..fbe4f80aa6 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7731,16 +7731,28 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, goto illegal_op; } break; - case 7: /* sfence / clflush */ + case 7: /* sfence / clflush / clflushopt / pcommit */ if ((modrm & 0xc7) == 0xc0) { - /* sfence */ - /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */ - if (!(s->cpuid_features & CPUID_SSE)) - goto illegal_op; + if (s->prefix & PREFIX_DATA) { + /* pcommit */ + if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)) + goto illegal_op; + } else { + /* sfence */ + /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */ + if (!(s->cpuid_features & CPUID_SSE)) + goto illegal_op; + } } else { - /* clflush */ - if (!(s->cpuid_features & CPUID_CLFLUSH)) - goto illegal_op; + if (s->prefix & PREFIX_DATA) { + /* clflushopt */ + if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) + goto illegal_op; + } else { + /* clflush */ + if (!(s->cpuid_features & CPUID_CLFLUSH)) + goto illegal_op; + } gen_lea_modrm(env, s, modrm); } break; |