first self virtualizable version
[qemu] / exec-i386.c
index ec14ca0..dedcbfa 100644 (file)
@@ -87,6 +87,20 @@ static inline int testandset (int *p)
 }
 #endif
 
+#ifdef __s390__
+static inline int testandset (int *p)
+{
+    int ret;
+
+    __asm__ __volatile__ ("0: cs    %0,%1,0(%2)\n"
+                         "   jl    0b"
+                         : "=&d" (ret)
+                         : "r" (1), "a" (p), "0" (*p) 
+                         : "cc", "memory" );
+    return ret;
+}
+#endif
+
 int global_cpu_lock = 0;
 
 void cpu_lock(void)
@@ -330,9 +344,10 @@ int cpu_x86_exec(CPUX86State *env1)
 #endif
     
     /* put eflags in CPU temporary format */
-    T0 = env->eflags;
-    op_movl_eflags_T0();
+    CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+    DF = 1 - (2 * ((env->eflags >> 10) & 1));
     CC_OP = CC_OP_EFLAGS;
+    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
     env->interrupt_request = 0;
     
     /* prepare setjmp context for exception handling */
@@ -354,6 +369,7 @@ int cpu_x86_exec(CPUX86State *env1)
                        (unsigned long)env->seg_cache[R_ES].base |
                        (unsigned long)env->seg_cache[R_SS].base) != 0) << 
                 GEN_FLAG_ADDSEG_SHIFT;
+            flags |= (env->eflags & VM_MASK) >> (17 - GEN_FLAG_VM_SHIFT);
             cs_base = env->seg_cache[R_CS].base;
             pc = cs_base + env->eip;
             tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, 
@@ -390,8 +406,7 @@ int cpu_x86_exec(CPUX86State *env1)
     ret = env->exception_index;
 
     /* restore flags in standard format */
-    op_movl_T0_eflags();
-    env->eflags = T0;
+    env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
 
     /* restore global registers */
 #ifdef reg_EAX
@@ -485,7 +500,11 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
     unsigned long pc;
     sigset_t *pold_set;
     
-    pc = uc->uc_mcontext.gregs[EIP];
+#ifndef REG_EIP
+/* for glibc 2.1 */
+#define REG_EIP EIP
+#endif
+    pc = uc->uc_mcontext.gregs[REG_EIP];
     pold_set = &uc->uc_sigmask;
     return handle_cpu_signal(pc, pold_set);
 #else