From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53118) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a9e5t-0004Mz-OF for qemu-devel@nongnu.org; Thu, 17 Dec 2015 14:20:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a9e5s-0006XI-Ao for qemu-devel@nongnu.org; Thu, 17 Dec 2015 14:20:05 -0500 Received: from mail-qk0-x229.google.com ([2607:f8b0:400d:c09::229]:33676) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a9e5s-0006XD-4f for qemu-devel@nongnu.org; Thu, 17 Dec 2015 14:20:04 -0500 Received: by mail-qk0-x229.google.com with SMTP id k189so102877343qkc.0 for ; Thu, 17 Dec 2015 11:20:04 -0800 (PST) Sender: Richard Henderson From: Richard Henderson Date: Thu, 17 Dec 2015 11:19:21 -0800 Message-Id: <1450379966-28198-6-git-send-email-rth@twiddle.net> In-Reply-To: <1450379966-28198-1-git-send-email-rth@twiddle.net> References: <1450379966-28198-1-git-send-email-rth@twiddle.net> Subject: [Qemu-devel] [PATCH v2 05/10] target-i386: Access segs via TCG registers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, aurelien@aurel32.net, peter.maydell@linaro.org 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. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson --- target-i386/translate.c | 52 ++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index 1e6dccd..b346ca5 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -67,6 +67,7 @@ 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 cpu_seg_base[6]; /* local temps */ static TCGv cpu_T[2]; /* local register indexes (only used inside old micro ops) */ @@ -424,12 +425,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); } } @@ -502,9 +502,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); @@ -515,8 +513,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); } } @@ -2207,12 +2203,10 @@ static inline void gen_op_movl_T0_seg(int 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_ext16u_tl(cpu_T[0], cpu_T[0]); 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_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 @@ -7277,21 +7271,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; @@ -7740,6 +7729,14 @@ 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", + }; int i; cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); @@ -7758,6 +7755,13 @@ void optimize_flags_init(void) 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]); + } + helper_lock_init(); } -- 2.5.0