From patchwork Mon Feb 8 17:03:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 580412 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 822D5140213 for ; Tue, 9 Feb 2016 04:16:34 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=aFbb1VHz; dkim-atps=neutral Received: from localhost ([::1]:46963 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aSpQO-0000y1-Ik for incoming@patchwork.ozlabs.org; Mon, 08 Feb 2016 12:16:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43635) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aSpE8-0003iW-88 for qemu-devel@nongnu.org; Mon, 08 Feb 2016 12:03:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aSpE6-0006s8-Na for qemu-devel@nongnu.org; Mon, 08 Feb 2016 12:03:52 -0500 Received: from mail-wm0-x22f.google.com ([2a00:1450:400c:c09::22f]:35478) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aSpE6-0006rq-Cd for qemu-devel@nongnu.org; Mon, 08 Feb 2016 12:03:50 -0500 Received: by mail-wm0-x22f.google.com with SMTP id c200so25254592wme.0 for ; Mon, 08 Feb 2016 09:03:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=0j4TD9zSL6+ZS7MzkVRp3ZMiQ+5PLLkpHowZOLeI4G8=; b=aFbb1VHzp6iK32L89IYkmh4V+oweMW+OMwm2qwV4lV14hl46eo5NXStoiPMnQTBpfE mHWH8Fhxtz+z+1Ul1M3AnpENSKsG92ZamgD/3tZxB+PxUTteBdlK5jOiXIIpR+AO4aSn jsixojf4dQizwiqSm0j+kbxYwjiIrIYA8TIAW8ax3dPJVGhZiOTBjNUgRxvLV/B5S7ew +kLZXTyWVUNchEZxLRXTGWXopouqw2QGgPU6Vtf7DnrUUm/5XuU+cFZXn9XHveX41nRV dPbcv54HGf6r0rWSuIQXNSeBn+XH81fE+EDfB0MUPm3b5IRdPZvpRviTmQ1Or5N8qvcD cl1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=0j4TD9zSL6+ZS7MzkVRp3ZMiQ+5PLLkpHowZOLeI4G8=; b=jyMUZUsBxsuWDA6kwapFXrwB3BJSUZEMngw/OxBA07IQGXtLrxH9NRzOqZFb6zzkH3 zKf2c2/12r0xYZATyXjp356vsxiNw8N5Zzo+/dXmkt695+OPcA+XfymeLYP1paxMXUSB fovWyDqKoGuhJDyKI5HeMcnsZAgbR5Hzcx4ojI1WeqMdqhH6AzH2Gaqm66qsGXlBrTRw MBb6GByPg24vKMWVGNL1aMg9GEv0YQjhrBhMkGf8mmxGX26h+H3eKtkkn+NS7WWPe/Pu lQ4M6Rs09ozxlclytQUitX1Xhnu93spOIY/7KBc0jhzEPeqrc5eT2KpKK5RR3UlbZFRK 6N4w== X-Gm-Message-State: AG10YOSqyrEo5+9FrXXz1zvF+SBkcQx0HJKouA9Mhmtf8RuQzs1BXJzeH2aYmsK1QWrxnQ== X-Received: by 10.194.202.135 with SMTP id ki7mr33134060wjc.81.1454951029714; Mon, 08 Feb 2016 09:03:49 -0800 (PST) Received: from 640k.lan (94-39-141-130.adsl-ull.clienti.tiscali.it. [94.39.141.130]) by smtp.gmail.com with ESMTPSA id b1sm30651442wjy.0.2016.02.08.09.03.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 08 Feb 2016 09:03:49 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 8 Feb 2016 18:03:13 +0100 Message-Id: <1454950999-64128-23-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1454950999-64128-1-git-send-email-pbonzini@redhat.com> References: <1454950999-64128-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::22f Cc: Richard Henderson Subject: [Qemu-devel] [PULL 22/28] target-i386: Rewrite gen_enter inline X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Richard Henderson Use gen_lea_v_seg for centralized segment base knowledge. Unify code across 32- and 64-bit. Fix note about "must save state" before using the out-of-line helpers. Signed-off-by: Richard Henderson Message-Id: <1450379966-28198-8-git-send-email-rth@twiddle.net> Signed-off-by: Paolo Bonzini --- target-i386/helper.h | 4 --- target-i386/seg_helper.c | 74 -------------------------------------- target-i386/translate.c | 93 ++++++++++++++++++------------------------------ 3 files changed, 34 insertions(+), 137 deletions(-) diff --git a/target-i386/helper.h b/target-i386/helper.h index ecfcfd1..3a25c3b 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -44,10 +44,6 @@ DEF_HELPER_FLAGS_3(set_dr, TCG_CALL_NO_WG, void, env, int, tl) DEF_HELPER_FLAGS_2(get_dr, TCG_CALL_NO_WG, tl, env, int) DEF_HELPER_2(invlpg, void, env, tl) -DEF_HELPER_4(enter_level, void, env, int, int, tl) -#ifdef TARGET_X86_64 -DEF_HELPER_4(enter64_level, void, env, int, int, tl) -#endif DEF_HELPER_1(sysenter, void, env) DEF_HELPER_2(sysexit, void, env, int) #ifdef TARGET_X86_64 diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index 4f26941..b5f3d72 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -1379,80 +1379,6 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request) return ret; } -void helper_enter_level(CPUX86State *env, int level, int data32, - target_ulong t1) -{ - target_ulong ssp; - uint32_t esp_mask, esp, ebp; - - esp_mask = get_sp_mask(env->segs[R_SS].flags); - ssp = env->segs[R_SS].base; - ebp = env->regs[R_EBP]; - esp = env->regs[R_ESP]; - if (data32) { - /* 32 bit */ - esp -= 4; - while (--level) { - esp -= 4; - ebp -= 4; - cpu_stl_data_ra(env, ssp + (esp & esp_mask), - cpu_ldl_data_ra(env, ssp + (ebp & esp_mask), - GETPC()), - GETPC()); - } - esp -= 4; - cpu_stl_data_ra(env, ssp + (esp & esp_mask), t1, GETPC()); - } else { - /* 16 bit */ - esp -= 2; - while (--level) { - esp -= 2; - ebp -= 2; - cpu_stw_data_ra(env, ssp + (esp & esp_mask), - cpu_lduw_data_ra(env, ssp + (ebp & esp_mask), - GETPC()), - GETPC()); - } - esp -= 2; - cpu_stw_data_ra(env, ssp + (esp & esp_mask), t1, GETPC()); - } -} - -#ifdef TARGET_X86_64 -void helper_enter64_level(CPUX86State *env, int level, int data64, - target_ulong t1) -{ - target_ulong esp, ebp; - - ebp = env->regs[R_EBP]; - esp = env->regs[R_ESP]; - - if (data64) { - /* 64 bit */ - esp -= 8; - while (--level) { - esp -= 8; - ebp -= 8; - cpu_stq_data_ra(env, esp, cpu_ldq_data_ra(env, ebp, GETPC()), - GETPC()); - } - esp -= 8; - cpu_stq_data_ra(env, esp, t1, GETPC()); - } else { - /* 16 bit */ - esp -= 2; - while (--level) { - esp -= 2; - ebp -= 2; - cpu_stw_data_ra(env, esp, cpu_lduw_data_ra(env, ebp, GETPC()), - GETPC()); - } - esp -= 2; - cpu_stw_data_ra(env, esp, t1, GETPC()); - } -} -#endif - void helper_lldt(CPUX86State *env, int selector) { SegmentCache *dt; diff --git a/target-i386/translate.c b/target-i386/translate.c index 78168aa..b2f8790 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -373,11 +373,6 @@ static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg) } } -static inline void gen_op_movl_A0_reg(int reg) -{ - tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]); -} - static inline void gen_op_addl_A0_im(int32_t val) { tcg_gen_addi_tl(cpu_A0, cpu_A0, val); @@ -420,17 +415,6 @@ static inline void gen_op_add_reg_T0(TCGMemOp size, int reg) gen_op_mov_reg_v(size, reg, cpu_tmp0); } -static inline void gen_op_addl_A0_seg(DisasContext *s, int reg) -{ - if (CODE64(s)) { - tcg_gen_ext32u_tl(cpu_A0, cpu_A0); - tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_seg_base[reg]); - } else { - tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_seg_base[reg]); - tcg_gen_ext32u_tl(cpu_A0, cpu_A0); - } -} - static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0) { tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE); @@ -2337,51 +2321,42 @@ static void gen_popa(DisasContext *s) static void gen_enter(DisasContext *s, int esp_addend, int level) { - TCGMemOp ot = mo_pushpop(s, s->dflag); - int opsize = 1 << ot; + TCGMemOp d_ot = mo_pushpop(s, s->dflag); + TCGMemOp a_ot = CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16; + int size = 1 << d_ot; - level &= 0x1f; -#ifdef TARGET_X86_64 - if (CODE64(s)) { - gen_op_movl_A0_reg(R_ESP); - gen_op_addq_A0_im(-opsize); - tcg_gen_mov_tl(cpu_T[1], cpu_A0); - - /* push bp */ - gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP); - gen_op_st_v(s, ot, cpu_T[0], cpu_A0); - if (level) { - /* XXX: must save state */ - gen_helper_enter64_level(cpu_env, tcg_const_i32(level), - tcg_const_i32((ot == MO_64)), - cpu_T[1]); - } - gen_op_mov_reg_v(ot, R_EBP, cpu_T[1]); - tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level)); - gen_op_mov_reg_v(MO_64, R_ESP, cpu_T[1]); - } else -#endif - { - gen_op_movl_A0_reg(R_ESP); - gen_op_addl_A0_im(-opsize); - if (!s->ss32) - tcg_gen_ext16u_tl(cpu_A0, cpu_A0); - tcg_gen_mov_tl(cpu_T[1], cpu_A0); - if (s->addseg) - gen_op_addl_A0_seg(s, R_SS); - /* push bp */ - gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP); - gen_op_st_v(s, ot, cpu_T[0], cpu_A0); - if (level) { - /* XXX: must save state */ - gen_helper_enter_level(cpu_env, tcg_const_i32(level), - tcg_const_i32(s->dflag - 1), - cpu_T[1]); - } - gen_op_mov_reg_v(ot, R_EBP, cpu_T[1]); - tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level)); - gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]); + /* Push BP; compute FrameTemp into T1. */ + tcg_gen_subi_tl(cpu_T[1], cpu_regs[R_ESP], size); + gen_lea_v_seg(s, a_ot, cpu_T[1], R_SS, -1); + gen_op_st_v(s, d_ot, cpu_regs[R_EBP], cpu_A0); + + level &= 31; + if (level != 0) { + int i; + + /* Copy level-1 pointers from the previous frame. */ + for (i = 1; i < level; ++i) { + tcg_gen_subi_tl(cpu_A0, cpu_regs[R_EBP], size * i); + gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1); + gen_op_ld_v(s, d_ot, cpu_tmp0, cpu_A0); + + tcg_gen_subi_tl(cpu_A0, cpu_T[1], size * i); + gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1); + gen_op_st_v(s, d_ot, cpu_tmp0, cpu_A0); + } + + /* Push the current FrameTemp as the last level. */ + tcg_gen_subi_tl(cpu_A0, cpu_T[1], size * level); + gen_lea_v_seg(s, a_ot, cpu_A0, R_SS, -1); + gen_op_st_v(s, d_ot, cpu_T[1], cpu_A0); } + + /* Copy the FrameTemp value to EBP. */ + gen_op_mov_reg_v(a_ot, R_EBP, cpu_T[1]); + + /* Compute the final value of ESP. */ + tcg_gen_subi_tl(cpu_T[1], cpu_T[1], esp_addend + size * level); + gen_op_mov_reg_v(a_ot, R_ESP, cpu_T[1]); } static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)