From patchwork Thu Apr 17 10:34:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 28574 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f198.google.com (mail-pd0-f198.google.com [209.85.192.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 52E2920674 for ; Thu, 17 Apr 2014 12:24:49 +0000 (UTC) Received: by mail-pd0-f198.google.com with SMTP id fp1sf1127658pdb.9 for ; Thu, 17 Apr 2014 05:24:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=LiQSDd6w7yS8E7aQXH7WncyDeU7ZxtpqxZRyAduhBdA=; b=dYcx+lacVjcgcXcnU+QQZopA1aLGGCYc49dXJaYQZrId8Ba+2X4N/6zNvo2UMdzRnp PE0OuVNqu1HhOE4Wi8fVDejWgyBQee8/XzlVVNJ4eOxQWhA48MhE2eqQcJalk6TI1scr qBl7OVcEeG2kF6320zbPQaM8mE9lvMM6n/3XBXVV8TZV5fLSVOWNRWMGrK8Iy5lg63ly grsl9bVA2IMUyfl9Twg+gQUfDjfwbQvuCZ2JybUvhsLpU38opQg4rgfzg6H2ijRBJNeD Jbo4EpI6rE7Br1XNOtQX5pYTINBMS5eer13Lu/QAPV07rj4lC5QZF4uDK9IdchnqxLfy l3hw== X-Gm-Message-State: ALoCoQmiGwFaWUv1VcPyqZORIavgApKj5iWT87n0Sc+BpT5q8CmS9AroBb9D5HNx1++uDYGf9W4D X-Received: by 10.66.66.109 with SMTP id e13mr6923497pat.1.1397737488572; Thu, 17 Apr 2014 05:24:48 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.102.87 with SMTP id v81ls1032561qge.0.gmail; Thu, 17 Apr 2014 05:24:48 -0700 (PDT) X-Received: by 10.221.63.1 with SMTP id xc1mr84434vcb.35.1397737488383; Thu, 17 Apr 2014 05:24:48 -0700 (PDT) Received: from mail-vc0-f180.google.com (mail-vc0-f180.google.com [209.85.220.180]) by mx.google.com with ESMTPS id tq2si4417856vdc.93.2014.04.17.05.24.48 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 17 Apr 2014 05:24:48 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.180 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.180; Received: by mail-vc0-f180.google.com with SMTP id lf12so381947vcb.39 for ; Thu, 17 Apr 2014 05:24:48 -0700 (PDT) X-Received: by 10.58.248.5 with SMTP id yi5mr48333vec.42.1397737488270; Thu, 17 Apr 2014 05:24:48 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp30977vcb; Thu, 17 Apr 2014 05:24:47 -0700 (PDT) X-Received: by 10.224.124.129 with SMTP id u1mr2196182qar.95.1397737487589; Thu, 17 Apr 2014 05:24:47 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id v6si10446920qas.91.2014.04.17.05.24.47 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 17 Apr 2014 05:24:47 -0700 (PDT) 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; Received: from localhost ([::1]:59418 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wajh1-0002TG-IO for patch@linaro.org; Thu, 17 Apr 2014 06:37:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50694) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Waje5-0007f3-T0 for qemu-devel@nongnu.org; Thu, 17 Apr 2014 06:34:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Waje3-0002Pj-SX for qemu-devel@nongnu.org; Thu, 17 Apr 2014 06:34:17 -0400 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:47842) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Waje3-0002OB-Ki for qemu-devel@nongnu.org; Thu, 17 Apr 2014 06:34:15 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1Wajdy-00022g-1c for qemu-devel@nongnu.org; Thu, 17 Apr 2014 11:34:10 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 17 Apr 2014 11:34:05 +0100 Message-Id: <1397730846-7576-51-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1397730846-7576-1-git-send-email-peter.maydell@linaro.org> References: <1397730846-7576-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Subject: [Qemu-devel] [PULL 50/51] arm: translate.c: Fix smlald Instruction 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+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.180 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Peter Crosthwaite The smlald (and probably smlsld) instruction was doing incorrect sign extensions of the operands amongst 64bit result calculation. The instruction psuedo-code is: operand2 = if m_swap then ROR(R[m],16) else R[m]; product1 = SInt(R[n]<15:0>) * SInt(operand2<15:0>); product2 = SInt(R[n]<31:16>) * SInt(operand2<31:16>); result = product1 + product2 + SInt(R[dHi]:R[dLo]); R[dHi] = result<63:32>; R[dLo] = result<31:0>; The result calculation should be done in 64 bit arithmetic, and hence product1 and product2 should be sign extended to 64b before calculation. The current implementation was adding product1 and product2 together then sign-extending the intermediate result leading to false negatives. E.G. if product1 = product2 = 0x4000000, their sum = 0x80000000, which will be incorrectly interpreted as -ve on sign extension. We fix by doing the 64b extensions on both product1 and product2 before any addition/subtraction happens. We also fix where we were possibly incorrectly setting the Q saturation flag for SMLSLD, which the ARM ARM specifically says is not set. Reported-by: Christina Smith Signed-off-by: Peter Crosthwaite Reviewed-by: Peter Maydell Message-id: 2cddb6f5a15be4ab8d2160f3499d128ae93d304d.1397704570.git.peter.crosthwaite@xilinx.com Cc: qemu-stable@nongnu.org Signed-off-by: Peter Maydell --- target-arm/translate.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index 0c08cc1..a4d920b 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -8430,27 +8430,39 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s) if (insn & (1 << 5)) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); - if (insn & (1 << 6)) { - /* This subtraction cannot overflow. */ - tcg_gen_sub_i32(tmp, tmp, tmp2); - } else { - /* This addition cannot overflow 32 bits; - * however it may overflow considered as a signed - * operation, in which case we must set the Q flag. - */ - gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); - } - tcg_temp_free_i32(tmp2); if (insn & (1 << 22)) { /* smlald, smlsld */ + TCGv_i64 tmp64_2; + tmp64 = tcg_temp_new_i64(); + tmp64_2 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); + tcg_gen_ext_i32_i64(tmp64_2, tmp2); tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + if (insn & (1 << 6)) { + tcg_gen_sub_i64(tmp64, tmp64, tmp64_2); + } else { + tcg_gen_add_i64(tmp64, tmp64, tmp64_2); + } + tcg_temp_free_i64(tmp64_2); gen_addq(s, tmp64, rd, rn); gen_storeq_reg(s, rd, rn, tmp64); tcg_temp_free_i64(tmp64); } else { /* smuad, smusd, smlad, smlsd */ + if (insn & (1 << 6)) { + /* This subtraction cannot overflow. */ + tcg_gen_sub_i32(tmp, tmp, tmp2); + } else { + /* This addition cannot overflow 32 bits; + * however it may overflow considered as a + * signed operation, in which case we must set + * the Q flag. + */ + gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); + } + tcg_temp_free_i32(tmp2); if (rd != 15) { tmp2 = load_reg(s, rd);