From nobody Mon Feb 9 16:18:41 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1591635502; cv=none; d=zohomail.com; s=zohoarc; b=HNaT7URb9QqNMstISyoGQrjEtiZ2rnCwDSFUfRdJz3JzVtsoRWxO6qJtWfFvcSifsuR+Xr9py12cvmWBx6hDX7QCCGCj9bGFJ8EpdA+4StkRrTRsl3YzhENgBHij+VQVTbCn0fYtXsO9q0u0fT5XnZsSjTux9M1z0358y6gVt8k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1591635502; h=Content-Type:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=8CmLu7q6/DzkOxM0eGk2L9PanswjI6hDWJAjde5j27s=; b=S2hfET0epGWlM0CdNFxfse49mk6NYjBffcP9ODcVh2LI10QYu/0prMXJI12zEYYE1V1LKW8px1PLG7lALp7wQQmk1UOnphRviE9S4ZQEMr7DxWkOd80OkIBl5yox1y1dvHOXU05+ZqeWnjg0K7ZmLv2Bx5ULdXFpulWKXLA80SM= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1591635502432506.4557656721554; Mon, 8 Jun 2020 09:58:22 -0700 (PDT) Received: from localhost ([::1]:45030 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jiL6L-0006Ds-2Z for importer@patchew.org; Mon, 08 Jun 2020 12:58:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45528) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jiL3V-0001Yl-8k for qemu-devel@nongnu.org; Mon, 08 Jun 2020 12:55:25 -0400 Received: from esa4.mentor.iphmx.com ([68.232.137.252]:8930) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jiL3Q-0000yK-GV for qemu-devel@nongnu.org; Mon, 08 Jun 2020 12:55:24 -0400 Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa4.mentor.iphmx.com with ESMTP; 08 Jun 2020 08:55:17 -0800 IronPort-SDR: Khmbr5fiZqI6t24vgc6puH3jNWBnRnTSx1gJfTQcMe9/CO+dqeqkI2fEK/2BaOMQnrkP3ambwc eRPed7mxWkO587DYyl+eGoy/TKNAtURc5KsgkTwbrAviEkOdKDQUCu9LMm0wlPj40EEAanQHtk ieUWPw64QTAC+9GtfCQGVCaj2mJlzHnYE/2cIDG8c0Oa83vTZ/jSq6lZpp7teT5b4Bn/WWL1bH Pu3iU1djgpx6W5HYcGISEDsLYdmD1K9Rcqdu+Yzl0Bc7yih1CLKGYVRtAIMEdkf4Y4WMZzkIZb 9lE= X-IronPort-AV: E=Sophos;i="5.73,487,1583222400"; d="scan'208";a="49689833" IronPort-SDR: fduFEj/KvJtcW19ZwVW2A2cJDBiphUnRo/1Adt8HUYpAEUvgwKDG7BAknr61WOtkXPEWQ3rYk8 UQ7+RuDzAfPU6YPd9Od0lAvtjnuQtMdt/6QMIubySVQkIBkJgZW4jlc073FPiRiJhistiQCdIi SDr4suwAsbIEexOOyWN/RcF0w24jJEHegTPOoLWfTBZlE6qaeXOJxDX6opf4sSzses6x5W5S9Q ArHJ3ykQfPhJ+M4coTI1o6V25GNqIhBLhY2xsmLBNUQPcimyD66r2hOaKn0g6RKmqD75bsed2Q ZUs= Date: Mon, 8 Jun 2020 16:55:11 +0000 From: Joseph Myers X-X-Sender: jsm28@digraph.polyomino.org.uk To: , , , , , , , Subject: [PATCH v2 1/6] softfloat: merge floatx80_mod and floatx80_rem In-Reply-To: Message-ID: References: User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-07.mgc.mentorg.com (139.181.222.7) To svr-ies-mbx-02.mgc.mentorg.com (139.181.222.2) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=68.232.137.252; envelope-from=joseph_myers@mentor.com; helo=esa4.mentor.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/08 12:55:19 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -39 X-Spam_score: -4.0 X-Spam_bar: ---- X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The m68k-specific softfloat code includes a function floatx80_mod that is extremely similar to floatx80_rem, but computing the remainder based on truncating the quotient toward zero rather than rounding it to nearest integer. This is also useful for emulating the x87 fprem and fprem1 instructions. Change the floatx80_rem implementation into floatx80_modrem that can perform either operation, with both floatx80_rem and floatx80_mod as thin wrappers available for all targets. There does not appear to be any use for the _mod operation for other floating-point formats in QEMU (the only other architectures using _rem at all are linux-user/arm/nwfpe, for FPA emulation, and openrisc, for instructions that have been removed in the latest version of the architecture), so no change is made to the code for other formats. Signed-off-by: Joseph Myers Reviewed-by: Richard Henderson --- fpu/softfloat.c | 49 ++++++++++++++++++------ include/fpu/softfloat.h | 2 + target/m68k/softfloat.c | 83 ----------------------------------------- target/m68k/softfloat.h | 1 - 4 files changed, 40 insertions(+), 95 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6c8f2d597a..7b1ce7664f 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -5682,10 +5682,13 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float= _status *status) /*------------------------------------------------------------------------= ---- | Returns the remainder of the extended double-precision floating-point va= lue | `a' with respect to the corresponding value `b'. The operation is perfo= rmed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic, +| if 'mod' is false; if 'mod' is true, return the remainder based on trunc= ating +| the quotient toward zero instead. *-------------------------------------------------------------------------= ---*/ =20 -floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status) +floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod, + float_status *status) { bool aSign, zSign; int32_t aExp, bExp, expDiff; @@ -5731,7 +5734,7 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_s= tatus *status) expDiff =3D aExp - bExp; aSig1 =3D 0; if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; + if ( mod || expDiff < -1 ) return a; shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); expDiff =3D 0; } @@ -5763,14 +5766,16 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float= _status *status) term1 =3D 0; term0 =3D bSig; } - sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 ); - if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) - || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 ) - && ( q & 1 ) ) - ) { - aSig0 =3D alternateASig0; - aSig1 =3D alternateASig1; - zSign =3D ! zSign; + if (!mod) { + sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASi= g1 ); + if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) + || ( eq128( alternateASig0, alternateASig1, aSig0, aSig= 1 ) + && ( q & 1 ) ) + ) { + aSig0 =3D alternateASig0; + aSig1 =3D alternateASig1; + zSign =3D ! zSign; + } } return normalizeRoundAndPackFloatx80( @@ -5778,6 +5783,28 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_= status *status) =20 } =20 +/*------------------------------------------------------------------------= ---- +| Returns the remainder of the extended double-precision floating-point va= lue +| `a' with respect to the corresponding value `b'. The operation is perfo= rmed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*-------------------------------------------------------------------------= ---*/ + +floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status) +{ + return floatx80_modrem(a, b, false, status); +} + +/*------------------------------------------------------------------------= ---- +| Returns the remainder of the extended double-precision floating-point va= lue +| `a' with respect to the corresponding value `b', with the quotient trunc= ated +| toward zero. +*-------------------------------------------------------------------------= ---*/ + +floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status) +{ + return floatx80_modrem(a, b, true, status); +} + /*------------------------------------------------------------------------= ---- | Returns the square root of the extended double-precision floating-point | value `a'. The operation is performed according to the IEC/IEEE Standard diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 16ca697a73..bff6934d09 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -687,6 +687,8 @@ floatx80 floatx80_add(floatx80, floatx80, float_status = *status); floatx80 floatx80_sub(floatx80, floatx80, float_status *status); floatx80 floatx80_mul(floatx80, floatx80, float_status *status); floatx80 floatx80_div(floatx80, floatx80, float_status *status); +floatx80 floatx80_modrem(floatx80, floatx80, bool, float_status *status); +floatx80 floatx80_mod(floatx80, floatx80, float_status *status); floatx80 floatx80_rem(floatx80, floatx80, float_status *status); floatx80 floatx80_sqrt(floatx80, float_status *status); FloatRelation floatx80_compare(floatx80, floatx80, float_status *status); diff --git a/target/m68k/softfloat.c b/target/m68k/softfloat.c index 9f120cf15e..b6d0ed7acf 100644 --- a/target/m68k/softfloat.c +++ b/target/m68k/softfloat.c @@ -42,89 +42,6 @@ static floatx80 propagateFloatx80NaNOneArg(floatx80 a, f= loat_status *status) return a; } =20 -/* - * Returns the modulo remainder of the extended double-precision floating-= point - * value `a' with respect to the corresponding value `b'. - */ - -floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status) -{ - bool aSign, zSign; - int32_t aExp, bExp, expDiff; - uint64_t aSig0, aSig1, bSig; - uint64_t qTemp, term0, term1; - - aSig0 =3D extractFloatx80Frac(a); - aExp =3D extractFloatx80Exp(a); - aSign =3D extractFloatx80Sign(a); - bSig =3D extractFloatx80Frac(b); - bExp =3D extractFloatx80Exp(b); - - if (aExp =3D=3D 0x7FFF) { - if ((uint64_t) (aSig0 << 1) - || ((bExp =3D=3D 0x7FFF) && (uint64_t) (bSig << 1))) { - return propagateFloatx80NaN(a, b, status); - } - goto invalid; - } - if (bExp =3D=3D 0x7FFF) { - if ((uint64_t) (bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return a; - } - if (bExp =3D=3D 0) { - if (bSig =3D=3D 0) { - invalid: - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - if (aExp =3D=3D 0) { - if ((uint64_t) (aSig0 << 1) =3D=3D 0) { - return a; - } - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); - } - bSig |=3D UINT64_C(0x8000000000000000); - zSign =3D aSign; - expDiff =3D aExp - bExp; - aSig1 =3D 0; - if (expDiff < 0) { - return a; - } - qTemp =3D (bSig <=3D aSig0); - if (qTemp) { - aSig0 -=3D bSig; - } - expDiff -=3D 64; - while (0 < expDiff) { - qTemp =3D estimateDiv128To64(aSig0, aSig1, bSig); - qTemp =3D (2 < qTemp) ? qTemp - 2 : 0; - mul64To128(bSig, qTemp, &term0, &term1); - sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1); - shortShift128Left(aSig0, aSig1, 62, &aSig0, &aSig1); - expDiff -=3D 62; - } - expDiff +=3D 64; - if (0 < expDiff) { - qTemp =3D estimateDiv128To64(aSig0, aSig1, bSig); - qTemp =3D (2 < qTemp) ? qTemp - 2 : 0; - qTemp >>=3D 64 - expDiff; - mul64To128(bSig, qTemp << (64 - expDiff), &term0, &term1); - sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1); - shortShift128Left(0, bSig, 64 - expDiff, &term0, &term1); - while (le128(term0, term1, aSig0, aSig1)) { - ++qTemp; - sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1); - } - } - return - normalizeRoundAndPackFloatx80( - 80, zSign, bExp + expDiff, aSig0, aSig1, status); -} - /* * Returns the mantissa of the extended double-precision floating-point * value `a'. diff --git a/target/m68k/softfloat.h b/target/m68k/softfloat.h index 365ef6ac7a..4bb9567134 100644 --- a/target/m68k/softfloat.h +++ b/target/m68k/softfloat.h @@ -23,7 +23,6 @@ #define TARGET_M68K_SOFTFLOAT_H #include "fpu/softfloat.h" =20 -floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status); floatx80 floatx80_getman(floatx80 a, float_status *status); floatx80 floatx80_getexp(floatx80 a, float_status *status); floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status); --=20 2.17.1 --=20 Joseph S. Myers joseph@codesourcery.com