]> git.proxmox.com Git - qemu.git/blobdiff - op-i386.c
first step to fix precise eflags update in case of exception
[qemu.git] / op-i386.c
index 5836b1a1c30b10398fcba4791097b6d06699124c..a7e057bddc03a46100140599ffacb35571b241e2 100644 (file)
--- a/op-i386.c
+++ b/op-i386.c
@@ -80,62 +80,34 @@ static inline int lshift(int x, int n)
 
 /* operations with flags */
 
-void OPPROTO op_addl_T0_T1_cc(void)
+/* update flags with T0 and T1 (add/sub case) */
+void OPPROTO op_update2_cc(void)
 {
-    CC_SRC = T0;
-    T0 += T1;
+    CC_SRC = T1;
     CC_DST = T0;
 }
 
-void OPPROTO op_orl_T0_T1_cc(void)
+/* update flags with T0 (logic operation case) */
+void OPPROTO op_update1_cc(void)
 {
-    T0 |= T1;
     CC_DST = T0;
 }
 
-void OPPROTO op_andl_T0_T1_cc(void)
+void OPPROTO op_update_neg_cc(void)
 {
-    T0 &= T1;
-    CC_DST = T0;
-}
-
-void OPPROTO op_subl_T0_T1_cc(void)
-{
-    CC_SRC = T0;
-    T0 -= T1;
-    CC_DST = T0;
-}
-
-void OPPROTO op_xorl_T0_T1_cc(void)
-{
-    T0 ^= T1;
+    CC_SRC = -T0;
     CC_DST = T0;
 }
 
 void OPPROTO op_cmpl_T0_T1_cc(void)
 {
-    CC_SRC = T0;
+    CC_SRC = T1;
     CC_DST = T0 - T1;
 }
 
-void OPPROTO op_negl_T0_cc(void)
-{
-    CC_SRC = 0;
-    T0 = -T0;
-    CC_DST = T0;
-}
-
-void OPPROTO op_incl_T0_cc(void)
-{
-    CC_SRC = cc_table[CC_OP].compute_c();
-    T0++;
-    CC_DST = T0;
-}
-
-void OPPROTO op_decl_T0_cc(void)
+void OPPROTO op_update_inc_cc(void)
 {
     CC_SRC = cc_table[CC_OP].compute_c();
-    T0--;
     CC_DST = T0;
 }
 
@@ -493,6 +465,12 @@ void OPPROTO op_jmp_im(void)
     EIP = PARAM1;
 }
 
+void OPPROTO op_hlt(void)
+{
+    env->exception_index = EXCP_HLT;
+    cpu_loop_exit();
+}
+
 void OPPROTO op_raise_interrupt(void)
 {
     int intno;
@@ -954,6 +932,11 @@ void OPPROTO op_ljmp_T0_T1(void)
     jmp_seg(T0 & 0xffff, T1);
 }
 
+void OPPROTO op_iret_protected(void)
+{
+    helper_iret_protected(PARAM1);
+}
+
 void OPPROTO op_lldt_T0(void)
 {
     helper_lldt_T0();
@@ -983,6 +966,11 @@ void OPPROTO op_lmsw_T0(void)
     helper_movl_crN_T0(0);
 }
 
+void OPPROTO op_invlpg_A0(void)
+{
+    helper_invlpg(A0);
+}
+
 void OPPROTO op_movl_T0_env(void)
 {
     T0 = *(uint32_t *)((char *)env + PARAM1);
@@ -1082,8 +1070,7 @@ void OPPROTO op_set_cc_op(void)
     CC_OP = PARAM1;
 }
 
-#define FL_UPDATE_MASK32 (TF_MASK | AC_MASK | ID_MASK)
-#define FL_UPDATE_MASK16 (TF_MASK)
+#define FL_UPDATE_MASK16 (FL_UPDATE_MASK32 & 0xffff)
 
 void OPPROTO op_movl_eflags_T0(void)
 {
@@ -1092,7 +1079,8 @@ void OPPROTO op_movl_eflags_T0(void)
     CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     DF = 1 - (2 * ((eflags >> 10) & 1));
     /* we also update some system flags as in user mode */
-    env->eflags = (env->eflags & ~FL_UPDATE_MASK32) | (eflags & FL_UPDATE_MASK32);
+    env->eflags = (env->eflags & ~FL_UPDATE_MASK32) | 
+        (eflags & FL_UPDATE_MASK32);
 }
 
 void OPPROTO op_movw_eflags_T0(void)
@@ -1102,7 +1090,18 @@ void OPPROTO op_movw_eflags_T0(void)
     CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     DF = 1 - (2 * ((eflags >> 10) & 1));
     /* we also update some system flags as in user mode */
-    env->eflags = (env->eflags & ~FL_UPDATE_MASK16) | (eflags & FL_UPDATE_MASK16);
+    env->eflags = (env->eflags & ~FL_UPDATE_MASK16) | 
+        (eflags & FL_UPDATE_MASK16);
+}
+
+void OPPROTO op_movl_eflags_T0_cpl0(void)
+{
+    load_eflags(T0, FL_UPDATE_CPL0_MASK);
+}
+
+void OPPROTO op_movw_eflags_T0_cpl0(void)
+{
+    load_eflags(T0, FL_UPDATE_CPL0_MASK & 0xffff);
 }
 
 #if 0