diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2004-05-29 11:08:52 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2004-05-29 11:08:52 +0000 |
commit | 023fe10d24acd124d0b7c5c5ac8edd41d6cc08f2 (patch) | |
tree | a8916df0fb3521f53aedf8e695ef312d0c2e7f13 /target-i386/translate.c | |
parent | f66723fab9eab2695a1b3cf15b55ffc2936b6418 (diff) |
fnop FPU exception support (aka FreeBSD FPU probe) - sysenter/sysexit support (untested, not enabled in cpuid)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@869 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386/translate.c')
-rw-r--r-- | target-i386/translate.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/target-i386/translate.c b/target-i386/translate.c index 514399d937..ee4f05ad3e 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2973,6 +2973,11 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) case 0x0a: /* grp d9/2 */ switch(rm) { case 0: /* fnop */ + /* check exceptions (FreeBSD FPU probe) */ + if (s->cc_op != CC_OP_DYNAMIC) + gen_op_set_cc_op(s->cc_op); + gen_op_jmp_im(pc_start - s->cs_base); + gen_op_fwait(); break; default: goto illegal_op; @@ -3881,6 +3886,32 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) case 0x131: /* rdtsc */ gen_op_rdtsc(); break; + case 0x134: /* sysenter */ + if (!s->pe) { + gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); + } else { + if (s->cc_op != CC_OP_DYNAMIC) { + gen_op_set_cc_op(s->cc_op); + s->cc_op = CC_OP_DYNAMIC; + } + gen_op_jmp_im(pc_start - s->cs_base); + gen_op_sysenter(); + gen_eob(s); + } + break; + case 0x135: /* sysexit */ + if (!s->pe) { + gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); + } else { + if (s->cc_op != CC_OP_DYNAMIC) { + gen_op_set_cc_op(s->cc_op); + s->cc_op = CC_OP_DYNAMIC; + } + gen_op_jmp_im(pc_start - s->cs_base); + gen_op_sysexit(); + gen_eob(s); + } + break; case 0x1a2: /* cpuid */ gen_op_cpuid(); break; |