From patchwork Fri Nov 23 14:45:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 151912 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp2248975ljp; Fri, 23 Nov 2018 07:18:21 -0800 (PST) X-Google-Smtp-Source: AFSGD/V2TkTS7Cy0w9fHx70dxnJJ10tnlqSSh7j6WBp0Oaer2jA/ZLArTAUQZkqT59LhJ/BhQJjy X-Received: by 2002:a81:e40b:: with SMTP id r11mr7370305ywl.56.1542986301330; Fri, 23 Nov 2018 07:18:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542986301; cv=none; d=google.com; s=arc-20160816; b=tqA/A9cd/gLOor537QvByCT82RDoStE0+PF65WbeGtN1NCwy8D8LuaZtEyUKSj60eX F6dyIGza6tgg8uiwzn7SjRe5b5SiimFaXxN+61J+8vJJ0YmetbNhLFBGr1VJXOi0oaOy eKt4/io6ApkS6/dUYbjvEmU4poo98sgAmqqIu0j7jhkC3BoEub9fHF5wTwfI77+Bs1L/ tBVGa/ivJoIwqv1dRtpRiGqW1RQBSdrtRVKv9ZjT/faYQdgwW1ZlgufoZqK6xvsGCAjp 7Qv81NZ/aXah7UUOSdP2zBUC4EksfdDaTtQKk/2NuT9iwliTOmd/4X2GRG7261JEIRjH p4ug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=HTYkvsG0udVGuawIRsgNi33ekLoZkN1Kc95kEWex73U=; b=kFJKyKjwQyeyewd6WeLnHLdPXAMX7WTfNwP8PHg51hG0YqviEJKrnvgL6giV4BUXmf S8PCN1bpy3V+X0WUyI7CJKKga7ed2KMWjcS6KFF9l8XUbbah0MJDHfEUuBqR12oXoI0y X2XehAFi8IXJuJZNUkbZOTDkHVGDcD5L3IxSiVMJQg5pJW9+t29YyiRfoCOe7KdTS5c6 G4uNdUvxxEvAFdcGeq1v9PyS5/vex8HgjUhfvPNOAJj9IY/u6Xs6INYkxAWzaySskHDi KRrem5rqHcP499GFjT77UYJMDu6ZCouH+2IDfZ4QIaU6fvAk+Z6qHuycAwzW7LhNfzvr L6Yw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Jv5aw1gX; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id q128-v6si34124448ywb.131.2018.11.23.07.18.21 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 23 Nov 2018 07:18:21 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Jv5aw1gX; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52943 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gQDDo-0005qT-Mv for patch@linaro.org; Fri, 23 Nov 2018 10:18:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44265) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gQCj5-0000Hg-FT for qemu-devel@nongnu.org; Fri, 23 Nov 2018 09:46:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gQCj3-0003jw-KT for qemu-devel@nongnu.org; Fri, 23 Nov 2018 09:46:35 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:46584) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gQCj3-0003hc-Ae for qemu-devel@nongnu.org; Fri, 23 Nov 2018 09:46:33 -0500 Received: by mail-wr1-x442.google.com with SMTP id l9so12571118wrt.13 for ; Fri, 23 Nov 2018 06:46:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=HTYkvsG0udVGuawIRsgNi33ekLoZkN1Kc95kEWex73U=; b=Jv5aw1gXrYHa5lX61lUpc5KKKXaM2RHbriAPo8nuCEwOjAOlNcECbf1i0quYntI08W MXNDmM5SWk/C1O9t1hxlImNKeUJaR/dR+5UnF8anhQgKlP5FyeNt3PVkZ38yl2vwhV57 FG5ZDF1Fvp+u3yMgoHDrzTpBtfhuSsq6lR//k= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=HTYkvsG0udVGuawIRsgNi33ekLoZkN1Kc95kEWex73U=; b=ZdewyK7zEeW7Gsz5FQPmHKNsyQWGIiBAAZwfNHJsTlJq6YuvXrXBPkNE0cE+pbP3Bv Y8pKCrPBUMSehUXOK1jeT3JuOhsGp8hJJIg+HbPYksHKKGOPvUrHQ/EjysOHAFYaqGab s37IrlBd8IAmwnEX0Q1nW0SPp4viwUTMIjxX8HzsOdHEUvEitLJEI4YH8cSxBZWRB+zI 4Jb/sMgixbAU/gZwHhAlMg/MLuAxq4pQg7sb7xJ75cyyK8lfDUxxo1euvh/adTugyKls RH61PqzQ5OtNlMjJ/WvuKZl+YP6uY68vFkNfMAVJ7w6sqZ2Z1w7zoFWQ6Yy3x1zDalJR duhQ== X-Gm-Message-State: AA+aEWZ9z9A4EqZlpxtOu15oHgH6V8vB6S4FwdX0dE9RVavavS+Kt5Ij 2TS19CmLDm8y19iVCUvsvUCMX9NL9UfM0Q== X-Received: by 2002:adf:81b6:: with SMTP id 51mr15186676wra.240.1542984391256; Fri, 23 Nov 2018 06:46:31 -0800 (PST) Received: from cloudburst.twiddle.net ([195.77.246.50]) by smtp.gmail.com with ESMTPSA id p74sm10339630wmd.29.2018.11.23.06.46.30 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 23 Nov 2018 06:46:30 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 23 Nov 2018 15:45:53 +0100 Message-Id: <20181123144558.5048-33-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181123144558.5048-1-richard.henderson@linaro.org> References: <20181123144558.5048-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::442 Subject: [Qemu-devel] [PATCH for-4.0 v2 32/37] tcg/arm: Set TCG_TARGET_HAS_MEMORY_BSWAP to false for user-only 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: , Cc: Alistair.Francis@wdc.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Letting the generic code emit any bswaps allows us to avoid reserving an extra register for CONFIG_USER_ONLY. For SOFTMMU, where we have free call-clobbered registers anyway, leaving the bswap in the out-of-line thunk maximizes code sharing. Signed-off-by: Richard Henderson --- tcg/arm/tcg-target.h | 4 ++ tcg/arm/tcg-target.inc.c | 129 +++++++++++++-------------------------- 2 files changed, 48 insertions(+), 85 deletions(-) -- 2.17.2 diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index 7a4c55d66d..a05310a684 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -131,7 +131,11 @@ enum { }; #define TCG_TARGET_DEFAULT_MO (0) +#ifdef CONFIG_SOFTMMU #define TCG_TARGET_HAS_MEMORY_BSWAP 1 +#else +#define TCG_TARGET_HAS_MEMORY_BSWAP 0 +#endif static inline void flush_icache_range(uintptr_t start, uintptr_t stop) { diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c index 5a15f6a546..898701f105 100644 --- a/tcg/arm/tcg-target.inc.c +++ b/tcg/arm/tcg-target.inc.c @@ -270,15 +270,6 @@ static const char *target_parse_constraint(TCGArgConstraint *ct, ct->u.regs = 0xffff; break; - /* qemu_st address & data */ - case 's': - ct->ct |= TCG_CT_REG; - ct->u.regs = 0xffff; - /* r0-r1 doing the byte swapping, so don't use these */ - tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0); - tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1); - break; - default: return NULL; } @@ -1363,6 +1354,7 @@ static inline void tcg_out_qemu_ld_index(TCGContext *s, TCGMemOp opc, TCGReg addrlo, TCGReg addend) { TCGMemOp bswap = opc & MO_BSWAP; + assert(USING_SOFTMMU || !bswap); switch (opc & MO_SSIZE) { case MO_UB: @@ -1386,7 +1378,6 @@ static inline void tcg_out_qemu_ld_index(TCGContext *s, TCGMemOp opc, } break; case MO_UL: - default: tcg_out_ld32_r(s, COND_AL, datalo, addrlo, addend); if (bswap) { tcg_out_bswap32(s, COND_AL, datalo, datalo); @@ -1416,6 +1407,8 @@ static inline void tcg_out_qemu_ld_index(TCGContext *s, TCGMemOp opc, } } break; + default: + g_assert_not_reached(); } } @@ -1424,6 +1417,7 @@ static inline void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, TCGReg addrlo) { TCGMemOp bswap = opc & MO_BSWAP; + assert(!USING_SOFTMMU && !bswap); switch (opc & MO_SSIZE) { case MO_UB: @@ -1434,47 +1428,24 @@ static inline void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp opc, break; case MO_UW: tcg_out_ld16u_8(s, COND_AL, datalo, addrlo, 0); - if (bswap) { - tcg_out_bswap16(s, COND_AL, datalo, datalo); - } break; case MO_SW: - if (bswap) { - tcg_out_ld16u_8(s, COND_AL, datalo, addrlo, 0); - tcg_out_bswap16s(s, COND_AL, datalo, datalo); - } else { - tcg_out_ld16s_8(s, COND_AL, datalo, addrlo, 0); - } + tcg_out_ld16s_8(s, COND_AL, datalo, addrlo, 0); break; case MO_UL: - default: tcg_out_ld32_12(s, COND_AL, datalo, addrlo, 0); - if (bswap) { - tcg_out_bswap32(s, COND_AL, datalo, datalo); - } break; case MO_Q: - { - TCGReg dl = (bswap ? datahi : datalo); - TCGReg dh = (bswap ? datalo : datahi); - - /* Avoid ldrd for user-only emulation, to handle unaligned. */ - if (USING_SOFTMMU && use_armv6_instructions - && (dl & 1) == 0 && dh == dl + 1) { - tcg_out_ldrd_8(s, COND_AL, dl, addrlo, 0); - } else if (dl == addrlo) { - tcg_out_ld32_12(s, COND_AL, dh, addrlo, bswap ? 0 : 4); - tcg_out_ld32_12(s, COND_AL, dl, addrlo, bswap ? 4 : 0); - } else { - tcg_out_ld32_12(s, COND_AL, dl, addrlo, bswap ? 4 : 0); - tcg_out_ld32_12(s, COND_AL, dh, addrlo, bswap ? 0 : 4); - } - if (bswap) { - tcg_out_bswap32(s, COND_AL, dl, dl); - tcg_out_bswap32(s, COND_AL, dh, dh); - } + if (datalo == addrlo) { + tcg_out_ld32_12(s, COND_AL, datahi, addrlo, 4); + tcg_out_ld32_12(s, COND_AL, datalo, addrlo, 0); + } else { + tcg_out_ld32_12(s, COND_AL, datalo, addrlo, 0); + tcg_out_ld32_12(s, COND_AL, datahi, addrlo, 4); } break; + default: + g_assert_not_reached(); } } @@ -1485,19 +1456,18 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64) TCGReg datalo __attribute__((unused)); TCGReg datahi __attribute__((unused)); TCGMemOpIdx oi; - TCGMemOp opc; datalo = *args++; datahi = (is64 ? *args++ : 0); addrlo = *args++; addrhi = (TARGET_LONG_BITS == 64 ? *args++ : 0); oi = *args++; - opc = get_memop(oi); #ifdef CONFIG_SOFTMMU add_ldst_ool_label(s, true, is64, oi, R_ARM_PC24, 0); tcg_out_bl_noaddr(s, COND_AL); #else + TCGMemOp opc = get_memop(oi); if (guest_base) { tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, guest_base); tcg_out_qemu_ld_index(s, opc, datalo, datahi, addrlo, TCG_REG_TMP); @@ -1512,6 +1482,7 @@ static inline void tcg_out_qemu_st_index(TCGContext *s, int cond, TCGMemOp opc, TCGReg addrlo, TCGReg addend) { TCGMemOp bswap = opc & MO_BSWAP; + assert(USING_SOFTMMU || !bswap); switch (opc & MO_SIZE) { case MO_8: @@ -1526,7 +1497,6 @@ static inline void tcg_out_qemu_st_index(TCGContext *s, int cond, TCGMemOp opc, } break; case MO_32: - default: if (bswap) { tcg_out_bswap32(s, cond, TCG_REG_R0, datalo); tcg_out_st32_r(s, cond, TCG_REG_R0, addrlo, addend); @@ -1535,20 +1505,32 @@ static inline void tcg_out_qemu_st_index(TCGContext *s, int cond, TCGMemOp opc, } break; case MO_64: - /* Avoid strd for user-only emulation, to handle unaligned. */ if (bswap) { - tcg_out_bswap32(s, cond, TCG_REG_R0, datahi); - tcg_out_st32_rwb(s, cond, TCG_REG_R0, addend, addrlo); - tcg_out_bswap32(s, cond, TCG_REG_R0, datalo); - tcg_out_st32_12(s, cond, TCG_REG_R0, addend, 4); - } else if (USING_SOFTMMU && use_armv6_instructions - && (datalo & 1) == 0 && datahi == datalo + 1) { + /* + * Assert inputs are where I think, for the softmmu thunk. + * One pair of R0/R1 or R2/R3 will be free and call-clobbered, + * which allows the use of STRD below. Note the bswaps also + * reverse the lo/hi registers to swap the two words. + */ + tcg_debug_assert(addend == TCG_REG_TMP); + tcg_debug_assert(datalo == TCG_REG_R4); + tcg_debug_assert(datahi == TCG_REG_R5); + datalo = addrlo == TCG_REG_R1 ? TCG_REG_R2 : TCG_REG_R0; + datahi = datalo + 1; + tcg_out_bswap32(s, cond, datalo, TCG_REG_R5); + tcg_out_bswap32(s, cond, datahi, TCG_REG_R4); + } + /* Avoid strd for user-only emulation, to handle unaligned. */ + if (USING_SOFTMMU && use_armv6_instructions + && (datalo & 1) == 0 && datahi == datalo + 1) { tcg_out_strd_r(s, cond, datalo, addrlo, addend); } else { tcg_out_st32_rwb(s, cond, datalo, addend, addrlo); tcg_out_st32_12(s, cond, datahi, addend, 4); } break; + default: + g_assert_not_reached(); } } @@ -1557,43 +1539,25 @@ static inline void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp opc, TCGReg addrlo) { TCGMemOp bswap = opc & MO_BSWAP; + assert(!USING_SOFTMMU && !bswap); switch (opc & MO_SIZE) { case MO_8: tcg_out_st8_12(s, COND_AL, datalo, addrlo, 0); break; case MO_16: - if (bswap) { - tcg_out_bswap16st(s, COND_AL, TCG_REG_R0, datalo); - tcg_out_st16_8(s, COND_AL, TCG_REG_R0, addrlo, 0); - } else { - tcg_out_st16_8(s, COND_AL, datalo, addrlo, 0); - } + tcg_out_st16_8(s, COND_AL, datalo, addrlo, 0); break; case MO_32: - default: - if (bswap) { - tcg_out_bswap32(s, COND_AL, TCG_REG_R0, datalo); - tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addrlo, 0); - } else { - tcg_out_st32_12(s, COND_AL, datalo, addrlo, 0); - } + tcg_out_st32_12(s, COND_AL, datalo, addrlo, 0); break; case MO_64: /* Avoid strd for user-only emulation, to handle unaligned. */ - if (bswap) { - tcg_out_bswap32(s, COND_AL, TCG_REG_R0, datahi); - tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addrlo, 0); - tcg_out_bswap32(s, COND_AL, TCG_REG_R0, datalo); - tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addrlo, 4); - } else if (USING_SOFTMMU && use_armv6_instructions - && (datalo & 1) == 0 && datahi == datalo + 1) { - tcg_out_strd_8(s, COND_AL, datalo, addrlo, 0); - } else { - tcg_out_st32_12(s, COND_AL, datalo, addrlo, 0); - tcg_out_st32_12(s, COND_AL, datahi, addrlo, 4); - } + tcg_out_st32_12(s, COND_AL, datalo, addrlo, 0); + tcg_out_st32_12(s, COND_AL, datahi, addrlo, 4); break; + default: + g_assert_not_reached(); } } @@ -1604,19 +1568,18 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64) TCGReg datalo __attribute__((unused)); TCGReg datahi __attribute__((unused)); TCGMemOpIdx oi; - TCGMemOp opc; datalo = *args++; datahi = (is64 ? *args++ : 0); addrlo = *args++; addrhi = (TARGET_LONG_BITS == 64 ? *args++ : 0); oi = *args++; - opc = get_memop(oi); #ifdef CONFIG_SOFTMMU add_ldst_ool_label(s, false, is64, oi, R_ARM_PC24, 0); tcg_out_bl_noaddr(s, COND_AL); #else + TCGMemOp opc = get_memop(oi); if (guest_base) { tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, guest_base); tcg_out_qemu_st_index(s, COND_AL, opc, datalo, @@ -2055,11 +2018,9 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) { static const TCGTargetOpDef r = { .args_ct_str = { "r" } }; static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } }; - static const TCGTargetOpDef s_s = { .args_ct_str = { "s", "s" } }; static const TCGTargetOpDef a_b = { .args_ct_str = { "a", "b" } }; static const TCGTargetOpDef c_b = { .args_ct_str = { "c", "b" } }; static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } }; - static const TCGTargetOpDef s_s_s = { .args_ct_str = { "s", "s", "s" } }; static const TCGTargetOpDef a_c_d = { .args_ct_str = { "a", "c", "d" } }; static const TCGTargetOpDef a_b_b = { .args_ct_str = { "a", "b", "b" } }; static const TCGTargetOpDef e_c_d = { .args_ct_str = { "e", "c", "d" } }; @@ -2072,8 +2033,6 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) = { .args_ct_str = { "r", "r", "rIK" } }; static const TCGTargetOpDef r_r_r_r = { .args_ct_str = { "r", "r", "r", "r" } }; - static const TCGTargetOpDef s_s_s_s - = { .args_ct_str = { "s", "s", "s", "s" } }; static const TCGTargetOpDef a_b_c_d = { .args_ct_str = { "a", "b", "c", "d" } }; static const TCGTargetOpDef e_f_c_d @@ -2175,7 +2134,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) } case INDEX_op_qemu_st_i32: if (!USING_SOFTMMU) { - return TARGET_LONG_BITS == 32 ? &s_s : &s_s_s; + return TARGET_LONG_BITS == 32 ? &r_r : &r_r_r; } else if (TARGET_LONG_BITS == 32) { return &c_b; /* temps available r0, r3, r12 */ } else { @@ -2183,7 +2142,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op) } case INDEX_op_qemu_st_i64: if (!USING_SOFTMMU) { - return TARGET_LONG_BITS == 32 ? &s_s_s : &s_s_s_s; + return TARGET_LONG_BITS == 32 ? &r_r_r : &r_r_r_r; } else if (TARGET_LONG_BITS == 32) { return &e_f_b; /* temps available r0, r2, r3, r12 */ } else {