summaryrefslogtreecommitdiff
path: root/target-i386/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-i386/translate.c')
-rw-r--r--target-i386/translate.c57
1 files changed, 42 insertions, 15 deletions
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 66aa21bb65..82ee3d50f1 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7206,31 +7206,58 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_eob(s);
}
break;
- case 7: /* invlpg */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+ case 7:
+ if (mod != 3) { /* invlpg */
+ if (s->cpl != 0) {
+ 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);
+ gen_jmp_im(pc_start - s->cs_base);
+ gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
+ gen_helper_invlpg(cpu_A0);
+ gen_jmp_im(s->pc - s->cs_base);
+ gen_eob(s);
+ }
} else {
- if (mod == 3) {
+ switch (rm) {
+ case 0: /* swapgs */
#ifdef TARGET_X86_64
- if (CODE64(s) && rm == 0) {
- /* swapgs */
- tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
- tcg_gen_ld_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,kernelgsbase));
- tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
- tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,kernelgsbase));
+ if (CODE64(s)) {
+ if (s->cpl != 0) {
+ gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+ } else {
+ tcg_gen_ld_tl(cpu_T[0], cpu_env,
+ offsetof(CPUX86State,segs[R_GS].base));
+ tcg_gen_ld_tl(cpu_T[1], cpu_env,
+ offsetof(CPUX86State,kernelgsbase));
+ tcg_gen_st_tl(cpu_T[1], cpu_env,
+ offsetof(CPUX86State,segs[R_GS].base));
+ tcg_gen_st_tl(cpu_T[0], cpu_env,
+ offsetof(CPUX86State,kernelgsbase));
+ }
} else
#endif
{
goto illegal_op;
}
- } else {
+ break;
+ case 1: /* rdtscp */
+ if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
+ goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_helper_invlpg(cpu_A0);
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
+ if (use_icount)
+ gen_io_start();
+ gen_helper_rdtscp();
+ if (use_icount) {
+ gen_io_end();
+ gen_jmp(s, s->pc - s->cs_base);
+ }
+ break;
+ default:
+ goto illegal_op;
}
}
break;