diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-04-09 06:41:37 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-04-09 06:41:37 +0000 |
commit | e771edab0d9aaa7925dc26aec3e0c6eac27f19c3 (patch) | |
tree | 7a556b3653c68fee4235d93774712cb6e63d1a67 /target-i386 | |
parent | 27985df9cc0af41f5d7cac622a7aeb24d3d86cd5 (diff) |
Check for 3DNow! CPUID at translation time
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4184 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/translate.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/target-i386/translate.c b/target-i386/translate.c index 74ad2dc639..e9c65aa300 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; |