From patchwork Fri Sep 28 00:24:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 187612 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 5DFD12C00B8 for ; Fri, 28 Sep 2012 10:24:32 +1000 (EST) Received: from localhost ([::1]:41994 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1THONa-0003RK-Cs for incoming@patchwork.ozlabs.org; Thu, 27 Sep 2012 20:24:30 -0400 Received: from eggs.gnu.org ([208.118.235.92]:35241) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1THONT-0003Qt-51 for qemu-devel@nongnu.org; Thu, 27 Sep 2012 20:24:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1THONR-0003Ut-Jo for qemu-devel@nongnu.org; Thu, 27 Sep 2012 20:24:23 -0400 Received: from mail-da0-f45.google.com ([209.85.210.45]:50075) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1THONR-0003Up-AB for qemu-devel@nongnu.org; Thu, 27 Sep 2012 20:24:21 -0400 Received: by dadn15 with SMTP id n15so517692dad.4 for ; Thu, 27 Sep 2012 17:24:20 -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=N6Des4FMCfnEsbgzitsy+oxpn1tNUGnGDzbtFkTwTos=; b=ghRiwQsAZLobTchILjWcIpKK8oeUwzfbS92N/2b2zUw6pgBoS1KiwzgF4OiKVRZkff IWY6M7o5FKvEawgVoFYU5KWG7ijXqHbnwTvITgvx8AgDTZyOr9xeYMvjxz1a9Jd+2HXs wBDgk78F7CQife0R8hxQnWPL+0dlH6THnjatMKjJy5hDVsMyE+xnOCK0bFF9hXyu6nnb EQOQsQDMBEANUwKY+cdZmzu2JKdYDDVmwRdV6bLJ0bbrz2kGSuaGp0SzY36NtpUDS/8d 4s62yF9wGY4KQHPuwjPAYtJCyBO92d5SmUmm6WwEJDhz0yNMD6k1lIzkXvBk0DFZkYme bVbA== Received: by 10.66.77.170 with SMTP id t10mr13398159paw.0.1348791860346; Thu, 27 Sep 2012 17:24:20 -0700 (PDT) Received: from anchor.twiddle.home.com ([173.160.232.49]) by mx.google.com with ESMTPS id gt2sm4600154pbc.62.2012.09.27.17.24.19 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 27 Sep 2012 17:24:19 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 27 Sep 2012 17:24:16 -0700 Message-Id: <1348791856-26564-1-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.11.4 In-Reply-To: <1348785610-23418-1-git-send-email-rth@twiddle.net> References: <1348785610-23418-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.210.45 Cc: Alexander Graf Subject: [Qemu-devel] [PATCH 090/147] 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 | 43 +++++++++++++++++++++++++------------------ target-s390x/translate.c | 31 ++++++++++++++++++++++--------- 4 files changed, 51 insertions(+), 28 deletions(-) diff --git a/target-s390x/helper.h b/target-s390x/helper.h index 5ae723e..9bcf79f 100644 --- a/target-s390x/helper.h +++ b/target-s390x/helper.h @@ -75,7 +75,7 @@ DEF_HELPER_3(sqxb, i64, env, i64, i64) DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32) DEF_HELPER_4(unpk, void, env, i32, i64, i64) DEF_HELPER_4(tr, void, env, i32, i64, i64) -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 13b1771..74f1032 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 db48d63..1b06297 100644 --- a/target-s390x/mem_helper.c +++ b/target-s390x/mem_helper.c @@ -753,42 +753,49 @@ 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; + len += 1; break; case 2: cksm += cpu_lduw_data(env, src) << 16; + len += 2; break; case 3: cksm += cpu_lduw_data(env, src) << 16; cksm += cpu_ldub_data(env, src + 2) << 8; + len += 3; 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 4990e57..06b0322 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -1034,15 +1034,6 @@ static void disas_b2(CPUS390XState *env, DisasContext *s, int op, 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])); @@ -2047,6 +2038,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); @@ -3847,6 +3855,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;