From e771edab0d9aaa7925dc26aec3e0c6eac27f19c3 Mon Sep 17 00:00:00 2001 From: aurel32 Date: Wed, 9 Apr 2008 06:41:37 +0000 Subject: [PATCH] Check for 3DNow! CPUID at translation time git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4184 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/translate.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index 74ad2dc..e9c65aa 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -100,6 +100,7 @@ typedef struct DisasContext { int rip_offset; /* only used in x86_64, but left for simplicity */ int cpuid_features; int cpuid_ext_features; + int cpuid_ext2_features; } DisasContext; static void gen_eob(DisasContext *s); @@ -2649,8 +2650,15 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) } if (is_xmm && !(s->flags & HF_OSFXSR_MASK)) goto illegal_op; - if (b == 0x77 || b == 0x0e) { - /* emms or femms */ + if (b == 0x0e) { + if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) + goto illegal_op; + /* femms */ + gen_op_emms(); + return; + } + if (b == 0x77) { + /* emms */ gen_op_emms(); return; } @@ -3183,6 +3191,8 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) } switch(b) { case 0x0f: /* 3DNow! data insns */ + if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) + goto illegal_op; val = ldub_code(s->pc++); sse_op2 = sse_op_table5[val]; if (!sse_op2) @@ -6757,6 +6767,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, } dc->cpuid_features = env->cpuid_features; dc->cpuid_ext_features = env->cpuid_ext_features; + dc->cpuid_ext2_features = env->cpuid_ext2_features; #ifdef TARGET_X86_64 dc->lma = (flags >> HF_LMA_SHIFT) & 1; dc->code64 = (flags >> HF_CS64_SHIFT) & 1; -- 2.7.4