From patchwork Sun Sep 9 21:05:41 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 182719 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 58FA42C00A0 for ; Mon, 10 Sep 2012 09:01:24 +1000 (EST) Received: from localhost ([::1]:49091 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TAqVG-0005eR-F9 for incoming@patchwork.ozlabs.org; Sun, 09 Sep 2012 19:01:22 -0400 Received: from eggs.gnu.org ([208.118.235.92]:57157) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TAojL-00007m-5m for qemu-devel@nongnu.org; Sun, 09 Sep 2012 17:07:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TAojJ-0006E7-OD for qemu-devel@nongnu.org; Sun, 09 Sep 2012 17:07:47 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:59699) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TAojJ-0005pQ-IP for qemu-devel@nongnu.org; Sun, 09 Sep 2012 17:07:45 -0400 Received: by mail-pb0-f45.google.com with SMTP id rp12so291958pbb.4 for ; Sun, 09 Sep 2012 14:07:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=7j6zY8OZl2DvV6NH0UswTDIe8Vfacw8umG12ETTU4mU=; b=v4wJUuiNq6+b2sSVRe+6m09Qtz0t2JsIRzNhW/YDwg8119ClsLMkB2FcBFEsjfCp1L tSNkDblvrTK3JjmBdTZxrWnRphFDCbhJDPDO/Hoqv1WjMPNhKxnReiN/KxnflkRaWPZW IAU3NEPbL9BYBFde6IqWRuPA80ABoMuNkGciJ07IIop3y/MEFDWp4+RhB2wPD3SlW7Ep NDtZHGoK64VbKPvU8kz+Y3DLRGJ4rqTNX96o+NHEsOWSwxcYiw3D2TcfBQsJvlU8E693 6C4+Fsw+8QsnXOs052saLvQPud15cUr8CpXgftWfSIHPXzirIts5Jtz27a8dnfKV+ggy bnjA== Received: by 10.68.222.167 with SMTP id qn7mr2035128pbc.98.1347224865212; Sun, 09 Sep 2012 14:07:45 -0700 (PDT) Received: from anchor.twiddle.home ([173.160.232.49]) by mx.google.com with ESMTPS id tw5sm662053pbc.48.2012.09.09.14.07.44 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 09 Sep 2012 14:07:44 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sun, 9 Sep 2012 14:05:41 -0700 Message-Id: <1347224784-19472-84-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.11.4 In-Reply-To: <1347224784-19472-1-git-send-email-rth@twiddle.net> References: <1347224784-19472-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.160.45 Cc: Alexander Graf Subject: [Qemu-devel] [PATCH 083/126] target-s390: Convert CKSM 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 Signed-off-by: Richard Henderson --- target-s390x/helper.h | 2 +- target-s390x/insn-data.def | 3 +++ target-s390x/mem_helper.c | 40 ++++++++++++++++++++++------------------ target-s390x/translate.c | 31 ++++++++++++++++++++++--------- 4 files changed, 48 insertions(+), 28 deletions(-) diff --git a/target-s390x/helper.h b/target-s390x/helper.h index bb1f740..2bd4105 100644 --- a/target-s390x/helper.h +++ b/target-s390x/helper.h @@ -118,7 +118,7 @@ DEF_HELPER_FLAGS_3(ipte, TCG_CALL_CONST, void, env, i64, i64) DEF_HELPER_FLAGS_1(ptlb, TCG_CALL_CONST, void, env) DEF_HELPER_2(lra, i64, env, i64) DEF_HELPER_3(stura, void, env, i64, i32) -DEF_HELPER_3(cksm, void, env, i32, i32) +DEF_HELPER_4(cksm, i64, env, i64, i64, i64) DEF_HELPER_FLAGS_2(sfpc, TCG_CALL_CONST, void, env, i64) DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_PURE|TCG_CALL_CONST, diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def index 2eb248f..eec99fe 100644 --- a/target-s390x/insn-data.def +++ b/target-s390x/insn-data.def @@ -91,6 +91,9 @@ C(0xa706, BRCT, RI_b, Z, 0, 0, 0, 0, bct32, 0) C(0xa707, BRCTG, RI_b, Z, 0, 0, 0, 0, bct64, 0) +/* CHECKSUM */ + C(0xb241, CKSM, RRE, Z, r1_o, ra2, new, r1_32, cksm, 0) + /* COMPARE */ C(0x1900, CR, RR_a, Z, r1_o, r2_o, 0, 0, 0, cmps32) C(0x5900, C, RX_a, Z, r1_o, m2_32s, 0, 0, 0, cmps32) diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c index dfdb2c7..5f70aad 100644 --- a/target-s390x/mem_helper.c +++ b/target-s390x/mem_helper.c @@ -753,23 +753,22 @@ uint32_t HELPER(clcle)(CPUS390XState *env, uint32_t r1, uint64_t a2, } /* checksum */ -void HELPER(cksm)(CPUS390XState *env, uint32_t r1, uint32_t r2) +uint64_t HELPER(cksm)(CPUS390XState *env, uint64_t r1, + uint64_t src, uint64_t src_len) { - uint64_t src = get_address_31fix(env, r2); - uint64_t src_len = env->regs[(r2 + 1) & 15]; - uint64_t cksm = (uint32_t)env->regs[r1]; + uint64_t max_len, len; + uint64_t cksm = (uint32_t)r1; - while (src_len >= 4) { - cksm += cpu_ldl_data(env, src); + /* Lest we fail to service interrupts in a timely manner, limit the + amount of work we're willing to do. For now, lets cap at 8k. */ + max_len = (src_len > 0x2000 ? 0x2000 : src_len); - /* move to next word */ - src_len -= 4; - src += 4; + /* Process full words as available. */ + for (len = 0; len + 4 <= max_len; len += 4, src += 4) { + cksm += (uint32_t)cpu_ldl_data(env, src); } - switch (src_len) { - case 0: - break; + switch (max_len - len) { case 1: cksm += cpu_ldub_data(env, src) << 24; break; @@ -782,13 +781,18 @@ void HELPER(cksm)(CPUS390XState *env, uint32_t r1, uint32_t r2) break; } - /* indicate we've processed everything */ - env->regs[r2] = src + src_len; - env->regs[(r2 + 1) & 15] = 0; + /* Fold the carry from the checksum. Note that we can see carry-out + during folding more than once (but probably not more than twice). */ + while (cksm > 0xffffffffull) { + cksm = (uint32_t)cksm + (cksm >> 32); + } + + /* Indicate whether or not we've processed everything. */ + env->cc_op = (len == src_len ? 0 : 3); - /* store result */ - env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | - ((uint32_t)cksm + (cksm >> 32)); + /* Return both cksm and processed length. */ + env->retxl = cksm; + return len; } void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest, diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 34615cb..16eabba 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -1031,15 +1031,6 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn) LOG_DISAS("disas_b2: op 0x%x r1 %d r2 %d\n", op, r1, r2); switch (op) { - case 0x41: /* CKSM R1,R2 [RRE] */ - tmp32_1 = tcg_const_i32(r1); - tmp32_2 = tcg_const_i32(r2); - potential_page_fault(s); - gen_helper_cksm(cpu_env, tmp32_1, tmp32_2); - tcg_temp_free_i32(tmp32_1); - tcg_temp_free_i32(tmp32_2); - gen_op_movi_cc(s, 0); - break; case 0x4e: /* SAR R1,R2 [RRE] */ tmp32_1 = load_reg32(r2); tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, aregs[r1])); @@ -2000,6 +1991,23 @@ static ExitStatus op_cxgb(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_cksm(DisasContext *s, DisasOps *o) +{ + int r2 = get_field(s->fields, r2); + TCGv_i64 len = tcg_temp_new_i64(); + + potential_page_fault(s); + gen_helper_cksm(len, cpu_env, o->in1, o->in2, regs[r2 + 1]); + set_cc_static(s); + return_low128(o->out); + + tcg_gen_add_i64(regs[r2], regs[r2], len); + tcg_gen_sub_i64(regs[r2 + 1], regs[r2 + 1], len); + tcg_temp_free_i64(len); + + return NO_EXIT; +} + static ExitStatus op_clc(DisasContext *s, DisasOps *o) { int l = get_field(s->fields, l1); @@ -3771,6 +3779,11 @@ static void in2_x2_o(DisasContext *s, DisasFields *f, DisasOps *o) o->g_in1 = o->g_in2 = true; } +static void in2_ra2(DisasContext *s, DisasFields *f, DisasOps *o) +{ + o->in2 = get_address(s, 0, get_field(f, r2), 0); +} + static void in2_a2(DisasContext *s, DisasFields *f, DisasOps *o) { int x2 = have_field(f, x2) ? get_field(f, x2) : 0;