qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [4514] convert remaining segment handling to TCG


From: Fabrice Bellard
Subject: [Qemu-devel] [4514] convert remaining segment handling to TCG
Date: Wed, 21 May 2008 16:34:07 +0000

Revision: 4514
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4514
Author:   bellard
Date:     2008-05-21 16:34:06 +0000 (Wed, 21 May 2008)

Log Message:
-----------
convert remaining segment handling to TCG

Modified Paths:
--------------
    trunk/target-i386/TODO
    trunk/target-i386/op.c
    trunk/target-i386/translate.c

Modified: trunk/target-i386/TODO
===================================================================
--- trunk/target-i386/TODO      2008-05-21 16:25:27 UTC (rev 4513)
+++ trunk/target-i386/TODO      2008-05-21 16:34:06 UTC (rev 4514)
@@ -4,7 +4,6 @@
 - SVM: rework the implementation: simplify code, move most intercept
   tests as dynamic, correct segment access, verify exception safety,
   cpu save/restore, SMM save/restore. 
-- arpl eflags computation is invalid
 - x86_64: fxsave/fxrestore intel/amd differences
 - x86_64: lcall/ljmp intel/amd differences ?
 - x86_64: cmpxchgl intel/amd differences ?
@@ -32,6 +31,8 @@
 - add VMX support
 - add AVX support
 - add SSE5 support
+- faster EFLAGS update: consider SZAP, C, O can be updated separately
+  with a bit field in CC_OP and more state variables.
 - evaluate x87 stack pointer statically
 - find a way to avoid translating several time the same TB if CR0.TS
   is set or not.

Modified: trunk/target-i386/op.c
===================================================================
--- trunk/target-i386/op.c      2008-05-21 16:25:27 UTC (rev 4513)
+++ trunk/target-i386/op.c      2008-05-21 16:34:06 UTC (rev 4514)
@@ -147,45 +147,6 @@
 
 #endif
 
-/* segment handling */
-
-/* faster VM86 version */
-void OPPROTO op_movl_seg_T0_vm(void)
-{
-    int selector;
-    SegmentCache *sc;
-
-    selector = T0 & 0xffff;
-    /* env->segs[] access */
-    sc = (SegmentCache *)((char *)env + PARAM1);
-    sc->selector = selector;
-    sc->base = (selector << 4);
-}
-
-void OPPROTO op_movl_T0_seg(void)
-{
-    T0 = env->segs[PARAM1].selector;
-}
-
-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;
-}
-
 void OPPROTO op_movl_T0_env(void)
 {
     T0 = *(uint32_t *)((char *)env + PARAM1);

Modified: trunk/target-i386/translate.c
===================================================================
--- trunk/target-i386/translate.c       2008-05-21 16:25:27 UTC (rev 4513)
+++ trunk/target-i386/translate.c       2008-05-21 16:34:06 UTC (rev 4514)
@@ -2167,6 +2167,22 @@
     }
 }
 
+static inline void gen_op_movl_T0_seg(int seg_reg)
+{
+    tcg_gen_ld32u_tl(cpu_T[0], cpu_env, 
+                     offsetof(CPUX86State,segs[seg_reg].selector));
+}
+
+static inline void gen_op_movl_seg_T0_vm(int seg_reg)
+{
+    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
+    tcg_gen_st32_tl(cpu_T[0], cpu_env, 
+                    offsetof(CPUX86State,segs[seg_reg].selector));
+    tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4);
+    tcg_gen_st_tl(cpu_T[0], cpu_env, 
+                  offsetof(CPUX86State,segs[seg_reg].base));
+}
+
 /* move T0 to seg_reg and compute if the CPU state may change. Never
    call this function with seg_reg == R_CS */
 static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
@@ -2185,7 +2201,7 @@
         if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
             s->is_jmp = 3;
     } else {
-        gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg]));
+        gen_op_movl_seg_T0_vm(seg_reg);
         if (seg_reg == R_SS)
             s->is_jmp = 3;
     }
@@ -4085,7 +4101,7 @@
                                    cpu_T[1],
                                    tcg_const_i32(s->pc - pc_start));
             } else {
-                gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
+                gen_op_movl_seg_T0_vm(R_CS);
                 gen_op_movl_T0_T1();
                 gen_op_jmp_T0();
             }
@@ -5575,7 +5591,7 @@
             /* pop selector */
             gen_op_addl_A0_im(2 << s->dflag);
             gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
-            gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
+            gen_op_movl_seg_T0_vm(R_CS);
             /* add stack offset */
             gen_stack_update(s, val + (4 << s->dflag));
         }
@@ -6578,9 +6594,10 @@
         } else
 #endif
         {
+            int label1;
             if (!s->pe || s->vm86)
                 goto illegal_op;
-            ot = dflag ? OT_LONG : OT_WORD;
+            ot = OT_WORD;
             modrm = ldub_code(s->pc++);
             reg = (modrm >> 3) & 7;
             mod = (modrm >> 6) & 3;
@@ -6592,16 +6609,26 @@
                 gen_op_mov_TN_reg(ot, 0, rm);
             }
             gen_op_mov_TN_reg(ot, 1, reg);
-            if (s->cc_op != CC_OP_DYNAMIC)
-                gen_op_set_cc_op(s->cc_op);
-            gen_op_arpl();
-            s->cc_op = CC_OP_EFLAGS;
+            tcg_gen_andi_tl(cpu_tmp0, cpu_T[0], 3);
+            tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 3);
+            tcg_gen_movi_tl(cpu_T3, 0);
+            label1 = gen_new_label();
+            tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, cpu_T[1], label1);
+            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~3);
+            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
+            tcg_gen_movi_tl(cpu_T3, CC_Z);
+            gen_set_label(label1);
             if (mod != 3) {
                 gen_op_st_T0_A0(ot + s->mem_index);
             } else {
                 gen_op_mov_reg_T0(ot, rm);
             }
-            gen_op_arpl_update();
+            if (s->cc_op != CC_OP_DYNAMIC)
+                gen_op_set_cc_op(s->cc_op);
+            gen_compute_eflags(cpu_cc_src);
+            tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
+            tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T3);
+            s->cc_op = CC_OP_EFLAGS;
         }
         break;
     case 0x102: /* lar */






reply via email to

[Prev in Thread] Current Thread [Next in Thread]