From patchwork Sun Jun 4 17:34:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 9765157 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 C3CC36032D for ; Sun, 4 Jun 2017 18:03:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B85AA27FB3 for ; Sun, 4 Jun 2017 18:03:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AB695280B0; Sun, 4 Jun 2017 18:03:13 +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 0E8EB27FB3 for ; Sun, 4 Jun 2017 18:03:13 +0000 (UTC) Received: from localhost ([::1]:57947 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dHZrs-0007cu-1H for patchwork-qemu-devel@patchwork.kernel.org; Sun, 04 Jun 2017 14:03:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50430) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dHZRf-0007qf-E3 for qemu-devel@nongnu.org; Sun, 04 Jun 2017 13:36:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dHZRe-0003Y6-5S for qemu-devel@nongnu.org; Sun, 04 Jun 2017 13:36:07 -0400 Received: from mail-pg0-x241.google.com ([2607:f8b0:400e:c05::241]:35795) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dHZRd-0003XQ-T0 for qemu-devel@nongnu.org; Sun, 04 Jun 2017 13:36:06 -0400 Received: by mail-pg0-x241.google.com with SMTP id f127so7256164pgc.2 for ; Sun, 04 Jun 2017 10:36:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=/kr8ps84mVKBjpfIXGC8Z9DgOi3pc9TVx3w/2qYjHEI=; b=ovHkwkjFJWfO7KUaWfGytfC9VGy9XU0oOcCaWIPk9Tii4cX1VMQK+PZaZKip7PKHb3 U09wIsLEFL/Y5BU4mXE5gAuD99JsLvFowAq05lEj1BM419xJJQkaWVVIlVUbrUEai8r9 lVePQbBDzkeWcKrNZflKgAPQl6AptrcIOsWcdtwTEbQPnKmskxz2wFtADWkDr6aERJ09 iJc6gghOTuOi20O5z+3JFkH6LfDdXbWx+Ngy5s5eZkWiSFtQVF9GdmtUTXG/pHvqSFDR 2G+103QHlGrhFCu7lmuXCYsH6BN6q3nHz+jNJuLIeitAXfswwnBkxHOvrfR9/Oxz8ib5 C1xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=/kr8ps84mVKBjpfIXGC8Z9DgOi3pc9TVx3w/2qYjHEI=; b=c3uie4r/DBfDP/xoZZorSpDNPHO/No23vWmWwyY/RybkmDVmBCudw/m8Q9yw6/0GYk uZq1J63g1T6TSfes/Vr+tHZWlQSHABETNZ2lyTUKAXVDaPB/0DYZwzoVvv0zGR20Bmhf 8VCTC7OFfIu9DLfQkPDbg1tPWkoEUyaMrKzb5Wwkz/vIixG8HmzerVLnKBiSCaqsOWT8 Zja9JLfOEZ7ezqY/Jq7BIp4GMR10GQQZ0abadAAjWerdbsI3AayqMOvFcS4Bxf+/3Fd4 AcPmBepvNE6+l+XNm/kE48GrY7TC9oKlfv0l4HH6n9GyXozDqaD+bvTCZvdRY2Xowqnk 0XwA== X-Gm-Message-State: AODbwcDRXHQaEMXLLoQC1musuLKsMqi0jagYnnYsXUmjBjLRhHAGVTFn od/XE/uJI0QmwClGe48= X-Received: by 10.99.94.70 with SMTP id s67mr16925986pgb.82.1496597764817; Sun, 04 Jun 2017 10:36:04 -0700 (PDT) Received: from bigtime.ASUS (cpe-98-155-27-246.hawaii.res.rr.com. [98.155.27.246]) by smtp.gmail.com with ESMTPSA id j191sm52854419pgc.53.2017.06.04.10.36.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 04 Jun 2017 10:36:04 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sun, 4 Jun 2017 10:34:38 -0700 Message-Id: <20170604173509.29684-39-rth@twiddle.net> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170604173509.29684-1-rth@twiddle.net> References: <20170604173509.29684-1-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::241 Subject: [Qemu-devel] [PULL 38/69] target/s390x: Re-implement a few EXECUTE target insns directly 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: peter.maydell@linaro.org, aurelien@aurel32.net Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP While the previous patch is required for proper conformance, the vast majority of target insns are MVC and XC for implementing memmove and memset respectively. The next most common are CLC, TR, and SVC. Implementing these (and a few others for which we already have an implementation) directly is faster than going through full translation to a TB. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- target/s390x/mem_helper.c | 66 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 3a77edc..e35571e 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -200,31 +200,30 @@ uint32_t HELPER(oc)(CPUS390XState *env, uint32_t l, uint64_t dest, } /* memmove */ -static void do_helper_mvc(CPUS390XState *env, uint32_t l, uint64_t dest, - uint64_t src, uintptr_t ra) +static uint32_t do_helper_mvc(CPUS390XState *env, uint32_t l, uint64_t dest, + uint64_t src, uintptr_t ra) { uint32_t i; HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n", __func__, l, dest, src); + /* mvc and memmove do not behave the same when areas overlap! */ /* mvc with source pointing to the byte after the destination is the same as memset with the first source byte */ if (dest == src + 1) { fast_memset(env, dest, cpu_ldub_data_ra(env, src, ra), l + 1, ra); - return; - } - - /* mvc and memmove do not behave the same when areas overlap! */ - if (dest < src || src + l < dest) { + } else if (dest < src || src + l < dest) { fast_memmove(env, dest, src, l + 1, ra); - return; + } else { + /* slow version with byte accesses which always work */ + for (i = 0; i <= l; i++) { + uint8_t x = cpu_ldub_data_ra(env, src + i, ra); + cpu_stb_data_ra(env, dest + i, x, ra); + } } - /* slow version with byte accesses which always work */ - for (i = 0; i <= l; i++) { - cpu_stb_data_ra(env, dest + i, cpu_ldub_data_ra(env, src + i, ra), ra); - } + return env->cc_op; } void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src) @@ -692,8 +691,8 @@ void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest, } } -static void do_helper_tr(CPUS390XState *env, uint32_t len, uint64_t array, - uint64_t trans, uintptr_t ra) +static uint32_t do_helper_tr(CPUS390XState *env, uint32_t len, uint64_t array, + uint64_t trans, uintptr_t ra) { uint32_t i; @@ -702,12 +701,14 @@ static void do_helper_tr(CPUS390XState *env, uint32_t len, uint64_t array, uint8_t new_byte = cpu_ldub_data_ra(env, trans + byte, ra); cpu_stb_data_ra(env, array + i, new_byte, ra); } + + return env->cc_op; } void HELPER(tr)(CPUS390XState *env, uint32_t len, uint64_t array, uint64_t trans) { - return do_helper_tr(env, len, array, trans, GETPC()); + do_helper_tr(env, len, array, trans, GETPC()); } uint64_t HELPER(tre)(CPUS390XState *env, uint64_t array, @@ -1221,6 +1222,41 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr) g_assert_not_reached(); } + /* The very most common cases can be sped up by avoiding a new TB. */ + if ((opc & 0xf0) == 0xd0) { + typedef uint32_t (*dx_helper)(CPUS390XState *, uint32_t, uint64_t, + uint64_t, uintptr_t); + static const dx_helper dx[16] = { + [0x2] = do_helper_mvc, + [0x4] = do_helper_nc, + [0x5] = do_helper_clc, + [0x6] = do_helper_oc, + [0x7] = do_helper_xc, + [0xc] = do_helper_tr, + [0xd] = do_helper_trt, + }; + dx_helper helper = dx[opc & 0xf]; + + if (helper) { + uint32_t l = extract64(insn, 48, 8); + uint32_t b1 = extract64(insn, 44, 4); + uint32_t d1 = extract64(insn, 32, 12); + uint32_t b2 = extract64(insn, 28, 4); + uint32_t d2 = extract64(insn, 16, 12); + uint64_t a1 = get_address(env, 0, b1, d1); + uint64_t a2 = get_address(env, 0, b2, d2); + + env->cc_op = helper(env, l, a1, a2, 0); + env->psw.addr += ilen; + return; + } + } else if (opc == 0x0a) { + env->int_svc_code = extract64(insn, 48, 8); + env->int_svc_ilen = ilen; + helper_exception(env, EXCP_SVC); + g_assert_not_reached(); + } + /* Record the insn we want to execute as well as the ilen to use during the execution of the target insn. This will also ensure that ex_value is non-zero, which flags that we are in a state