Patchwork [for-1.8,43/61] target-i386: Use gen_lea_v_seg in gen_lea_modrm

login
register
mail settings
Submitter Richard Henderson
Date Nov. 7, 2013, 1:05 a.m.
Message ID <1383786324-18415-44-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/289145/
State New
Headers show

Comments

Richard Henderson - Nov. 7, 2013, 1:05 a.m.
Centralize handling of segment bases.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-i386/translate.c | 82 +++++++++++++------------------------------------
 1 file changed, 22 insertions(+), 60 deletions(-)

Patch

diff --git a/target-i386/translate.c b/target-i386/translate.c
index b588eb9..ec2716d 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -1860,17 +1860,12 @@  static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
 {
     target_long disp;
-    int havesib;
-    int base;
-    int index;
-    int scale;
-    int mod, rm, code, override, must_add_seg;
+    int havesib, base, index, scale;
+    int mod, rm, code, def_seg, ovr_seg;
     TCGv sum;
 
-    override = s->override;
-    must_add_seg = s->addseg;
-    if (override >= 0)
-        must_add_seg = 1;
+    def_seg = R_DS;
+    ovr_seg = s->override;
     mod = (modrm >> 6) & 3;
     rm = modrm & 7;
 
@@ -1942,61 +1937,34 @@  static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
         }
         if (TCGV_IS_UNUSED(sum)) {
             tcg_gen_movi_tl(cpu_A0, disp);
-        } else {
+            sum = cpu_A0;
+        } else if (disp != 0) {
             tcg_gen_addi_tl(cpu_A0, sum, disp);
+            sum = cpu_A0;
         }
 
-        if (must_add_seg) {
-            if (override < 0) {
-                if (base == R_EBP || base == R_ESP) {
-                    override = R_SS;
-                } else {
-                    override = R_DS;
-                }
-            }
-
-            tcg_gen_ld_tl(cpu_tmp0, cpu_env,
-                          offsetof(CPUX86State, segs[override].base));
-            if (CODE64(s)) {
-                if (s->aflag == MO_32) {
-                    tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
-                }
-                tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
-                break;
-            }
-
-            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
-        }
-
-        if (s->aflag == MO_32) {
-            tcg_gen_ext32u_tl(cpu_A0, cpu_A0);
+        if (base == R_EBP || base == R_ESP) {
+            def_seg = R_SS;
         }
         break;
 
     case MO_16:
-        switch (mod) {
-        case 0:
+        sum = cpu_A0;
+        if (mod == 0) {
             if (rm == 6) {
                 disp = cpu_lduw_code(env, s->pc);
                 s->pc += 2;
                 tcg_gen_movi_tl(cpu_A0, disp);
-                rm = 0; /* avoid SS override */
-                goto no_rm;
-            } else {
-                disp = 0;
+                break;
             }
-            break;
-        case 1:
+            disp = 0;
+        } else if (mod == 1) {
             disp = (int8_t)cpu_ldub_code(env, s->pc++);
-            break;
-        default:
-        case 2:
+        } else {
             disp = (int16_t)cpu_lduw_code(env, s->pc);
             s->pc += 2;
-            break;
         }
 
-        sum = cpu_A0;
         switch (rm) {
         case 0:
             tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBX], cpu_regs[R_ESI]);
@@ -2006,9 +1974,11 @@  static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
             break;
         case 2:
             tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBP], cpu_regs[R_ESI]);
+            def_seg = R_SS;
             break;
         case 3:
             tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBP], cpu_regs[R_EDI]);
+            def_seg = R_SS;
             break;
         case 4:
             sum = cpu_regs[R_ESI];
@@ -2018,24 +1988,16 @@  static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
             break;
         case 6:
             sum = cpu_regs[R_EBP];
+            def_seg = R_SS;
             break;
         default:
         case 7:
             sum = cpu_regs[R_EBX];
             break;
         }
-        tcg_gen_addi_tl(cpu_A0, sum, disp);
-        tcg_gen_ext16u_tl(cpu_A0, cpu_A0);
-    no_rm:
-        if (must_add_seg) {
-            if (override < 0) {
-                if (rm == 2 || rm == 3 || rm == 6) {
-                    override = R_SS;
-                } else {
-                    override = R_DS;
-                }
-            }
-            gen_op_addl_A0_seg(s, override);
+        if (disp != 0) {
+            tcg_gen_addi_tl(cpu_A0, sum, disp);
+            sum = cpu_A0;
         }
         break;
 
@@ -2043,7 +2005,7 @@  static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
         tcg_abort();
     }
 
-    disp = 0;
+    gen_lea_v_seg(s, sum, def_seg, ovr_seg);
 }
 
 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)