]> git.proxmox.com Git - qemu.git/blobdiff - target-i386/op.c
P4 style multiplication eflags
[qemu.git] / target-i386 / op.c
index f1276f7a6430cebd955a912219e28b6584ee1b4c..5423be5a3a6f7dd0989d29fe1c4658e62cfee641 100644 (file)
@@ -169,11 +169,16 @@ void OPPROTO op_bswapl_T0(void)
 }
 
 /* multiply/divide */
+
+/* XXX: add eflags optimizations */
+/* XXX: add non P4 style flags */
+
 void OPPROTO op_mulb_AL_T0(void)
 {
     unsigned int res;
     res = (uint8_t)EAX * (uint8_t)T0;
     EAX = (EAX & 0xffff0000) | res;
+    CC_DST = res;
     CC_SRC = (res & 0xff00);
 }
 
@@ -182,6 +187,7 @@ void OPPROTO op_imulb_AL_T0(void)
     int res;
     res = (int8_t)EAX * (int8_t)T0;
     EAX = (EAX & 0xffff0000) | (res & 0xffff);
+    CC_DST = res;
     CC_SRC = (res != (int8_t)res);
 }
 
@@ -191,6 +197,7 @@ void OPPROTO op_mulw_AX_T0(void)
     res = (uint16_t)EAX * (uint16_t)T0;
     EAX = (EAX & 0xffff0000) | (res & 0xffff);
     EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
+    CC_DST = res;
     CC_SRC = res >> 16;
 }
 
@@ -200,6 +207,7 @@ void OPPROTO op_imulw_AX_T0(void)
     res = (int16_t)EAX * (int16_t)T0;
     EAX = (EAX & 0xffff0000) | (res & 0xffff);
     EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
+    CC_DST = res;
     CC_SRC = (res != (int16_t)res);
 }
 
@@ -209,6 +217,7 @@ void OPPROTO op_mull_EAX_T0(void)
     res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);
     EAX = res;
     EDX = res >> 32;
+    CC_DST = res;
     CC_SRC = res >> 32;
 }
 
@@ -218,6 +227,7 @@ void OPPROTO op_imull_EAX_T0(void)
     res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);
     EAX = res;
     EDX = res >> 32;
+    CC_DST = res;
     CC_SRC = (res != (int32_t)res);
 }
 
@@ -226,6 +236,7 @@ void OPPROTO op_imulw_T0_T1(void)
     int res;
     res = (int16_t)T0 * (int16_t)T1;
     T0 = res;
+    CC_DST = res;
     CC_SRC = (res != (int16_t)res);
 }
 
@@ -234,6 +245,7 @@ void OPPROTO op_imull_T0_T1(void)
     int64_t res;
     res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
     T0 = res;
+    CC_DST = res;
     CC_SRC = (res != (int32_t)res);
 }
 
@@ -936,6 +948,35 @@ void OPPROTO op_lar(void)
     helper_lar();
 }
 
+void OPPROTO op_verr(void)
+{
+    helper_verr();
+}
+
+void OPPROTO op_verw(void)
+{
+    helper_verw();
+}
+
+void OPPROTO op_arpl(void)
+{
+    if ((T0 & 3) < (T1 & 3)) {
+        /* XXX: emulate bug or 0xff3f0000 oring as in bochs ? */
+        T0 = (T0 & ~3) | (T1 & 3);
+        T1 = CC_Z;
+   } else {
+        T1 = 0;
+    }
+    FORCE_RET();
+}
+            
+void OPPROTO op_arpl_update(void)
+{
+    int eflags;
+    eflags = cc_table[CC_OP].compute_all();
+    CC_SRC = (eflags & ~CC_Z) | T1;
+}
+    
 /* T0: segment, T1:eip */
 void OPPROTO op_ljmp_protected_T0_T1(void)
 {
@@ -1109,38 +1150,36 @@ void OPPROTO op_set_cc_op(void)
     CC_OP = PARAM1;
 }
 
-#define FL_UPDATE_MASK16 (FL_UPDATE_MASK32 & 0xffff)
+/* XXX: clear VIF/VIP in all ops ? */
 
 void OPPROTO op_movl_eflags_T0(void)
 {
-    int eflags;
-    eflags = T0;
-    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);
+    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK));
 }
 
 void OPPROTO op_movw_eflags_T0(void)
 {
-    int eflags;
-    eflags = T0;
-    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);
+    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK) & 0xffff);
+}
+
+void OPPROTO op_movl_eflags_T0_io(void)
+{
+    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | IF_MASK));
+}
+
+void OPPROTO op_movw_eflags_T0_io(void)
+{
+    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | IF_MASK) & 0xffff);
 }
 
 void OPPROTO op_movl_eflags_T0_cpl0(void)
 {
-    load_eflags(T0, FL_UPDATE_CPL0_MASK);
+    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK));
 }
 
 void OPPROTO op_movw_eflags_T0_cpl0(void)
 {
-    load_eflags(T0, FL_UPDATE_CPL0_MASK & 0xffff);
+    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK) & 0xffff);
 }
 
 #if 0
@@ -1266,31 +1305,14 @@ static int compute_c_eflags(void)
     return CC_SRC & CC_C;
 }
 
-static int compute_c_mul(void)
-{
-    int cf;
-    cf = (CC_SRC != 0);
-    return cf;
-}
-
-static int compute_all_mul(void)
-{
-    int cf, pf, af, zf, sf, of;
-    cf = (CC_SRC != 0);
-    pf = 0; /* undefined */
-    af = 0; /* undefined */
-    zf = 0; /* undefined */
-    sf = 0; /* undefined */
-    of = cf << 11;
-    return cf | pf | af | zf | sf | of;
-}
-    
 CCTable cc_table[CC_OP_NB] = {
     [CC_OP_DYNAMIC] = { /* should never happen */ },
 
     [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags },
 
-    [CC_OP_MUL] = { compute_all_mul, compute_c_mul },
+    [CC_OP_MULB] = { compute_all_mulb, compute_c_mull },
+    [CC_OP_MULW] = { compute_all_mulw, compute_c_mull },
+    [CC_OP_MULL] = { compute_all_mull, compute_c_mull },
 
     [CC_OP_ADDB] = { compute_all_addb, compute_c_addb },
     [CC_OP_ADDW] = { compute_all_addw, compute_c_addw  },
@@ -1747,6 +1769,14 @@ void OPPROTO op_fucomi_ST0_FT0(void)
     FORCE_RET();
 }
 
+void OPPROTO op_fcmov_ST0_STN_T0(void)
+{
+    if (T0) {
+        ST0 = ST(PARAM1);
+    }
+    FORCE_RET();
+}
+
 void OPPROTO op_fadd_ST0_FT0(void)
 {
     ST0 += FT0;
@@ -1866,7 +1896,7 @@ void OPPROTO op_fldz_ST0(void)
 
 void OPPROTO op_fldz_FT0(void)
 {
-    ST0 = f15rk[0];
+    FT0 = f15rk[0];
 }
 
 /* associated heplers to reduce generated code length and to simplify