From patchwork Wed Oct 3 18:07:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 148074 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp6797955lji; Wed, 3 Oct 2018 11:11:54 -0700 (PDT) X-Google-Smtp-Source: ACcGV60S52VzjvYfaESZkaUU7YvoA5MmS9UkM0CmyEnuR7pO7hpnO5Qi5R8lJ7mflEu5AOGvSP0a X-Received: by 2002:ac8:6119:: with SMTP id a25-v6mr2293147qtm.130.1538590314512; Wed, 03 Oct 2018 11:11:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538590314; cv=none; d=google.com; s=arc-20160816; b=dggzFvR3HvPKYROpDT2a9alFLuYhTXGJW9s4TpfiRbvES/eXIVUld28HLd0PXwCs/9 O3euOTux4mFJ1BS42bSYG3ldPH+QjJu396LQSlJeo3TqgagicTR+wBbE+42ToElFlG8b Mx5geAo/PmbliwsiM+VNtsWUnaE5NP1kRA7GVjt+qaIQqZZpQ8DmBEl9M1p51CX3kJeX gEdkPEsOgfaGwRm2KH2KgX41a1eNadDsnas7w6CVuy7jbWdSXMFE8zOcOSDYf248bdJF cpufzA6v9y0rm9Rw2NtFsl6bf2TgpngFwcXWhu10i7R8DWGogpdRFi5OJXpwKWXv7+Ji C4+Q== 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=odg7ZfMV79SrVzKzwTaTVznqxYz9qBXX7PFYNzpKD8U=; b=huxDl7wFdsJKy+qiTGT//d3aVjfKoBWLTPNPLCVXxh0LB4+F73dXpBhcwEkNxomjhH Q80tMG5KBBsIKaIJdeffqhG2NHZVcf1w6095wXeKlBhNJ1S2uHmQfo9MNy3k6yAOqEhw 9xnJN5mjDnxugeW70BhTpZLsGHHUeRtw7eou6dO/WQNEMZ6/vw2Yo8maEEJ5KkN78YB0 vYB2m5dbqCqnh8z1nVb9KyKjwOUs/9VkVjnBFBSqym65J0+ZhRps2Vo2aTzfUCFFh6nm y/NrVXCMkfXtDsDpHX2pQDfHzKnpk0xDWSpmYZ/8nt++ptMip/6xhcixuOVSqXCj6QpB COsw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=HU0y4ynC; 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 y190-v6si1244236qka.39.2018.10.03.11.11.54 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 03 Oct 2018 11:11:54 -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; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=HU0y4ynC; 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]:51688 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7lco-0005qT-1j for patch@linaro.org; Wed, 03 Oct 2018 14:11:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55402) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7lYf-0002f4-VF for qemu-devel@nongnu.org; Wed, 03 Oct 2018 14:07:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7lYb-0005AR-P0 for qemu-devel@nongnu.org; Wed, 03 Oct 2018 14:07:37 -0400 Received: from mail-ot1-x32a.google.com ([2607:f8b0:4864:20::32a]:32976) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g7lYa-00042u-7A for qemu-devel@nongnu.org; Wed, 03 Oct 2018 14:07:33 -0400 Received: by mail-ot1-x32a.google.com with SMTP id q50so2343837otd.0 for ; Wed, 03 Oct 2018 11:07:18 -0700 (PDT) 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=odg7ZfMV79SrVzKzwTaTVznqxYz9qBXX7PFYNzpKD8U=; b=HU0y4ynCdHuYigSfxaPUHPiEujR0c7zDFQ0XKsBbxaRgCjHE4/aFXwYDDN+HvL97Sx ay5V44U6GsPSHtux6LQAgoX2IueihVhe9QVj5t/+wUae9Igum6D8B0Nfc5DrlEoO6mCE P9i5DRxzQIRrjuPHmAl5dISc9DKULYcynVUA8= 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=odg7ZfMV79SrVzKzwTaTVznqxYz9qBXX7PFYNzpKD8U=; b=Gxg8Xy8jX3iiAcgn7gQZr1IMrwATpAz20k9gN1j2knDmtrsaElm3DHLgu8lfiZMItM tHHp3RiDnFRGVyBY1ZbUocu8oe/cxPZY+V8tbK3OcbCXvCjstP/a3flCnpBRf72QyG6n SfMC0+IUcEPKdPDlrK+L4dFXH1Rm8gfCDVUunyB4t5f7vwEKXNNhedqw6qzO6hTJj/EM zTlJppPohG+OpbNJ/S2b623DDCfoLSphM1hlmtlhWqGg1O1vaDqJlP3TkH3K8ZPmhp1c /TdbBCyBeB788xit6c+5IvHiLaFKekprMhhLl2gjou9Zj4SxqS7vu7k3DjrGOoN8MfOl DVzg== X-Gm-Message-State: ABuFfoiadNQbLU/qlVO9zzwWlrYvrTM/zezgUTW+960KXMyrqIAOiZ5i HLZ3jtrzaJE4UP+AOba4ZzTNuteInwYnRg== X-Received: by 2002:a9d:248:: with SMTP id 66-v6mr1437729otb.366.1538590037290; Wed, 03 Oct 2018 11:07:17 -0700 (PDT) Received: from cloudburst.twiddle.net ([187.217.227.243]) by smtp.gmail.com with ESMTPSA id f84-v6sm677709oia.44.2018.10.03.11.07.15 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 03 Oct 2018 11:07:16 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Wed, 3 Oct 2018 13:07:08 -0500 Message-Id: <20181003180711.19335-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181003180711.19335-1-richard.henderson@linaro.org> References: <20181003180711.19335-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::32a Subject: [Qemu-devel] [PATCH v2 1/4] softfloat: Fix division 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: cota@braap.org, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The __udiv_qrnnd primitive that we nicked from gmp requires its inputs to be normalized. We were not doing that. Because the inputs are nearly normalized already, finishing that is trivial. Replace div128to64 with a "proper" udiv_qrnnd, so that this remains a reusable primitive. Fixes: cf07323d494 Fixes: https://bugs.launchpad.net/qemu/+bug/1793119 Signed-off-by: Richard Henderson --- include/fpu/softfloat-macros.h | 7 ++++--- fpu/softfloat.c | 35 ++++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 11 deletions(-) -- 2.17.1 diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index edc682139e..03312471b2 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -619,7 +619,8 @@ static inline uint64_t estimateDiv128To64(uint64_t a0, uint64_t a1, uint64_t b) * * Licensed under the GPLv2/LGPLv3 */ -static inline uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d) +static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1, + uint64_t n0, uint64_t d) { uint64_t d0, d1, q0, q1, r1, r0, m; @@ -658,8 +659,8 @@ static inline uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d) } r0 -= m; - /* Return remainder in LSB */ - return (q1 << 32) | q0 | (r0 != 0); + *r = r0; + return (q1 << 32) | q0; } /*---------------------------------------------------------------------------- diff --git a/fpu/softfloat.c b/fpu/softfloat.c index a06b6ef7e4..97ef66d570 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1112,19 +1112,38 @@ static FloatParts div_floats(FloatParts a, FloatParts b, float_status *s) bool sign = a.sign ^ b.sign; if (a.cls == float_class_normal && b.cls == float_class_normal) { - uint64_t temp_lo, temp_hi; + uint64_t n0, n1, q, r; int exp = a.exp - b.exp; + + /* + * We want a 2*N / N-bit division to produce exactly an N-bit + * result, so that we do not lose any precision and so that we + * do not have to renormalize afterward. If A.frac < B.frac, + * then division would produce an (N-1)-bit result; shift A left + * by one to produce the an N-bit result, and decrement the + * exponent to match. + * + * The udiv_qrnnd algorithm that we're using requires normalization, + * i.e. the msb of the denominator must be set. Since we know that + * DECOMPOSED_BINARY_POINT is msb-1, the inputs must be shifted left + * by one (more), and the remainder must be shifted right by one. + */ if (a.frac < b.frac) { exp -= 1; - shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT + 1, - &temp_hi, &temp_lo); + shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT + 2, &n1, &n0); } else { - shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT, - &temp_hi, &temp_lo); + shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT + 1, &n1, &n0); } - /* LSB of quot is set if inexact which roundandpack will use - * to set flags. Yet again we re-use a for the result */ - a.frac = div128To64(temp_lo, temp_hi, b.frac); + q = udiv_qrnnd(&r, n1, n0, b.frac << 1); + + /* + * Set lsb if there is a remainder, to set inexact. + * As mentioned above, to find the actual value of the remainder we + * would need to shift right, but (1) we are only concerned about + * non-zero-ness, and (2) the remainder will always be even because + * both inputs to the division primitive are even. + */ + a.frac = q | (r != 0); a.sign = sign; a.exp = exp; return a;