From patchwork Sat Jun 4 07:54:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 9154535 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E370D60467 for ; Sat, 4 Jun 2016 07:54:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D3D7827F2B for ; Sat, 4 Jun 2016 07:54:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C88452832B; Sat, 4 Jun 2016 07:54:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 085C527F2B for ; Sat, 4 Jun 2016 07:54:44 +0000 (UTC) Received: from localhost ([::1]:59775 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b96Pr-0002UG-5k for patchwork-qemu-devel@patchwork.kernel.org; Sat, 04 Jun 2016 03:54:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41734) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b96PU-0002Su-Pz for qemu-devel@nongnu.org; Sat, 04 Jun 2016 03:54:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b96PN-0005CH-Hp for qemu-devel@nongnu.org; Sat, 04 Jun 2016 03:54:19 -0400 Received: from mail-pf0-x242.google.com ([2607:f8b0:400e:c00::242]:33561) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b96PN-0005Bq-7H for qemu-devel@nongnu.org; Sat, 04 Jun 2016 03:54:13 -0400 Received: by mail-pf0-x242.google.com with SMTP id b124so13477703pfb.0 for ; Sat, 04 Jun 2016 00:54:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id:in-reply-to:references; bh=/4qSJIaJiYrIfJm9s4/xrDxeFGeU6eWWD+d87dwjJzI=; b=IFb8ZtLfgU/NinlWUIq/5CWJSItgFF9AWQ+8YQYLdJ5H07tXReyxHYVQdKglAfnLGr f/VIEe2PyBfvtRoocyrEcZptDnFy/6JLoiGr9m4B+XR6fxz2GGqM2wBvlkBYBmujIH/s 1qhh4tbO72PbLaq7s6eIXo18KNDrh3jyPzsMC5oXAtsO3Hg9ij+dLb21T2wRvCLRXLsP VC/G3tuy3CDaPPXSC3/z3QE6pTgQ7nXlP+sRbxQaW9i3Hy7Cuq4Wv/l5JO/FEjt39RO3 YF9MMKrefbxvEDmRjfRSxQQOZt/NN7YU0dPbCaemYhtV0YYqBPCRkZVfAMzU/LOmY2u3 Ng9w== 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:subject:date:message-id :in-reply-to:references; bh=/4qSJIaJiYrIfJm9s4/xrDxeFGeU6eWWD+d87dwjJzI=; b=Z3Ur6RjTSaHGgQcIR8lUQYm3di/25wSXlnt62PypwkuF1H++GUPOa4ubTjHUfXlMsr o9TYPFXqBmxnqkufMwgn6xA8uCs1cofAVxxsXPl/yvYMWDjldsljT0a7O/IE2+SBciV7 uxHAIUtFokj0JVl5cdWpvJom7IYOVjkZPcsIVUw7bWMROjtSsqo7Yy/a5G9L/xf4p8P4 5r3ZByUrsOSkTysoUi8eKpeYET+U7hbH43row8OehDCjGdbsNxcV6rekEpOpeiTt8pkg 5gHL0IvauMmK1UPdFHBWIpzb/XG52vKsPKuY67bQtb1dg8ho3/76zRgXGz1XA8rQZRfk p1uA== X-Gm-Message-State: ALyK8tIV3L8xvbhUmPxhj1dRGwNU9/oOhzkluXiiv5DwFrKysX0/jci9/KDMUMqDLZN9jA== X-Received: by 10.98.52.65 with SMTP id b62mr2267117pfa.40.1465026849951; Sat, 04 Jun 2016 00:54:09 -0700 (PDT) Received: from bigtime.twiddle.net (71-37-54-227.tukw.qwest.net. [71.37.54.227]) by smtp.gmail.com with ESMTPSA id h5sm10837028pat.0.2016.06.04.00.54.09 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 04 Jun 2016 00:54:09 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 4 Jun 2016 00:54:06 -0700 Message-Id: <1465026847-6744-2-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1465026847-6744-1-git-send-email-rth@twiddle.net> References: <1465026847-6744-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c00::242 Subject: [Qemu-devel] [PATCH 1/2] tcg/i386: Reserve register for guest_base if a segment isn't available X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This saves 2 insns and 10 bytes from the implementation of each memory operation. Signed-off-by: Richard Henderson --- tcg/i386/tcg-target.inc.c | 143 +++++++++++++++++++++------------------------- 1 file changed, 66 insertions(+), 77 deletions(-) diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c index 317484c..11cbb3c 100644 --- a/tcg/i386/tcg-target.inc.c +++ b/tcg/i386/tcg-target.inc.c @@ -1441,22 +1441,43 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) tcg_out_push(s, retaddr); tcg_out_jmp(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]); } -#elif defined(__x86_64__) && defined(__linux__) -# include -# include - +#elif TCG_TARGET_REG_BITS == 64 +# ifdef __linux__ +# include +# include int arch_prctl(int code, unsigned long addr); +# endif +static int32_t guest_base_ofs; static int guest_base_flags; -static inline void setup_guest_base_seg(void) +static int guest_base_reg = -1; +static void setup_guest_base(TCGContext *s) { + if (guest_base == 0) { + if (TARGET_LONG_BITS == 32) { + guest_base_flags = P_ADDR32; + } + return; + } +# ifdef __linux__ if (arch_prctl(ARCH_SET_GS, guest_base) == 0) { - guest_base_flags = P_GS; + guest_base_flags = (TARGET_LONG_BITS == 32 ? P_GS | P_ADDR32 : P_GS); + return; + } +# endif + if (guest_base == (int32_t)guest_base) { + guest_base_ofs = guest_base; + } else { + guest_base_reg = TCG_REG_EBP; + tcg_regset_set_reg(s->reserved_regs, guest_base_reg); + tcg_out_movi(s, TCG_TYPE_PTR, guest_base_reg, guest_base); } } #else -# define guest_base_flags 0 -static inline void setup_guest_base_seg(void) { } +# define guest_base_flags 0 +# define guest_base_reg -1 +# define guest_base_ofs guest_base +# define setup_guest_base(s) #endif /* SOFTMMU */ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, @@ -1595,42 +1616,26 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) s->code_ptr, label_ptr); #else { - int32_t offset = guest_base; TCGReg base = addrlo; - int index = -1; - int seg = 0; + int flags = guest_base_flags; /* For a 32-bit guest, the high 32 bits may contain garbage. - We can do this with the ADDR32 prefix if we're not using + We do this with the ADDR32 prefix if we're not using a guest base, or when using segmentation. Otherwise we - need to zero-extend manually. */ - if (guest_base == 0 || guest_base_flags) { - seg = guest_base_flags; - offset = 0; - if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { - seg |= P_ADDR32; - } - } else if (TCG_TARGET_REG_BITS == 64) { - if (TARGET_LONG_BITS == 32) { - tcg_out_ext32u(s, TCG_REG_L0, base); - base = TCG_REG_L0; - } - if (offset != guest_base) { - tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L1, guest_base); - index = TCG_REG_L1; - offset = 0; - } + need to zero-extend manually. See setup_guest_base. */ + if (flags == 0 && TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { + tcg_out_ext32u(s, TCG_REG_L0, base); + base = TCG_REG_L0; } - - tcg_out_qemu_ld_direct(s, datalo, datahi, - base, index, offset, seg, opc); + tcg_out_qemu_ld_direct(s, datalo, datahi, base, guest_base_reg, + guest_base_ofs, flags, opc); } #endif } static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, - TCGReg base, intptr_t ofs, int seg, - TCGMemOp memop) + TCGReg base, int index, intptr_t ofs, + int seg, TCGMemOp memop) { /* ??? Ideally we wouldn't need a scratch register. For user-only, we could perform the bswap twice to restore the original value @@ -1654,8 +1659,8 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo); datalo = scratch; } - tcg_out_modrm_offset(s, OPC_MOVB_EvGv + P_REXB_R + seg, - datalo, base, ofs); + tcg_out_modrm_sib_offset(s, OPC_MOVB_EvGv + P_REXB_R + seg, datalo, + base, index, 0, ofs); break; case MO_16: if (bswap) { @@ -1663,7 +1668,8 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, tcg_out_rolw_8(s, scratch); datalo = scratch; } - tcg_out_modrm_offset(s, movop + P_DATA16 + seg, datalo, base, ofs); + tcg_out_modrm_sib_offset(s, movop + P_DATA16 + seg, datalo, + base, index, 0, ofs); break; case MO_32: if (bswap) { @@ -1671,7 +1677,7 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, tcg_out_bswap32(s, scratch); datalo = scratch; } - tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs); + tcg_out_modrm_sib_offset(s, movop + seg, datalo, base, index, 0, ofs); break; case MO_64: if (TCG_TARGET_REG_BITS == 64) { @@ -1680,22 +1686,27 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, tcg_out_bswap64(s, scratch); datalo = scratch; } - tcg_out_modrm_offset(s, movop + P_REXW + seg, datalo, base, ofs); + tcg_out_modrm_sib_offset(s, movop + P_REXW + seg, datalo, + base, index, 0, ofs); } else if (bswap) { tcg_out_mov(s, TCG_TYPE_I32, scratch, datahi); tcg_out_bswap32(s, scratch); - tcg_out_modrm_offset(s, OPC_MOVL_EvGv + seg, scratch, base, ofs); + tcg_out_modrm_sib_offset(s, OPC_MOVL_EvGv + seg, scratch, + base, index, 0, ofs); tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo); tcg_out_bswap32(s, scratch); - tcg_out_modrm_offset(s, OPC_MOVL_EvGv + seg, scratch, base, ofs+4); + tcg_out_modrm_sib_offset(s, OPC_MOVL_EvGv + seg, scratch, + base, index, 0, ofs+4); } else { if (real_bswap) { int t = datalo; datalo = datahi; datahi = t; } - tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs); - tcg_out_modrm_offset(s, movop + seg, datahi, base, ofs+4); + tcg_out_modrm_sib_offset(s, movop + seg, datalo, + base, index, 0, ofs); + tcg_out_modrm_sib_offset(s, movop + seg, datahi, + base, index, 0, ofs+4); } break; default: @@ -1728,43 +1739,23 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) label_ptr, offsetof(CPUTLBEntry, addr_write)); /* TLB Hit. */ - tcg_out_qemu_st_direct(s, datalo, datahi, TCG_REG_L1, 0, 0, opc); + tcg_out_qemu_st_direct(s, datalo, datahi, TCG_REG_L1, -1, 0, 0, opc); /* Record the current context of a store into ldst label */ add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi, s->code_ptr, label_ptr); #else { - int32_t offset = guest_base; TCGReg base = addrlo; - int seg = 0; + int flags = guest_base_flags; /* See comment in tcg_out_qemu_ld re zero-extension of addrlo. */ - if (guest_base == 0 || guest_base_flags) { - seg = guest_base_flags; - offset = 0; - if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { - seg |= P_ADDR32; - } - } else if (TCG_TARGET_REG_BITS == 64) { - /* ??? Note that we can't use the same SIB addressing scheme - as for loads, since we require L0 free for bswap. */ - if (offset != guest_base) { - if (TARGET_LONG_BITS == 32) { - tcg_out_ext32u(s, TCG_REG_L0, base); - base = TCG_REG_L0; - } - tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L1, guest_base); - tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_L1, base); - base = TCG_REG_L1; - offset = 0; - } else if (TARGET_LONG_BITS == 32) { - tcg_out_ext32u(s, TCG_REG_L1, base); - base = TCG_REG_L1; - } + if (flags == 0 && TCG_TARGET_REG_BITS > TARGET_LONG_BITS) { + tcg_out_ext32u(s, TCG_REG_L1, base); + base = TCG_REG_L1; } - - tcg_out_qemu_st_direct(s, datalo, datahi, base, offset, seg, opc); + tcg_out_qemu_st_direct(s, datalo, datahi, base, guest_base_reg, + guest_base_ofs, flags, opc); } #endif } @@ -2326,6 +2317,11 @@ static void tcg_target_qemu_prologue(TCGContext *s) #else tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); tcg_out_addi(s, TCG_REG_ESP, -stack_addend); + +# if !defined(CONFIG_SOFTMMU) + setup_guest_base(s); +# endif + /* jmp *tb. */ tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]); #endif @@ -2339,13 +2335,6 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_out_pop(s, tcg_target_callee_save_regs[i]); } tcg_out_opc(s, OPC_RET, 0, 0, 0); - -#if !defined(CONFIG_SOFTMMU) - /* Try to set up a segment register to point to guest_base. */ - if (guest_base) { - setup_guest_base_seg(); - } -#endif } static void tcg_target_init(TCGContext *s)