aboutsummaryrefslogtreecommitdiff
path: root/target-i386/op_helper.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-06-18 09:32:32 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-06-18 09:32:32 +0000
commit94451178b6b7d6d08c0f16a5a1b0d03bf978f74b (patch)
treeb794553b91c5562d300e54a1a03c3da6de4b7263 /target-i386/op_helper.c
parent17ca26e7918353ae67fa9cfcbf61e3b90a1b3a6b (diff)
HLT, MWAIT and MONITOR insn fixes (initial patch by Alexander Graf)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4746 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386/op_helper.c')
-rw-r--r--target-i386/op_helper.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 730ec81698..beb568741d 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4547,16 +4547,22 @@ void helper_idivq_EAX(target_ulong t0)
}
#endif
-void helper_hlt(void)
+static void do_hlt(void)
{
- helper_svm_check_intercept_param(SVM_EXIT_HLT, 0);
-
env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
env->halted = 1;
env->exception_index = EXCP_HLT;
cpu_loop_exit();
}
+void helper_hlt(int next_eip_addend)
+{
+ helper_svm_check_intercept_param(SVM_EXIT_HLT, 0);
+ EIP += next_eip_addend;
+
+ do_hlt();
+}
+
void helper_monitor(target_ulong ptr)
{
if ((uint32_t)ECX != 0)
@@ -4565,17 +4571,19 @@ void helper_monitor(target_ulong ptr)
helper_svm_check_intercept_param(SVM_EXIT_MONITOR, 0);
}
-void helper_mwait(void)
+void helper_mwait(int next_eip_addend)
{
if ((uint32_t)ECX != 0)
raise_exception(EXCP0D_GPF);
helper_svm_check_intercept_param(SVM_EXIT_MWAIT, 0);
+ EIP += next_eip_addend;
+
/* XXX: not complete but not completely erroneous */
if (env->cpu_index != 0 || env->next_cpu != NULL) {
/* more than one CPU: do not sleep because another CPU may
wake this one */
} else {
- helper_hlt();
+ do_hlt();
}
}