qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH v2 45/60] target-i386: Access segs via TCG registers


From: Richard Henderson
Subject: [Qemu-devel] [PATCH v2 45/60] target-i386: Access segs via TCG registers
Date: Fri, 29 Nov 2013 16:00:32 +1300

Having segs[].base as a register significantly improves code
generation for real and protected modes, particularly for TBs
that have multiple memory references where the segment base
can be held in a hard register through the TB.

Signed-off-by: Richard Henderson <address@hidden>
---
 target-i386/translate.c | 71 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 43 insertions(+), 28 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index 5a5c8b6..89e775e 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -65,6 +65,8 @@ static TCGv cpu_A0;
 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT;
 static TCGv_i32 cpu_cc_op;
 static TCGv cpu_regs[CPU_NB_REGS];
+static TCGv_i32 cpu_seg_sel[6];
+static TCGv cpu_seg_base[6];
 /* local temps */
 static TCGv cpu_T[2];
 /* local register indexes (only used inside old micro ops) */
@@ -442,12 +444,11 @@ static inline void gen_op_add_reg_T0(TCGMemOp size, int 
reg)
 
 static inline void gen_op_addl_A0_seg(DisasContext *s, int reg)
 {
-    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));
     if (CODE64(s)) {
         tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
-        tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
+        tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_seg_base[reg]);
     } else {
-        tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
+        tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_seg_base[reg]);
         tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
     }
 }
@@ -519,9 +520,7 @@ static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, 
TCGv a0,
     }
 
     if (ovr_seg >= 0) {
-        TCGv seg = tcg_temp_new();
-
-        tcg_gen_ld_tl(seg, cpu_env, offsetof(CPUX86State, segs[ovr_seg].base));
+        TCGv seg = cpu_seg_base[ovr_seg];
 
         if (aflag == MO_64) {
             tcg_gen_add_tl(cpu_A0, a0, seg);
@@ -532,8 +531,6 @@ static void gen_lea_v_seg(DisasContext *s, TCGMemOp aflag, 
TCGv a0,
             tcg_gen_add_tl(cpu_A0, a0, seg);
             tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
         }
-
-        tcg_temp_free(seg);
     }
 }
 
@@ -2216,18 +2213,14 @@ static void gen_cmovcc1(CPUX86State *env, DisasContext 
*s, TCGMemOp ot, int b,
 
 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));
+    tcg_gen_extu_i32_tl(cpu_T[0], cpu_seg_sel[seg_reg]);
 }
 
 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));
+    tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]);
+    tcg_gen_trunc_tl_i32(cpu_seg_sel[seg_reg], cpu_T[0]);
+    tcg_gen_shli_tl(cpu_seg_base[seg_reg], cpu_T[0], 4);
 }
 
 /* move T0 to seg_reg and compute if the CPU state may change. Never
@@ -7297,21 +7290,16 @@ static target_ulong disas_insn(CPUX86State *env, 
DisasContext *s,
                         if (s->cpl != 0) {
                             gen_exception(s, EXCP0D_GPF, pc_start - 
s->cs_base);
                         } else {
-                            tcg_gen_ld_tl(cpu_T[0], cpu_env,
-                                offsetof(CPUX86State,segs[R_GS].base));
-                            tcg_gen_ld_tl(cpu_T[1], cpu_env,
-                                offsetof(CPUX86State,kernelgsbase));
-                            tcg_gen_st_tl(cpu_T[1], cpu_env,
-                                offsetof(CPUX86State,segs[R_GS].base));
+                            tcg_gen_mov_tl(cpu_T[0], cpu_seg_base[R_GS]);
+                            tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
+                                          offsetof(CPUX86State, kernelgsbase));
                             tcg_gen_st_tl(cpu_T[0], cpu_env,
-                                offsetof(CPUX86State,kernelgsbase));
+                                          offsetof(CPUX86State, kernelgsbase));
                         }
-                    } else
-#endif
-                    {
-                        goto illegal_op;
+                        break;
                     }
-                    break;
+#endif
+                    goto illegal_op;
                 case 1: /* rdtscp */
                     if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
                         goto illegal_op;
@@ -7737,6 +7725,22 @@ void optimize_flags_init(void)
         [R_ESP] = "esp",
 #endif
     };
+    static const char seg_base_names[6][8] = {
+        [R_CS] = "cs_base",
+        [R_DS] = "ds_base",
+        [R_ES] = "es_base",
+        [R_FS] = "fs_base",
+        [R_GS] = "gs_base",
+        [R_SS] = "ss_base",
+    };
+    static const char seg_sel_names[6][8] = {
+        [R_CS] = "cs_sel",
+        [R_DS] = "ds_sel",
+        [R_ES] = "es_sel",
+        [R_FS] = "fs_sel",
+        [R_GS] = "gs_sel",
+        [R_SS] = "ss_sel",
+    };
     int i;
 
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
@@ -7754,6 +7758,17 @@ void optimize_flags_init(void)
                                          offsetof(CPUX86State, regs[i]),
                                          reg_names[i]);
     }
+
+    for (i = 0; i < 6; ++i) {
+        cpu_seg_base[i]
+            = tcg_global_mem_new(TCG_AREG0,
+                                 offsetof(CPUX86State, segs[i].base),
+                                 seg_base_names[i]);
+        cpu_seg_sel[i]
+            = tcg_global_mem_new_i32(TCG_AREG0,
+                                     offsetof(CPUX86State, segs[i].selector),
+                                     seg_sel_names[i]);
+    }
 }
 
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
-- 
1.8.3.1




reply via email to

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