Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1475775/?format=api
{ "id": 1475775, "url": "http://patchwork.ozlabs.org/api/patches/1475775/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20210508014802.892561-73-richard.henderson@linaro.org/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20210508014802.892561-73-richard.henderson@linaro.org>", "list_archive_url": null, "date": "2021-05-08T01:48:02", "name": "[72/72] softfloat: Convert modrem operations to FloatParts", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "dc9fb56dc3af5da04bc1ca7f51dbbc6103e4f675", "submitter": { "id": 72104, "url": "http://patchwork.ozlabs.org/api/people/72104/?format=api", "name": "Richard Henderson", "email": "richard.henderson@linaro.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20210508014802.892561-73-richard.henderson@linaro.org/mbox/", "series": [ { "id": 242770, "url": "http://patchwork.ozlabs.org/api/series/242770/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=242770", "date": "2021-05-08T01:46:53", "name": "Convert floatx80 and float128 to FloatParts", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/242770/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1475775/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1475775/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=<UNKNOWN>)", "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=K5Ouhzh5;\n\tdkim-atps=neutral" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 4FcWns4Frtz9sTD\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 8 May 2021 12:42:56 +1000 (AEST)", "from localhost ([::1]:54206 helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1lfCvd-0005KY-Gj\n\tfor incoming@patchwork.ozlabs.org; Fri, 07 May 2021 22:42:53 -0400", "from eggs.gnu.org ([2001:470:142:3::10]:41854)\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <richard.henderson@linaro.org>)\n id 1lfC8S-0003Yg-VS\n for qemu-devel@nongnu.org; Fri, 07 May 2021 21:52:05 -0400", "from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]:52917)\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <richard.henderson@linaro.org>)\n id 1lfC8G-0005cG-8q\n for qemu-devel@nongnu.org; Fri, 07 May 2021 21:52:04 -0400", "by mail-pj1-x1031.google.com with SMTP id ge1so6202803pjb.2\n for <qemu-devel@nongnu.org>; Fri, 07 May 2021 18:51:51 -0700 (PDT)", "from localhost.localdomain ([71.212.144.24])\n by smtp.gmail.com with ESMTPSA id 204sm5861396pfw.158.2021.05.07.18.51.49\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 07 May 2021 18:51:50 -0700 (PDT)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google;\n h=from:to:cc:subject:date:message-id:in-reply-to:references\n :mime-version:content-transfer-encoding;\n bh=jyFTCsiIz4vQ/b29mHqKyxCY82vLhUnZ9Ckfj2MLd9w=;\n b=K5Ouhzh59Gfkgrr3h9fFkv4zdpIee3dmJ5BazJRK2y8CKVz+4tmrt6sN/XTXPATNdS\n J+0zI8KaJepy+9eehy42hoaUJXoXwpo5VnSQw8fPJ0Af2u8ep8jYggOAPRwP9Ks8PxRH\n SlmKtPWykgVUx9n8/TW2VbcFyhJs6AFwnjTthHMsOkzgIjeRv7QxVnPPE+tfePyPKX3y\n Hx7iyY86v71T7zZPl9i7ALrlid2vo8hY5iNi4P6b3CcnDaDdrB5jPCdUsi+mgKxTzegE\n crWFBBikbxcy7ZOisocpzVi15ifJCJbFJKWK+Mat0tU3QbH2+Ixusk/Lc1aqz+AvgNjY\n MNhg==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20161025;\n h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n :references:mime-version:content-transfer-encoding;\n bh=jyFTCsiIz4vQ/b29mHqKyxCY82vLhUnZ9Ckfj2MLd9w=;\n b=Ab+Yo3Ru103DNxuV0PockGLYJ6ZnHo2ZwYWAtJO0VWcbaJQQEyNhm09rNAWcOeGeYe\n ep9kB7p39akDKFYH3Wg/RWm8UQyThpID1lGlZEptiBSBKEwZJKs4mI2410rCBJut2/ga\n uYp2RlO8EVxahMR8XZRxuBa0cD0ILbjrAw2um+HVuhCi34xInOK29HGmjKnFDuPFyrqS\n v5n1QZ6zKr4ai9+EnINY3AvCW7xSc9WgCLV9Lx2QGpYou7AvLSGEmBsWFXukbF0d9+6R\n au/ztPn8jvlteFnp6FR6Hb9SYiTXKBPOBjpNCiLZ9GW0+NRAz2FMxlh5HYLpeJV2I6KE\n 4gBw==", "X-Gm-Message-State": "AOAM531/XeN80v6kiJvS0vgin3xN2arFt7x39kJnVfpwM5D1iJvQUxJs\n KlGdLvfecz3ykaOUJwosn7Mo+VhL+GpmGw==", "X-Google-Smtp-Source": "\n ABdhPJwIc6l3lP5LUouqmTTzioIOV3AexYUJs5b9ew7PUQ4/9skkXw/clDa7sn1MpltQgPTUxo3/wA==", "X-Received": "by 2002:a17:903:4091:b029:ec:fbd2:3192 with SMTP id\n z17-20020a1709034091b02900ecfbd23192mr12855673plc.21.1620438710496;\n Fri, 07 May 2021 18:51:50 -0700 (PDT)", "From": "Richard Henderson <richard.henderson@linaro.org>", "To": "qemu-devel@nongnu.org", "Subject": "[PATCH 72/72] softfloat: Convert modrem operations to FloatParts", "Date": "Fri, 7 May 2021 18:48:02 -0700", "Message-Id": "<20210508014802.892561-73-richard.henderson@linaro.org>", "X-Mailer": "git-send-email 2.25.1", "In-Reply-To": "<20210508014802.892561-1-richard.henderson@linaro.org>", "References": "<20210508014802.892561-1-richard.henderson@linaro.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=2607:f8b0:4864:20::1031;\n envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1031.google.com", "X-Spam_score_int": "-20", "X-Spam_score": "-2.1", "X-Spam_bar": "--", "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.23", "Precedence": "list", "List-Id": "<qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Cc": "alex.bennee@linaro.org, david@redhat.com", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "\"Qemu-devel\"\n <qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>" }, "content": "Rename to parts$N_modrem. This was the last use of a lot\nof the legacy infrastructure, so remove it as required.\n\nSigned-off-by: Richard Henderson <richard.henderson@linaro.org>\n---\n include/fpu/softfloat-macros.h | 34 +\n fpu/softfloat.c | 1339 +++++++-------------------------\n fpu/softfloat-parts.c.inc | 34 +\n fpu/softfloat-specialize.c.inc | 165 ----\n 4 files changed, 329 insertions(+), 1243 deletions(-)", "diff": "diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h\nindex ec4e27a595..81c3fe8256 100644\n--- a/include/fpu/softfloat-macros.h\n+++ b/include/fpu/softfloat-macros.h\n@@ -745,4 +745,38 @@ static inline bool ne128(uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1)\n return a0 != b0 || a1 != b1;\n }\n \n+/*\n+ * Similarly, comparisons of 192-bit values.\n+ */\n+\n+static inline bool eq192(uint64_t a0, uint64_t a1, uint64_t a2,\n+ uint64_t b0, uint64_t b1, uint64_t b2)\n+{\n+ return ((a0 ^ b0) | (a1 ^ b1) | (a2 ^ b2)) == 0;\n+}\n+\n+static inline bool le192(uint64_t a0, uint64_t a1, uint64_t a2,\n+ uint64_t b0, uint64_t b1, uint64_t b2)\n+{\n+ if (a0 != b0) {\n+ return a0 < b0;\n+ }\n+ if (a1 != b1) {\n+ return a1 < b1;\n+ }\n+ return a2 <= b2;\n+}\n+\n+static inline bool lt192(uint64_t a0, uint64_t a1, uint64_t a2,\n+ uint64_t b0, uint64_t b1, uint64_t b2)\n+{\n+ if (a0 != b0) {\n+ return a0 < b0;\n+ }\n+ if (a1 != b1) {\n+ return a1 < b1;\n+ }\n+ return a2 < b2;\n+}\n+\n #endif\ndiff --git a/fpu/softfloat.c b/fpu/softfloat.c\nindex 3823a7ec6f..7376b3470c 100644\n--- a/fpu/softfloat.c\n+++ b/fpu/softfloat.c\n@@ -401,60 +401,6 @@ float64_gen2(float64 xa, float64 xb, float_status *s,\n return soft(ua.s, ub.s, s);\n }\n \n-/*----------------------------------------------------------------------------\n-| Returns the fraction bits of the single-precision floating-point value `a'.\n-*----------------------------------------------------------------------------*/\n-\n-static inline uint32_t extractFloat32Frac(float32 a)\n-{\n- return float32_val(a) & 0x007FFFFF;\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the exponent bits of the single-precision floating-point value `a'.\n-*----------------------------------------------------------------------------*/\n-\n-static inline int extractFloat32Exp(float32 a)\n-{\n- return (float32_val(a) >> 23) & 0xFF;\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the sign bit of the single-precision floating-point value `a'.\n-*----------------------------------------------------------------------------*/\n-\n-static inline bool extractFloat32Sign(float32 a)\n-{\n- return float32_val(a) >> 31;\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the fraction bits of the double-precision floating-point value `a'.\n-*----------------------------------------------------------------------------*/\n-\n-static inline uint64_t extractFloat64Frac(float64 a)\n-{\n- return float64_val(a) & UINT64_C(0x000FFFFFFFFFFFFF);\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the exponent bits of the double-precision floating-point value `a'.\n-*----------------------------------------------------------------------------*/\n-\n-static inline int extractFloat64Exp(float64 a)\n-{\n- return (float64_val(a) >> 52) & 0x7FF;\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the sign bit of the double-precision floating-point value `a'.\n-*----------------------------------------------------------------------------*/\n-\n-static inline bool extractFloat64Sign(float64 a)\n-{\n- return float64_val(a) >> 63;\n-}\n-\n /*\n * Classify a floating point number. Everything above float_class_qnan\n * is a NaN so cls >= float_class_qnan is any NaN.\n@@ -844,6 +790,14 @@ static FloatParts128 *parts128_div(FloatParts128 *a, FloatParts128 *b,\n #define parts_div(A, B, S) \\\n PARTS_GENERIC_64_128(div, A)(A, B, S)\n \n+static FloatParts64 *parts64_modrem(FloatParts64 *a, FloatParts64 *b,\n+ uint64_t *mod_quot, float_status *s);\n+static FloatParts128 *parts128_modrem(FloatParts128 *a, FloatParts128 *b,\n+ uint64_t *mod_quot, float_status *s);\n+\n+#define parts_modrem(A, B, Q, S) \\\n+ PARTS_GENERIC_64_128(modrem, A)(A, B, Q, S)\n+\n static void parts64_sqrt(FloatParts64 *a, float_status *s, const FloatFmt *f);\n static void parts128_sqrt(FloatParts128 *a, float_status *s, const FloatFmt *f);\n \n@@ -1228,6 +1182,186 @@ static int frac256_normalize(FloatParts256 *a)\n \n #define frac_normalize(A) FRAC_GENERIC_64_128_256(normalize, A)(A)\n \n+static void frac64_modrem(FloatParts64 *a, FloatParts64 *b, uint64_t *mod_quot)\n+{\n+ uint64_t a0, a1, b0, t0, t1, q, quot;\n+ int exp_diff = a->exp - b->exp;\n+ int shift;\n+\n+ a0 = a->frac;\n+ a1 = 0;\n+\n+ if (exp_diff < -1) {\n+ if (mod_quot) {\n+ *mod_quot = 0;\n+ }\n+ return;\n+ }\n+ if (exp_diff == -1) {\n+ a0 >>= 1;\n+ exp_diff = 0;\n+ }\n+\n+ b0 = b->frac;\n+ quot = q = b0 <= a0;\n+ if (q) {\n+ a0 -= b0;\n+ }\n+\n+ exp_diff -= 64;\n+ while (exp_diff > 0) {\n+ q = estimateDiv128To64(a0, a1, b0);\n+ q = q > 2 ? q - 2 : 0;\n+ mul64To128(b0, q, &t0, &t1);\n+ sub128(a0, a1, t0, t1, &a0, &a1);\n+ shortShift128Left(a0, a1, 62, &a0, &a1);\n+ exp_diff -= 62;\n+ quot = (quot << 62) + q;\n+ }\n+\n+ exp_diff += 64;\n+ if (exp_diff > 0) {\n+ q = estimateDiv128To64(a0, a1, b0);\n+ q = q > 2 ? (q - 2) >> (64 - exp_diff) : 0;\n+ mul64To128(b0, q << (64 - exp_diff), &t0, &t1);\n+ sub128(a0, a1, t0, t1, &a0, &a1);\n+ shortShift128Left(0, b0, 64 - exp_diff, &t0, &t1);\n+ while (le128(t0, t1, a0, a1)) {\n+ ++q;\n+ sub128(a0, a1, t0, t1, &a0, &a1);\n+ }\n+ quot = (exp_diff < 64 ? quot << exp_diff : 0) + q;\n+ } else {\n+ t0 = b0;\n+ t1 = 0;\n+ }\n+\n+ if (mod_quot) {\n+ *mod_quot = quot;\n+ } else {\n+ sub128(t0, t1, a0, a1, &t0, &t1);\n+ if (lt128(t0, t1, a0, a1) ||\n+ (eq128(t0, t1, a0, a1) && (q & 1))) {\n+ a0 = t0;\n+ a1 = t1;\n+ a->sign = !a->sign;\n+ }\n+ }\n+\n+ if (likely(a0)) {\n+ shift = clz64(a0);\n+ shortShift128Left(a0, a1, shift, &a0, &a1);\n+ } else if (likely(a1)) {\n+ shift = clz64(a1);\n+ a0 = a1 << shift;\n+ a1 = 0;\n+ shift += 64;\n+ } else {\n+ a->cls = float_class_zero;\n+ return;\n+ }\n+\n+ a->exp = b->exp + exp_diff - shift;\n+ a->frac = a0 | (a1 != 0);\n+}\n+\n+static void frac128_modrem(FloatParts128 *a, FloatParts128 *b,\n+ uint64_t *mod_quot)\n+{\n+ uint64_t a0, a1, a2, b0, b1, t0, t1, t2, q, quot;\n+ int exp_diff = a->exp - b->exp;\n+ int shift;\n+\n+ a0 = a->frac_hi;\n+ a1 = a->frac_lo;\n+ a2 = 0;\n+\n+ if (exp_diff < -1) {\n+ if (mod_quot) {\n+ *mod_quot = 0;\n+ }\n+ return;\n+ }\n+ if (exp_diff == -1) {\n+ shift128Right(a0, a1, 1, &a0, &a1);\n+ exp_diff = 0;\n+ }\n+\n+ b0 = b->frac_hi;\n+ b1 = b->frac_lo;\n+\n+ quot = q = le128(b0, b1, a0, a1);\n+ if (q) {\n+ sub128(a0, a1, b0, b1, &a0, &a1);\n+ }\n+\n+ exp_diff -= 64;\n+ while (exp_diff > 0) {\n+ q = estimateDiv128To64(a0, a1, b0);\n+ q = q > 4 ? q - 4 : 0;\n+ mul128By64To192(b0, b1, q, &t0, &t1, &t2);\n+ sub192(a0, a1, a2, t0, t1, t2, &a0, &a1, &a2);\n+ shortShift192Left(a0, a1, a2, 61, &a0, &a1, &a2);\n+ exp_diff -= 61;\n+ quot = (quot << 61) + q;\n+ }\n+\n+ exp_diff += 64;\n+ if (exp_diff > 0) {\n+ q = estimateDiv128To64(a0, a1, b0);\n+ q = q > 4 ? (q - 4) >> (64 - exp_diff) : 0;\n+ mul128By64To192(b0, b1, q << (64 - exp_diff), &t0, &t1, &t2);\n+ sub192(a0, a1, a2, t0, t1, t2, &a0, &a1, &a2);\n+ shortShift192Left(0, b0, b1, 64 - exp_diff, &t0, &t1, &t2);\n+ while (le192(t0, t1, t2, a0, a1, a2)) {\n+ ++q;\n+ sub192(a0, a1, a2, t0, t1, t2, &a0, &a1, &a2);\n+ }\n+ quot = (exp_diff < 64 ? quot << exp_diff : 0) + q;\n+ } else {\n+ t0 = b0;\n+ t1 = b1;\n+ t2 = 0;\n+ }\n+\n+ if (mod_quot) {\n+ *mod_quot = quot;\n+ } else {\n+ sub192(t0, t1, t2, a0, a1, a2, &t0, &t1, &t2);\n+ if (lt192(t0, t1, t2, a0, a1, a2) ||\n+ (eq192(t0, t1, t2, a0, a1, a2) && (q & 1))) {\n+ a0 = t0;\n+ a1 = t1;\n+ a2 = t2;\n+ a->sign = !a->sign;\n+ }\n+ }\n+\n+ if (likely(a0)) {\n+ shift = clz64(a0);\n+ shortShift192Left(a0, a1, a2, shift, &a0, &a1, &a2);\n+ } else if (likely(a1)) {\n+ shift = clz64(a1);\n+ shortShift128Left(a1, a2, shift, &a0, &a1);\n+ a2 = 0;\n+ shift += 64;\n+ } else if (likely(a2)) {\n+ shift = clz64(a2);\n+ a0 = a2 << shift;\n+ a1 = a2 = 0;\n+ shift += 128;\n+ } else {\n+ a->cls = float_class_zero;\n+ return;\n+ }\n+\n+ a->exp = b->exp + exp_diff - shift;\n+ a->frac_hi = a0;\n+ a->frac_lo = a1 | (a2 != 0);\n+}\n+\n+#define frac_modrem(A, B, Q) FRAC_GENERIC_64_128(modrem, A)(A, B, Q)\n+\n static void frac64_shl(FloatParts64 *a, int c)\n {\n a->frac <<= c;\n@@ -2312,6 +2446,79 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)\n return floatx80_round_pack_canonical(pr, status);\n }\n \n+/*\n+ * Remainder\n+ */\n+\n+float32 float32_rem(float32 a, float32 b, float_status *status)\n+{\n+ FloatParts64 pa, pb, *pr;\n+\n+ float32_unpack_canonical(&pa, a, status);\n+ float32_unpack_canonical(&pb, b, status);\n+ pr = parts_modrem(&pa, &pb, NULL, status);\n+\n+ return float32_round_pack_canonical(pr, status);\n+}\n+\n+float64 float64_rem(float64 a, float64 b, float_status *status)\n+{\n+ FloatParts64 pa, pb, *pr;\n+\n+ float64_unpack_canonical(&pa, a, status);\n+ float64_unpack_canonical(&pb, b, status);\n+ pr = parts_modrem(&pa, &pb, NULL, status);\n+\n+ return float64_round_pack_canonical(pr, status);\n+}\n+\n+float128 float128_rem(float128 a, float128 b, float_status *status)\n+{\n+ FloatParts128 pa, pb, *pr;\n+\n+ float128_unpack_canonical(&pa, a, status);\n+ float128_unpack_canonical(&pb, b, status);\n+ pr = parts_modrem(&pa, &pb, NULL, status);\n+\n+ return float128_round_pack_canonical(pr, status);\n+}\n+\n+/*\n+ * Returns the remainder of the extended double-precision floating-point value\n+ * `a' with respect to the corresponding value `b'.\n+ * If 'mod' is false, the operation is performed according to the IEC/IEEE\n+ * Standard for Binary Floating-Point Arithmetic. If 'mod' is true, return\n+ * the remainder based on truncating the quotient toward zero instead and\n+ * *quotient is set to the low 64 bits of the absolute value of the integer\n+ * quotient.\n+ */\n+floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,\n+ uint64_t *quotient, float_status *status)\n+{\n+ FloatParts128 pa, pb, *pr;\n+\n+ *quotient = 0;\n+ if (!floatx80_unpack_canonical(&pa, a, status) ||\n+ !floatx80_unpack_canonical(&pb, b, status)) {\n+ return floatx80_default_nan(status);\n+ }\n+ pr = parts_modrem(&pa, &pb, mod ? quotient : NULL, status);\n+\n+ return floatx80_round_pack_canonical(pr, status);\n+}\n+\n+floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)\n+{\n+ uint64_t quotient;\n+ return floatx80_modrem(a, b, false, "ient, status);\n+}\n+\n+floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)\n+{\n+ uint64_t quotient;\n+ return floatx80_modrem(a, b, true, "ient, status);\n+}\n+\n /*\n * Float to Float conversions\n *\n@@ -4264,300 +4471,6 @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status)\n return a;\n }\n \n-/*----------------------------------------------------------------------------\n-| Normalizes the subnormal single-precision floating-point value represented\n-| by the denormalized significand `aSig'. The normalized exponent and\n-| significand are stored at the locations pointed to by `zExpPtr' and\n-| `zSigPtr', respectively.\n-*----------------------------------------------------------------------------*/\n-\n-static void\n- normalizeFloat32Subnormal(uint32_t aSig, int *zExpPtr, uint32_t *zSigPtr)\n-{\n- int8_t shiftCount;\n-\n- shiftCount = clz32(aSig) - 8;\n- *zSigPtr = aSig<<shiftCount;\n- *zExpPtr = 1 - shiftCount;\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',\n-| and significand `zSig', and returns the proper single-precision floating-\n-| point value corresponding to the abstract input. Ordinarily, the abstract\n-| value is simply rounded and packed into the single-precision format, with\n-| the inexact exception raised if the abstract input cannot be represented\n-| exactly. However, if the abstract value is too large, the overflow and\n-| inexact exceptions are raised and an infinity or maximal finite value is\n-| returned. If the abstract value is too small, the input value is rounded to\n-| a subnormal number, and the underflow and inexact exceptions are raised if\n-| the abstract input cannot be represented exactly as a subnormal single-\n-| precision floating-point number.\n-| The input significand `zSig' has its binary point between bits 30\n-| and 29, which is 7 bits to the left of the usual location. This shifted\n-| significand must be normalized or smaller. If `zSig' is not normalized,\n-| `zExp' must be 0; in that case, the result returned is a subnormal number,\n-| and it must not require rounding. In the usual case that `zSig' is\n-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.\n-| The handling of underflow and overflow follows the IEC/IEEE Standard for\n-| Binary Floating-Point Arithmetic.\n-*----------------------------------------------------------------------------*/\n-\n-static float32 roundAndPackFloat32(bool zSign, int zExp, uint32_t zSig,\n- float_status *status)\n-{\n- int8_t roundingMode;\n- bool roundNearestEven;\n- int8_t roundIncrement, roundBits;\n- bool isTiny;\n-\n- roundingMode = status->float_rounding_mode;\n- roundNearestEven = ( roundingMode == float_round_nearest_even );\n- switch (roundingMode) {\n- case float_round_nearest_even:\n- case float_round_ties_away:\n- roundIncrement = 0x40;\n- break;\n- case float_round_to_zero:\n- roundIncrement = 0;\n- break;\n- case float_round_up:\n- roundIncrement = zSign ? 0 : 0x7f;\n- break;\n- case float_round_down:\n- roundIncrement = zSign ? 0x7f : 0;\n- break;\n- case float_round_to_odd:\n- roundIncrement = zSig & 0x80 ? 0 : 0x7f;\n- break;\n- default:\n- abort();\n- break;\n- }\n- roundBits = zSig & 0x7F;\n- if ( 0xFD <= (uint16_t) zExp ) {\n- if ( ( 0xFD < zExp )\n- || ( ( zExp == 0xFD )\n- && ( (int32_t) ( zSig + roundIncrement ) < 0 ) )\n- ) {\n- bool overflow_to_inf = roundingMode != float_round_to_odd &&\n- roundIncrement != 0;\n- float_raise(float_flag_overflow | float_flag_inexact, status);\n- return packFloat32(zSign, 0xFF, -!overflow_to_inf);\n- }\n- if ( zExp < 0 ) {\n- if (status->flush_to_zero) {\n- float_raise(float_flag_output_denormal, status);\n- return packFloat32(zSign, 0, 0);\n- }\n- isTiny = status->tininess_before_rounding\n- || (zExp < -1)\n- || (zSig + roundIncrement < 0x80000000);\n- shift32RightJamming( zSig, - zExp, &zSig );\n- zExp = 0;\n- roundBits = zSig & 0x7F;\n- if (isTiny && roundBits) {\n- float_raise(float_flag_underflow, status);\n- }\n- if (roundingMode == float_round_to_odd) {\n- /*\n- * For round-to-odd case, the roundIncrement depends on\n- * zSig which just changed.\n- */\n- roundIncrement = zSig & 0x80 ? 0 : 0x7f;\n- }\n- }\n- }\n- if (roundBits) {\n- float_raise(float_flag_inexact, status);\n- }\n- zSig = ( zSig + roundIncrement )>>7;\n- if (!(roundBits ^ 0x40) && roundNearestEven) {\n- zSig &= ~1;\n- }\n- if ( zSig == 0 ) zExp = 0;\n- return packFloat32( zSign, zExp, zSig );\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',\n-| and significand `zSig', and returns the proper single-precision floating-\n-| point value corresponding to the abstract input. This routine is just like\n-| `roundAndPackFloat32' except that `zSig' does not have to be normalized.\n-| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''\n-| floating-point exponent.\n-*----------------------------------------------------------------------------*/\n-\n-static float32\n- normalizeRoundAndPackFloat32(bool zSign, int zExp, uint32_t zSig,\n- float_status *status)\n-{\n- int8_t shiftCount;\n-\n- shiftCount = clz32(zSig) - 1;\n- return roundAndPackFloat32(zSign, zExp - shiftCount, zSig<<shiftCount,\n- status);\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Normalizes the subnormal double-precision floating-point value represented\n-| by the denormalized significand `aSig'. The normalized exponent and\n-| significand are stored at the locations pointed to by `zExpPtr' and\n-| `zSigPtr', respectively.\n-*----------------------------------------------------------------------------*/\n-\n-static void\n- normalizeFloat64Subnormal(uint64_t aSig, int *zExpPtr, uint64_t *zSigPtr)\n-{\n- int8_t shiftCount;\n-\n- shiftCount = clz64(aSig) - 11;\n- *zSigPtr = aSig<<shiftCount;\n- *zExpPtr = 1 - shiftCount;\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a\n-| double-precision floating-point value, returning the result. After being\n-| shifted into the proper positions, the three fields are simply added\n-| together to form the result. This means that any integer portion of `zSig'\n-| will be added into the exponent. Since a properly normalized significand\n-| will have an integer portion equal to 1, the `zExp' input should be 1 less\n-| than the desired result exponent whenever `zSig' is a complete, normalized\n-| significand.\n-*----------------------------------------------------------------------------*/\n-\n-static inline float64 packFloat64(bool zSign, int zExp, uint64_t zSig)\n-{\n-\n- return make_float64(\n- ( ( (uint64_t) zSign )<<63 ) + ( ( (uint64_t) zExp )<<52 ) + zSig);\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',\n-| and significand `zSig', and returns the proper double-precision floating-\n-| point value corresponding to the abstract input. Ordinarily, the abstract\n-| value is simply rounded and packed into the double-precision format, with\n-| the inexact exception raised if the abstract input cannot be represented\n-| exactly. However, if the abstract value is too large, the overflow and\n-| inexact exceptions are raised and an infinity or maximal finite value is\n-| returned. If the abstract value is too small, the input value is rounded to\n-| a subnormal number, and the underflow and inexact exceptions are raised if\n-| the abstract input cannot be represented exactly as a subnormal double-\n-| precision floating-point number.\n-| The input significand `zSig' has its binary point between bits 62\n-| and 61, which is 10 bits to the left of the usual location. This shifted\n-| significand must be normalized or smaller. If `zSig' is not normalized,\n-| `zExp' must be 0; in that case, the result returned is a subnormal number,\n-| and it must not require rounding. In the usual case that `zSig' is\n-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.\n-| The handling of underflow and overflow follows the IEC/IEEE Standard for\n-| Binary Floating-Point Arithmetic.\n-*----------------------------------------------------------------------------*/\n-\n-static float64 roundAndPackFloat64(bool zSign, int zExp, uint64_t zSig,\n- float_status *status)\n-{\n- int8_t roundingMode;\n- bool roundNearestEven;\n- int roundIncrement, roundBits;\n- bool isTiny;\n-\n- roundingMode = status->float_rounding_mode;\n- roundNearestEven = ( roundingMode == float_round_nearest_even );\n- switch (roundingMode) {\n- case float_round_nearest_even:\n- case float_round_ties_away:\n- roundIncrement = 0x200;\n- break;\n- case float_round_to_zero:\n- roundIncrement = 0;\n- break;\n- case float_round_up:\n- roundIncrement = zSign ? 0 : 0x3ff;\n- break;\n- case float_round_down:\n- roundIncrement = zSign ? 0x3ff : 0;\n- break;\n- case float_round_to_odd:\n- roundIncrement = (zSig & 0x400) ? 0 : 0x3ff;\n- break;\n- default:\n- abort();\n- }\n- roundBits = zSig & 0x3FF;\n- if ( 0x7FD <= (uint16_t) zExp ) {\n- if ( ( 0x7FD < zExp )\n- || ( ( zExp == 0x7FD )\n- && ( (int64_t) ( zSig + roundIncrement ) < 0 ) )\n- ) {\n- bool overflow_to_inf = roundingMode != float_round_to_odd &&\n- roundIncrement != 0;\n- float_raise(float_flag_overflow | float_flag_inexact, status);\n- return packFloat64(zSign, 0x7FF, -(!overflow_to_inf));\n- }\n- if ( zExp < 0 ) {\n- if (status->flush_to_zero) {\n- float_raise(float_flag_output_denormal, status);\n- return packFloat64(zSign, 0, 0);\n- }\n- isTiny = status->tininess_before_rounding\n- || (zExp < -1)\n- || (zSig + roundIncrement < UINT64_C(0x8000000000000000));\n- shift64RightJamming( zSig, - zExp, &zSig );\n- zExp = 0;\n- roundBits = zSig & 0x3FF;\n- if (isTiny && roundBits) {\n- float_raise(float_flag_underflow, status);\n- }\n- if (roundingMode == float_round_to_odd) {\n- /*\n- * For round-to-odd case, the roundIncrement depends on\n- * zSig which just changed.\n- */\n- roundIncrement = (zSig & 0x400) ? 0 : 0x3ff;\n- }\n- }\n- }\n- if (roundBits) {\n- float_raise(float_flag_inexact, status);\n- }\n- zSig = ( zSig + roundIncrement )>>10;\n- if (!(roundBits ^ 0x200) && roundNearestEven) {\n- zSig &= ~1;\n- }\n- if ( zSig == 0 ) zExp = 0;\n- return packFloat64( zSign, zExp, zSig );\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',\n-| and significand `zSig', and returns the proper double-precision floating-\n-| point value corresponding to the abstract input. This routine is just like\n-| `roundAndPackFloat64' except that `zSig' does not have to be normalized.\n-| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''\n-| floating-point exponent.\n-*----------------------------------------------------------------------------*/\n-\n-static float64\n- normalizeRoundAndPackFloat64(bool zSign, int zExp, uint64_t zSig,\n- float_status *status)\n-{\n- int8_t shiftCount;\n-\n- shiftCount = clz64(zSig) - 1;\n- return roundAndPackFloat64(zSign, zExp - shiftCount, zSig<<shiftCount,\n- status);\n-\n-}\n-\n /*----------------------------------------------------------------------------\n | Normalizes the subnormal extended double-precision floating-point value\n | represented by the denormalized significand `aSig'. The normalized exponent\n@@ -4818,388 +4731,6 @@ floatx80 normalizeRoundAndPackFloatx80(FloatX80RoundPrec roundingPrecision,\n \n }\n \n-/*----------------------------------------------------------------------------\n-| Returns the least-significant 64 fraction bits of the quadruple-precision\n-| floating-point value `a'.\n-*----------------------------------------------------------------------------*/\n-\n-static inline uint64_t extractFloat128Frac1( float128 a )\n-{\n-\n- return a.low;\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the most-significant 48 fraction bits of the quadruple-precision\n-| floating-point value `a'.\n-*----------------------------------------------------------------------------*/\n-\n-static inline uint64_t extractFloat128Frac0( float128 a )\n-{\n-\n- return a.high & UINT64_C(0x0000FFFFFFFFFFFF);\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the exponent bits of the quadruple-precision floating-point value\n-| `a'.\n-*----------------------------------------------------------------------------*/\n-\n-static inline int32_t extractFloat128Exp( float128 a )\n-{\n-\n- return ( a.high>>48 ) & 0x7FFF;\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the sign bit of the quadruple-precision floating-point value `a'.\n-*----------------------------------------------------------------------------*/\n-\n-static inline bool extractFloat128Sign(float128 a)\n-{\n- return a.high >> 63;\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Normalizes the subnormal quadruple-precision floating-point value\n-| represented by the denormalized significand formed by the concatenation of\n-| `aSig0' and `aSig1'. The normalized exponent is stored at the location\n-| pointed to by `zExpPtr'. The most significant 49 bits of the normalized\n-| significand are stored at the location pointed to by `zSig0Ptr', and the\n-| least significant 64 bits of the normalized significand are stored at the\n-| location pointed to by `zSig1Ptr'.\n-*----------------------------------------------------------------------------*/\n-\n-static void\n- normalizeFloat128Subnormal(\n- uint64_t aSig0,\n- uint64_t aSig1,\n- int32_t *zExpPtr,\n- uint64_t *zSig0Ptr,\n- uint64_t *zSig1Ptr\n- )\n-{\n- int8_t shiftCount;\n-\n- if ( aSig0 == 0 ) {\n- shiftCount = clz64(aSig1) - 15;\n- if ( shiftCount < 0 ) {\n- *zSig0Ptr = aSig1>>( - shiftCount );\n- *zSig1Ptr = aSig1<<( shiftCount & 63 );\n- }\n- else {\n- *zSig0Ptr = aSig1<<shiftCount;\n- *zSig1Ptr = 0;\n- }\n- *zExpPtr = - shiftCount - 63;\n- }\n- else {\n- shiftCount = clz64(aSig0) - 15;\n- shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );\n- *zExpPtr = 1 - shiftCount;\n- }\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Packs the sign `zSign', the exponent `zExp', and the significand formed\n-| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision\n-| floating-point value, returning the result. After being shifted into the\n-| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply\n-| added together to form the most significant 32 bits of the result. This\n-| means that any integer portion of `zSig0' will be added into the exponent.\n-| Since a properly normalized significand will have an integer portion equal\n-| to 1, the `zExp' input should be 1 less than the desired result exponent\n-| whenever `zSig0' and `zSig1' concatenated form a complete, normalized\n-| significand.\n-*----------------------------------------------------------------------------*/\n-\n-static inline float128\n-packFloat128(bool zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1)\n-{\n- float128 z;\n-\n- z.low = zSig1;\n- z.high = ((uint64_t)zSign << 63) + ((uint64_t)zExp << 48) + zSig0;\n- return z;\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',\n-| and extended significand formed by the concatenation of `zSig0', `zSig1',\n-| and `zSig2', and returns the proper quadruple-precision floating-point value\n-| corresponding to the abstract input. Ordinarily, the abstract value is\n-| simply rounded and packed into the quadruple-precision format, with the\n-| inexact exception raised if the abstract input cannot be represented\n-| exactly. However, if the abstract value is too large, the overflow and\n-| inexact exceptions are raised and an infinity or maximal finite value is\n-| returned. If the abstract value is too small, the input value is rounded to\n-| a subnormal number, and the underflow and inexact exceptions are raised if\n-| the abstract input cannot be represented exactly as a subnormal quadruple-\n-| precision floating-point number.\n-| The input significand must be normalized or smaller. If the input\n-| significand is not normalized, `zExp' must be 0; in that case, the result\n-| returned is a subnormal number, and it must not require rounding. In the\n-| usual case that the input significand is normalized, `zExp' must be 1 less\n-| than the ``true'' floating-point exponent. The handling of underflow and\n-| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.\n-*----------------------------------------------------------------------------*/\n-\n-static float128 roundAndPackFloat128(bool zSign, int32_t zExp,\n- uint64_t zSig0, uint64_t zSig1,\n- uint64_t zSig2, float_status *status)\n-{\n- int8_t roundingMode;\n- bool roundNearestEven, increment, isTiny;\n-\n- roundingMode = status->float_rounding_mode;\n- roundNearestEven = ( roundingMode == float_round_nearest_even );\n- switch (roundingMode) {\n- case float_round_nearest_even:\n- case float_round_ties_away:\n- increment = ((int64_t)zSig2 < 0);\n- break;\n- case float_round_to_zero:\n- increment = 0;\n- break;\n- case float_round_up:\n- increment = !zSign && zSig2;\n- break;\n- case float_round_down:\n- increment = zSign && zSig2;\n- break;\n- case float_round_to_odd:\n- increment = !(zSig1 & 0x1) && zSig2;\n- break;\n- default:\n- abort();\n- }\n- if ( 0x7FFD <= (uint32_t) zExp ) {\n- if ( ( 0x7FFD < zExp )\n- || ( ( zExp == 0x7FFD )\n- && eq128(\n- UINT64_C(0x0001FFFFFFFFFFFF),\n- UINT64_C(0xFFFFFFFFFFFFFFFF),\n- zSig0,\n- zSig1\n- )\n- && increment\n- )\n- ) {\n- float_raise(float_flag_overflow | float_flag_inexact, status);\n- if ( ( roundingMode == float_round_to_zero )\n- || ( zSign && ( roundingMode == float_round_up ) )\n- || ( ! zSign && ( roundingMode == float_round_down ) )\n- || (roundingMode == float_round_to_odd)\n- ) {\n- return\n- packFloat128(\n- zSign,\n- 0x7FFE,\n- UINT64_C(0x0000FFFFFFFFFFFF),\n- UINT64_C(0xFFFFFFFFFFFFFFFF)\n- );\n- }\n- return packFloat128( zSign, 0x7FFF, 0, 0 );\n- }\n- if ( zExp < 0 ) {\n- if (status->flush_to_zero) {\n- float_raise(float_flag_output_denormal, status);\n- return packFloat128(zSign, 0, 0, 0);\n- }\n- isTiny = status->tininess_before_rounding\n- || (zExp < -1)\n- || !increment\n- || lt128(zSig0, zSig1,\n- UINT64_C(0x0001FFFFFFFFFFFF),\n- UINT64_C(0xFFFFFFFFFFFFFFFF));\n- shift128ExtraRightJamming(\n- zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );\n- zExp = 0;\n- if (isTiny && zSig2) {\n- float_raise(float_flag_underflow, status);\n- }\n- switch (roundingMode) {\n- case float_round_nearest_even:\n- case float_round_ties_away:\n- increment = ((int64_t)zSig2 < 0);\n- break;\n- case float_round_to_zero:\n- increment = 0;\n- break;\n- case float_round_up:\n- increment = !zSign && zSig2;\n- break;\n- case float_round_down:\n- increment = zSign && zSig2;\n- break;\n- case float_round_to_odd:\n- increment = !(zSig1 & 0x1) && zSig2;\n- break;\n- default:\n- abort();\n- }\n- }\n- }\n- if (zSig2) {\n- float_raise(float_flag_inexact, status);\n- }\n- if ( increment ) {\n- add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );\n- if ((zSig2 + zSig2 == 0) && roundNearestEven) {\n- zSig1 &= ~1;\n- }\n- }\n- else {\n- if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;\n- }\n- return packFloat128( zSign, zExp, zSig0, zSig1 );\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',\n-| and significand formed by the concatenation of `zSig0' and `zSig1', and\n-| returns the proper quadruple-precision floating-point value corresponding\n-| to the abstract input. This routine is just like `roundAndPackFloat128'\n-| except that the input significand has fewer bits and does not have to be\n-| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-\n-| point exponent.\n-*----------------------------------------------------------------------------*/\n-\n-static float128 normalizeRoundAndPackFloat128(bool zSign, int32_t zExp,\n- uint64_t zSig0, uint64_t zSig1,\n- float_status *status)\n-{\n- int8_t shiftCount;\n- uint64_t zSig2;\n-\n- if ( zSig0 == 0 ) {\n- zSig0 = zSig1;\n- zSig1 = 0;\n- zExp -= 64;\n- }\n- shiftCount = clz64(zSig0) - 15;\n- if ( 0 <= shiftCount ) {\n- zSig2 = 0;\n- shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );\n- }\n- else {\n- shift128ExtraRightJamming(\n- zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );\n- }\n- zExp -= shiftCount;\n- return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status);\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the remainder of the single-precision floating-point value `a'\n-| with respect to the corresponding value `b'. The operation is performed\n-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.\n-*----------------------------------------------------------------------------*/\n-\n-float32 float32_rem(float32 a, float32 b, float_status *status)\n-{\n- bool aSign, zSign;\n- int aExp, bExp, expDiff;\n- uint32_t aSig, bSig;\n- uint32_t q;\n- uint64_t aSig64, bSig64, q64;\n- uint32_t alternateASig;\n- int32_t sigMean;\n- a = float32_squash_input_denormal(a, status);\n- b = float32_squash_input_denormal(b, status);\n-\n- aSig = extractFloat32Frac( a );\n- aExp = extractFloat32Exp( a );\n- aSign = extractFloat32Sign( a );\n- bSig = extractFloat32Frac( b );\n- bExp = extractFloat32Exp( b );\n- if ( aExp == 0xFF ) {\n- if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {\n- return propagateFloat32NaN(a, b, status);\n- }\n- float_raise(float_flag_invalid, status);\n- return float32_default_nan(status);\n- }\n- if ( bExp == 0xFF ) {\n- if (bSig) {\n- return propagateFloat32NaN(a, b, status);\n- }\n- return a;\n- }\n- if ( bExp == 0 ) {\n- if ( bSig == 0 ) {\n- float_raise(float_flag_invalid, status);\n- return float32_default_nan(status);\n- }\n- normalizeFloat32Subnormal( bSig, &bExp, &bSig );\n- }\n- if ( aExp == 0 ) {\n- if ( aSig == 0 ) return a;\n- normalizeFloat32Subnormal( aSig, &aExp, &aSig );\n- }\n- expDiff = aExp - bExp;\n- aSig |= 0x00800000;\n- bSig |= 0x00800000;\n- if ( expDiff < 32 ) {\n- aSig <<= 8;\n- bSig <<= 8;\n- if ( expDiff < 0 ) {\n- if ( expDiff < -1 ) return a;\n- aSig >>= 1;\n- }\n- q = ( bSig <= aSig );\n- if ( q ) aSig -= bSig;\n- if ( 0 < expDiff ) {\n- q = ( ( (uint64_t) aSig )<<32 ) / bSig;\n- q >>= 32 - expDiff;\n- bSig >>= 2;\n- aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;\n- }\n- else {\n- aSig >>= 2;\n- bSig >>= 2;\n- }\n- }\n- else {\n- if ( bSig <= aSig ) aSig -= bSig;\n- aSig64 = ( (uint64_t) aSig )<<40;\n- bSig64 = ( (uint64_t) bSig )<<40;\n- expDiff -= 64;\n- while ( 0 < expDiff ) {\n- q64 = estimateDiv128To64( aSig64, 0, bSig64 );\n- q64 = ( 2 < q64 ) ? q64 - 2 : 0;\n- aSig64 = - ( ( bSig * q64 )<<38 );\n- expDiff -= 62;\n- }\n- expDiff += 64;\n- q64 = estimateDiv128To64( aSig64, 0, bSig64 );\n- q64 = ( 2 < q64 ) ? q64 - 2 : 0;\n- q = q64>>( 64 - expDiff );\n- bSig <<= 6;\n- aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;\n- }\n- do {\n- alternateASig = aSig;\n- ++q;\n- aSig -= bSig;\n- } while ( 0 <= (int32_t) aSig );\n- sigMean = aSig + alternateASig;\n- if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {\n- aSig = alternateASig;\n- }\n- zSign = ( (int32_t) aSig < 0 );\n- if ( zSign ) aSig = - aSig;\n- return normalizeRoundAndPackFloat32(aSign ^ zSign, bExp, aSig, status);\n-}\n-\n-\n-\n /*----------------------------------------------------------------------------\n | Returns the binary exponential of the single-precision floating-point value\n | `a'. The operation is performed according to the IEC/IEEE Standard for\n@@ -5275,94 +4806,6 @@ float32 float32_exp2(float32 a, float_status *status)\n return float32_round_pack_canonical(&rp, status);\n }\n \n-/*----------------------------------------------------------------------------\n-| Returns the remainder of the double-precision floating-point value `a'\n-| with respect to the corresponding value `b'. The operation is performed\n-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.\n-*----------------------------------------------------------------------------*/\n-\n-float64 float64_rem(float64 a, float64 b, float_status *status)\n-{\n- bool aSign, zSign;\n- int aExp, bExp, expDiff;\n- uint64_t aSig, bSig;\n- uint64_t q, alternateASig;\n- int64_t sigMean;\n-\n- a = float64_squash_input_denormal(a, status);\n- b = float64_squash_input_denormal(b, status);\n- aSig = extractFloat64Frac( a );\n- aExp = extractFloat64Exp( a );\n- aSign = extractFloat64Sign( a );\n- bSig = extractFloat64Frac( b );\n- bExp = extractFloat64Exp( b );\n- if ( aExp == 0x7FF ) {\n- if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {\n- return propagateFloat64NaN(a, b, status);\n- }\n- float_raise(float_flag_invalid, status);\n- return float64_default_nan(status);\n- }\n- if ( bExp == 0x7FF ) {\n- if (bSig) {\n- return propagateFloat64NaN(a, b, status);\n- }\n- return a;\n- }\n- if ( bExp == 0 ) {\n- if ( bSig == 0 ) {\n- float_raise(float_flag_invalid, status);\n- return float64_default_nan(status);\n- }\n- normalizeFloat64Subnormal( bSig, &bExp, &bSig );\n- }\n- if ( aExp == 0 ) {\n- if ( aSig == 0 ) return a;\n- normalizeFloat64Subnormal( aSig, &aExp, &aSig );\n- }\n- expDiff = aExp - bExp;\n- aSig = (aSig | UINT64_C(0x0010000000000000)) << 11;\n- bSig = (bSig | UINT64_C(0x0010000000000000)) << 11;\n- if ( expDiff < 0 ) {\n- if ( expDiff < -1 ) return a;\n- aSig >>= 1;\n- }\n- q = ( bSig <= aSig );\n- if ( q ) aSig -= bSig;\n- expDiff -= 64;\n- while ( 0 < expDiff ) {\n- q = estimateDiv128To64( aSig, 0, bSig );\n- q = ( 2 < q ) ? q - 2 : 0;\n- aSig = - ( ( bSig>>2 ) * q );\n- expDiff -= 62;\n- }\n- expDiff += 64;\n- if ( 0 < expDiff ) {\n- q = estimateDiv128To64( aSig, 0, bSig );\n- q = ( 2 < q ) ? q - 2 : 0;\n- q >>= 64 - expDiff;\n- bSig >>= 2;\n- aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;\n- }\n- else {\n- aSig >>= 2;\n- bSig >>= 2;\n- }\n- do {\n- alternateASig = aSig;\n- ++q;\n- aSig -= bSig;\n- } while ( 0 <= (int64_t) aSig );\n- sigMean = aSig + alternateASig;\n- if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {\n- aSig = alternateASig;\n- }\n- zSign = ( (int64_t) aSig < 0 );\n- if ( zSign ) aSig = - aSig;\n- return normalizeRoundAndPackFloat64(aSign ^ zSign, bExp, aSig, status);\n-\n-}\n-\n /*----------------------------------------------------------------------------\n | Rounds the extended double-precision floating-point value `a'\n | to the precision provided by floatx80_rounding_precision and returns the\n@@ -5381,266 +4824,6 @@ floatx80 floatx80_round(floatx80 a, float_status *status)\n return floatx80_round_pack_canonical(&p, status);\n }\n \n-/*----------------------------------------------------------------------------\n-| Returns the remainder of the extended double-precision floating-point value\n-| `a' with respect to the corresponding value `b'. The operation is performed\n-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic,\n-| if 'mod' is false; if 'mod' is true, return the remainder based on truncating\n-| the quotient toward zero instead. '*quotient' is set to the low 64 bits of\n-| the absolute value of the integer quotient.\n-*----------------------------------------------------------------------------*/\n-\n-floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod, uint64_t *quotient,\n- float_status *status)\n-{\n- bool aSign, zSign;\n- int32_t aExp, bExp, expDiff, aExpOrig;\n- uint64_t aSig0, aSig1, bSig;\n- uint64_t q, term0, term1, alternateASig0, alternateASig1;\n-\n- *quotient = 0;\n- if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {\n- float_raise(float_flag_invalid, status);\n- return floatx80_default_nan(status);\n- }\n- aSig0 = extractFloatx80Frac( a );\n- aExpOrig = aExp = extractFloatx80Exp( a );\n- aSign = extractFloatx80Sign( a );\n- bSig = extractFloatx80Frac( b );\n- bExp = extractFloatx80Exp( b );\n- if ( aExp == 0x7FFF ) {\n- if ( (uint64_t) ( aSig0<<1 )\n- || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {\n- return propagateFloatx80NaN(a, b, status);\n- }\n- goto invalid;\n- }\n- if ( bExp == 0x7FFF ) {\n- if ((uint64_t)(bSig << 1)) {\n- return propagateFloatx80NaN(a, b, status);\n- }\n- if (aExp == 0 && aSig0 >> 63) {\n- /*\n- * Pseudo-denormal argument must be returned in normalized\n- * form.\n- */\n- return packFloatx80(aSign, 1, aSig0);\n- }\n- return a;\n- }\n- if ( bExp == 0 ) {\n- if ( bSig == 0 ) {\n- invalid:\n- float_raise(float_flag_invalid, status);\n- return floatx80_default_nan(status);\n- }\n- normalizeFloatx80Subnormal( bSig, &bExp, &bSig );\n- }\n- if ( aExp == 0 ) {\n- if ( aSig0 == 0 ) return a;\n- normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );\n- }\n- zSign = aSign;\n- expDiff = aExp - bExp;\n- aSig1 = 0;\n- if ( expDiff < 0 ) {\n- if ( mod || expDiff < -1 ) {\n- if (aExp == 1 && aExpOrig == 0) {\n- /*\n- * Pseudo-denormal argument must be returned in\n- * normalized form.\n- */\n- return packFloatx80(aSign, aExp, aSig0);\n- }\n- return a;\n- }\n- shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );\n- expDiff = 0;\n- }\n- *quotient = q = ( bSig <= aSig0 );\n- if ( q ) aSig0 -= bSig;\n- expDiff -= 64;\n- while ( 0 < expDiff ) {\n- q = estimateDiv128To64( aSig0, aSig1, bSig );\n- q = ( 2 < q ) ? q - 2 : 0;\n- mul64To128( bSig, q, &term0, &term1 );\n- sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );\n- shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );\n- expDiff -= 62;\n- *quotient <<= 62;\n- *quotient += q;\n- }\n- expDiff += 64;\n- if ( 0 < expDiff ) {\n- q = estimateDiv128To64( aSig0, aSig1, bSig );\n- q = ( 2 < q ) ? q - 2 : 0;\n- q >>= 64 - expDiff;\n- mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );\n- sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );\n- shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );\n- while ( le128( term0, term1, aSig0, aSig1 ) ) {\n- ++q;\n- sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );\n- }\n- if (expDiff < 64) {\n- *quotient <<= expDiff;\n- } else {\n- *quotient = 0;\n- }\n- *quotient += q;\n- }\n- else {\n- term1 = 0;\n- term0 = bSig;\n- }\n- if (!mod) {\n- sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );\n- if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )\n- || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )\n- && ( q & 1 ) )\n- ) {\n- aSig0 = alternateASig0;\n- aSig1 = alternateASig1;\n- zSign = ! zSign;\n- ++*quotient;\n- }\n- }\n- return\n- normalizeRoundAndPackFloatx80(\n- floatx80_precision_x, zSign, bExp + expDiff, aSig0, aSig1, status);\n-\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the remainder of the extended double-precision floating-point value\n-| `a' with respect to the corresponding value `b'. The operation is performed\n-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.\n-*----------------------------------------------------------------------------*/\n-\n-floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)\n-{\n- uint64_t quotient;\n- return floatx80_modrem(a, b, false, "ient, status);\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the remainder of the extended double-precision floating-point value\n-| `a' with respect to the corresponding value `b', with the quotient truncated\n-| toward zero.\n-*----------------------------------------------------------------------------*/\n-\n-floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)\n-{\n- uint64_t quotient;\n- return floatx80_modrem(a, b, true, "ient, status);\n-}\n-\n-/*----------------------------------------------------------------------------\n-| Returns the remainder of the quadruple-precision floating-point value `a'\n-| with respect to the corresponding value `b'. The operation is performed\n-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.\n-*----------------------------------------------------------------------------*/\n-\n-float128 float128_rem(float128 a, float128 b, float_status *status)\n-{\n- bool aSign, zSign;\n- int32_t aExp, bExp, expDiff;\n- uint64_t aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;\n- uint64_t allZero, alternateASig0, alternateASig1, sigMean1;\n- int64_t sigMean0;\n-\n- aSig1 = extractFloat128Frac1( a );\n- aSig0 = extractFloat128Frac0( a );\n- aExp = extractFloat128Exp( a );\n- aSign = extractFloat128Sign( a );\n- bSig1 = extractFloat128Frac1( b );\n- bSig0 = extractFloat128Frac0( b );\n- bExp = extractFloat128Exp( b );\n- if ( aExp == 0x7FFF ) {\n- if ( ( aSig0 | aSig1 )\n- || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {\n- return propagateFloat128NaN(a, b, status);\n- }\n- goto invalid;\n- }\n- if ( bExp == 0x7FFF ) {\n- if (bSig0 | bSig1) {\n- return propagateFloat128NaN(a, b, status);\n- }\n- return a;\n- }\n- if ( bExp == 0 ) {\n- if ( ( bSig0 | bSig1 ) == 0 ) {\n- invalid:\n- float_raise(float_flag_invalid, status);\n- return float128_default_nan(status);\n- }\n- normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );\n- }\n- if ( aExp == 0 ) {\n- if ( ( aSig0 | aSig1 ) == 0 ) return a;\n- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );\n- }\n- expDiff = aExp - bExp;\n- if ( expDiff < -1 ) return a;\n- shortShift128Left(\n- aSig0 | UINT64_C(0x0001000000000000),\n- aSig1,\n- 15 - ( expDiff < 0 ),\n- &aSig0,\n- &aSig1\n- );\n- shortShift128Left(\n- bSig0 | UINT64_C(0x0001000000000000), bSig1, 15, &bSig0, &bSig1 );\n- q = le128( bSig0, bSig1, aSig0, aSig1 );\n- if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );\n- expDiff -= 64;\n- while ( 0 < expDiff ) {\n- q = estimateDiv128To64( aSig0, aSig1, bSig0 );\n- q = ( 4 < q ) ? q - 4 : 0;\n- mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );\n- shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );\n- shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );\n- sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );\n- expDiff -= 61;\n- }\n- if ( -64 < expDiff ) {\n- q = estimateDiv128To64( aSig0, aSig1, bSig0 );\n- q = ( 4 < q ) ? q - 4 : 0;\n- q >>= - expDiff;\n- shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );\n- expDiff += 52;\n- if ( expDiff < 0 ) {\n- shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );\n- }\n- else {\n- shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );\n- }\n- mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );\n- sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );\n- }\n- else {\n- shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );\n- shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );\n- }\n- do {\n- alternateASig0 = aSig0;\n- alternateASig1 = aSig1;\n- ++q;\n- sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );\n- } while ( 0 <= (int64_t) aSig0 );\n- add128(\n- aSig0, aSig1, alternateASig0, alternateASig1, (uint64_t *)&sigMean0, &sigMean1 );\n- if ( ( sigMean0 < 0 )\n- || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {\n- aSig0 = alternateASig0;\n- aSig1 = alternateASig1;\n- }\n- zSign = ( (int64_t) aSig0 < 0 );\n- if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );\n- return normalizeRoundAndPackFloat128(aSign ^ zSign, bExp - 4, aSig0, aSig1,\n- status);\n-}\n static void __attribute__((constructor)) softfloat_init(void)\n {\n union_float64 ua, ub, uc, ur;\ndiff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc\nindex 3659c6a4c0..1bc8db4cf1 100644\n--- a/fpu/softfloat-parts.c.inc\n+++ b/fpu/softfloat-parts.c.inc\n@@ -625,6 +625,40 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatPartsN *b,\n return a;\n }\n \n+/*\n+ * Floating point remainder, per IEC/IEEE, or modulus.\n+ */\n+static FloatPartsN *partsN(modrem)(FloatPartsN *a, FloatPartsN *b,\n+ uint64_t *mod_quot, float_status *s)\n+{\n+ int ab_mask = float_cmask(a->cls) | float_cmask(b->cls);\n+\n+ if (likely(ab_mask == float_cmask_normal)) {\n+ frac_modrem(a, b, mod_quot);\n+ return a;\n+ }\n+\n+ if (mod_quot) {\n+ *mod_quot = 0;\n+ }\n+\n+ /* All the NaN cases */\n+ if (unlikely(ab_mask & float_cmask_anynan)) {\n+ return parts_pick_nan(a, b, s);\n+ }\n+\n+ /* Inf % N; N % 0 */\n+ if (a->cls == float_class_inf || b->cls == float_class_zero) {\n+ float_raise(float_flag_invalid, s);\n+ parts_default_nan(a, s);\n+ return a;\n+ }\n+\n+ /* N % Inf; 0 % N */\n+ g_assert(b->cls == float_class_inf || a->cls == float_class_zero);\n+ return a;\n+}\n+\n /*\n * Square Root\n *\ndiff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc\nindex 88eab344df..6754a94afc 100644\n--- a/fpu/softfloat-specialize.c.inc\n+++ b/fpu/softfloat-specialize.c.inc\n@@ -636,62 +636,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,\n #endif\n }\n \n-/*----------------------------------------------------------------------------\n-| Takes two single-precision floating-point values `a' and `b', one of which\n-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a\n-| signaling NaN, the invalid exception is raised.\n-*----------------------------------------------------------------------------*/\n-\n-static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status)\n-{\n- bool aIsLargerSignificand;\n- uint32_t av, bv;\n- FloatClass a_cls, b_cls;\n-\n- /* This is not complete, but is good enough for pickNaN. */\n- a_cls = (!float32_is_any_nan(a)\n- ? float_class_normal\n- : float32_is_signaling_nan(a, status)\n- ? float_class_snan\n- : float_class_qnan);\n- b_cls = (!float32_is_any_nan(b)\n- ? float_class_normal\n- : float32_is_signaling_nan(b, status)\n- ? float_class_snan\n- : float_class_qnan);\n-\n- av = float32_val(a);\n- bv = float32_val(b);\n-\n- if (is_snan(a_cls) || is_snan(b_cls)) {\n- float_raise(float_flag_invalid, status);\n- }\n-\n- if (status->default_nan_mode) {\n- return float32_default_nan(status);\n- }\n-\n- if ((uint32_t)(av << 1) < (uint32_t)(bv << 1)) {\n- aIsLargerSignificand = 0;\n- } else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) {\n- aIsLargerSignificand = 1;\n- } else {\n- aIsLargerSignificand = (av < bv) ? 1 : 0;\n- }\n-\n- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {\n- if (is_snan(b_cls)) {\n- return float32_silence_nan(b, status);\n- }\n- return b;\n- } else {\n- if (is_snan(a_cls)) {\n- return float32_silence_nan(a, status);\n- }\n- return a;\n- }\n-}\n-\n /*----------------------------------------------------------------------------\n | Returns 1 if the double-precision floating-point value `a' is a quiet\n | NaN; otherwise returns 0.\n@@ -732,62 +676,6 @@ bool float64_is_signaling_nan(float64 a_, float_status *status)\n }\n }\n \n-/*----------------------------------------------------------------------------\n-| Takes two double-precision floating-point values `a' and `b', one of which\n-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a\n-| signaling NaN, the invalid exception is raised.\n-*----------------------------------------------------------------------------*/\n-\n-static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status)\n-{\n- bool aIsLargerSignificand;\n- uint64_t av, bv;\n- FloatClass a_cls, b_cls;\n-\n- /* This is not complete, but is good enough for pickNaN. */\n- a_cls = (!float64_is_any_nan(a)\n- ? float_class_normal\n- : float64_is_signaling_nan(a, status)\n- ? float_class_snan\n- : float_class_qnan);\n- b_cls = (!float64_is_any_nan(b)\n- ? float_class_normal\n- : float64_is_signaling_nan(b, status)\n- ? float_class_snan\n- : float_class_qnan);\n-\n- av = float64_val(a);\n- bv = float64_val(b);\n-\n- if (is_snan(a_cls) || is_snan(b_cls)) {\n- float_raise(float_flag_invalid, status);\n- }\n-\n- if (status->default_nan_mode) {\n- return float64_default_nan(status);\n- }\n-\n- if ((uint64_t)(av << 1) < (uint64_t)(bv << 1)) {\n- aIsLargerSignificand = 0;\n- } else if ((uint64_t)(bv << 1) < (uint64_t)(av << 1)) {\n- aIsLargerSignificand = 1;\n- } else {\n- aIsLargerSignificand = (av < bv) ? 1 : 0;\n- }\n-\n- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {\n- if (is_snan(b_cls)) {\n- return float64_silence_nan(b, status);\n- }\n- return b;\n- } else {\n- if (is_snan(a_cls)) {\n- return float64_silence_nan(a, status);\n- }\n- return a;\n- }\n-}\n-\n /*----------------------------------------------------------------------------\n | Returns 1 if the extended double-precision floating-point value `a' is a\n | quiet NaN; otherwise returns 0. This slightly differs from the same\n@@ -942,56 +830,3 @@ bool float128_is_signaling_nan(float128 a, float_status *status)\n }\n }\n }\n-\n-/*----------------------------------------------------------------------------\n-| Takes two quadruple-precision floating-point values `a' and `b', one of\n-| which is a NaN, and returns the appropriate NaN result. If either `a' or\n-| `b' is a signaling NaN, the invalid exception is raised.\n-*----------------------------------------------------------------------------*/\n-\n-static float128 propagateFloat128NaN(float128 a, float128 b,\n- float_status *status)\n-{\n- bool aIsLargerSignificand;\n- FloatClass a_cls, b_cls;\n-\n- /* This is not complete, but is good enough for pickNaN. */\n- a_cls = (!float128_is_any_nan(a)\n- ? float_class_normal\n- : float128_is_signaling_nan(a, status)\n- ? float_class_snan\n- : float_class_qnan);\n- b_cls = (!float128_is_any_nan(b)\n- ? float_class_normal\n- : float128_is_signaling_nan(b, status)\n- ? float_class_snan\n- : float_class_qnan);\n-\n- if (is_snan(a_cls) || is_snan(b_cls)) {\n- float_raise(float_flag_invalid, status);\n- }\n-\n- if (status->default_nan_mode) {\n- return float128_default_nan(status);\n- }\n-\n- if (lt128(a.high << 1, a.low, b.high << 1, b.low)) {\n- aIsLargerSignificand = 0;\n- } else if (lt128(b.high << 1, b.low, a.high << 1, a.low)) {\n- aIsLargerSignificand = 1;\n- } else {\n- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;\n- }\n-\n- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {\n- if (is_snan(b_cls)) {\n- return float128_silence_nan(b, status);\n- }\n- return b;\n- } else {\n- if (is_snan(a_cls)) {\n- return float128_silence_nan(a, status);\n- }\n- return a;\n- }\n-}\n", "prefixes": [ "72/72" ] }