get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/1475761/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 1475761,
    "url": "http://patchwork.ozlabs.org/api/patches/1475761/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20210508014802.892561-46-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-46-richard.henderson@linaro.org>",
    "list_archive_url": null,
    "date": "2021-05-08T01:47:35",
    "name": "[45/72] softfloat: Move round_to_int to softfloat-parts.c.inc",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "3f242827b25536e6ee0eeb74555ee85adbab1037",
    "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-46-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/1475761/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/1475761/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=zXI42KrX;\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 4FcWZ45TdTz9sTD\n\tfor <incoming@patchwork.ozlabs.org>; Sat,  8 May 2021 12:32:44 +1000 (AEST)",
            "from localhost ([::1]:50192 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 1lfClm-0000jB-On\n\tfor incoming@patchwork.ozlabs.org; Fri, 07 May 2021 22:32:42 -0400",
            "from eggs.gnu.org ([2001:470:142:3::10]:41486)\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 1lfC81-0002rQ-PE\n for qemu-devel@nongnu.org; Fri, 07 May 2021 21:51:37 -0400",
            "from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]:41903)\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 1lfC7y-0005R4-Kt\n for qemu-devel@nongnu.org; Fri, 07 May 2021 21:51:37 -0400",
            "by mail-pl1-x634.google.com with SMTP id z18so2558961plg.8\n for <qemu-devel@nongnu.org>; Fri, 07 May 2021 18:51:34 -0700 (PDT)",
            "from localhost.localdomain ([71.212.144.24])\n by smtp.gmail.com with ESMTPSA id 204sm5861396pfw.158.2021.05.07.18.51.32\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 07 May 2021 18:51:32 -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=lD4M3xdqIE8r914VjTd/jttQJ/e/mxQ3BCpgAvIfUlU=;\n b=zXI42KrXmJ8wWhg4UQfr5JLQwGxQRljTYOqIcseHFB6flqYrTX6QR7xJTTa8K/lqL+\n BlZlA/VcbzdmZk3eRcVSVoYAAyUgaSUVWW5jTRSz2NZKgk078m3E2BQd4+rd6Iq5jnhv\n TviTToJ8Wtra1A/vSXAIbI8XdGoRufTsvhvUAW0dHvmAS3qsEfCqSDFqkLqUzRmKe703\n VNgHPlh6o2U7XUZ7nSTg4qAcV3aS16/b5QSw+BQsxTxvXXMm8QB2z91Cyktq1g+2rk4n\n SHecCQmNLQ0AwUc+RuKbHXS80UUIHZ6YlexNWTmhDwHtVVP+XvTR0ur+e9sjiTWw9pQ3\n bMkw==",
        "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=lD4M3xdqIE8r914VjTd/jttQJ/e/mxQ3BCpgAvIfUlU=;\n b=nWfvdbt9ypVi81Gw4ThxuSONze4gflznSSxhQdTKufJKLht9AiZ4rkGFXWDqbH3FQ+\n CRvXsB2WnqCMbNzfGrmE4OFO4sovjAg6rpXE+iADQMMBjOOzHqbhR/prNWwqUp8IAksy\n LB+wHjDuvlTPZowWyDiWar8pmPcJWkBs0qs73emAIGnKyNYyqdIqpAz8BSRsj2n7hLvv\n BKbul2Jq93MkTH9UZfpFwxLy32bYMbsDq20pOJ7afDayXtH5eYgV0zX7lFgXL+4FmAF1\n Pfxb0GorRiD8PLwezjdJ9gZZaECOpjKlAnUzhBPHi26x1OZDBJTvR7caoHCm2vhMq3Nu\n xYHg==",
        "X-Gm-Message-State": "AOAM530vu7hLk8F4xfmy0t7t2kPSKQ105Wx/sPiFdc84rlALM+BTx6bL\n NJF+BVsM5QRXfufyzL8wC311LOUzJ1Od/A==",
        "X-Google-Smtp-Source": "\n ABdhPJz5FxD8L84om6uMp78Uo7JOGt+lwpvSQLN9Do886HfngG/T+wKHbQ4Y3e6VzkTOGUAArCoAIQ==",
        "X-Received": "by 2002:a17:90b:2390:: with SMTP id\n mr16mr13836588pjb.133.1620438693131;\n Fri, 07 May 2021 18:51:33 -0700 (PDT)",
        "From": "Richard Henderson <richard.henderson@linaro.org>",
        "To": "qemu-devel@nongnu.org",
        "Subject": "[PATCH 45/72] softfloat: Move round_to_int to softfloat-parts.c.inc",
        "Date": "Fri,  7 May 2021 18:47:35 -0700",
        "Message-Id": "<20210508014802.892561-46-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::634;\n envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x634.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": "At the same time, convert to pointers, split out\nparts$N_round_to_int_normal, define a macro for\nparts_round_to_int using QEMU_GENERIC.\n\nThis necessarily meant some rearrangement to the\nrount_to_{,u}int_and_pack routines, so go ahead and\nconvert to parts_round_to_int_normal, which in turn\nallows cleaning up of the raised exception handling.\n\nSigned-off-by: Richard Henderson <richard.henderson@linaro.org>\n---\n fpu/softfloat.c           | 434 ++++++++++----------------------------\n fpu/softfloat-parts.c.inc | 157 ++++++++++++++\n 2 files changed, 263 insertions(+), 328 deletions(-)",
    "diff": "diff --git a/fpu/softfloat.c b/fpu/softfloat.c\nindex 1b86111279..ce96ea753c 100644\n--- a/fpu/softfloat.c\n+++ b/fpu/softfloat.c\n@@ -810,6 +810,24 @@ 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 bool parts64_round_to_int_normal(FloatParts64 *a, FloatRoundMode rm,\n+                                        int scale, int frac_size);\n+static bool parts128_round_to_int_normal(FloatParts128 *a, FloatRoundMode r,\n+                                         int scale, int frac_size);\n+\n+#define parts_round_to_int_normal(A, R, C, F) \\\n+    PARTS_GENERIC_64_128(round_to_int_normal, A)(A, R, C, F)\n+\n+static void parts64_round_to_int(FloatParts64 *a, FloatRoundMode rm,\n+                                 int scale, float_status *s,\n+                                 const FloatFmt *fmt);\n+static void parts128_round_to_int(FloatParts128 *a, FloatRoundMode r,\n+                                  int scale, float_status *s,\n+                                  const FloatFmt *fmt);\n+\n+#define parts_round_to_int(A, R, C, S, F) \\\n+    PARTS_GENERIC_64_128(round_to_int, A)(A, R, C, S, F)\n+\n /*\n  * Helper functions for softfloat-parts.c.inc, per-size operations.\n  */\n@@ -2284,153 +2302,52 @@ float128 float64_to_float128(float64 a, float_status *s)\n }\n \n /*\n- * Rounds the floating-point value `a' to an integer, and returns the\n- * result as a floating-point value. The operation is performed\n- * according to the IEC/IEEE Standard for Binary Floating-Point\n- * Arithmetic.\n+ * Round to integral value\n  */\n \n-static FloatParts64 round_to_int(FloatParts64 a, FloatRoundMode rmode,\n-                               int scale, float_status *s)\n-{\n-    switch (a.cls) {\n-    case float_class_qnan:\n-    case float_class_snan:\n-        parts_return_nan(&a, s);\n-        break;\n-\n-    case float_class_zero:\n-    case float_class_inf:\n-        /* already \"integral\" */\n-        break;\n-\n-    case float_class_normal:\n-        scale = MIN(MAX(scale, -0x10000), 0x10000);\n-        a.exp += scale;\n-\n-        if (a.exp >= DECOMPOSED_BINARY_POINT) {\n-            /* already integral */\n-            break;\n-        }\n-        if (a.exp < 0) {\n-            bool one;\n-            /* all fractional */\n-            float_raise(float_flag_inexact, s);\n-            switch (rmode) {\n-            case float_round_nearest_even:\n-                one = a.exp == -1 && a.frac > DECOMPOSED_IMPLICIT_BIT;\n-                break;\n-            case float_round_ties_away:\n-                one = a.exp == -1 && a.frac >= DECOMPOSED_IMPLICIT_BIT;\n-                break;\n-            case float_round_to_zero:\n-                one = false;\n-                break;\n-            case float_round_up:\n-                one = !a.sign;\n-                break;\n-            case float_round_down:\n-                one = a.sign;\n-                break;\n-            case float_round_to_odd:\n-                one = true;\n-                break;\n-            default:\n-                g_assert_not_reached();\n-            }\n-\n-            if (one) {\n-                a.frac = DECOMPOSED_IMPLICIT_BIT;\n-                a.exp = 0;\n-            } else {\n-                a.cls = float_class_zero;\n-            }\n-        } else {\n-            uint64_t frac_lsb = DECOMPOSED_IMPLICIT_BIT >> a.exp;\n-            uint64_t frac_lsbm1 = frac_lsb >> 1;\n-            uint64_t rnd_even_mask = (frac_lsb - 1) | frac_lsb;\n-            uint64_t rnd_mask = rnd_even_mask >> 1;\n-            uint64_t inc;\n-\n-            switch (rmode) {\n-            case float_round_nearest_even:\n-                inc = ((a.frac & rnd_even_mask) != frac_lsbm1 ? frac_lsbm1 : 0);\n-                break;\n-            case float_round_ties_away:\n-                inc = frac_lsbm1;\n-                break;\n-            case float_round_to_zero:\n-                inc = 0;\n-                break;\n-            case float_round_up:\n-                inc = a.sign ? 0 : rnd_mask;\n-                break;\n-            case float_round_down:\n-                inc = a.sign ? rnd_mask : 0;\n-                break;\n-            case float_round_to_odd:\n-                inc = a.frac & frac_lsb ? 0 : rnd_mask;\n-                break;\n-            default:\n-                g_assert_not_reached();\n-            }\n-\n-            if (a.frac & rnd_mask) {\n-                float_raise(float_flag_inexact, s);\n-                if (uadd64_overflow(a.frac, inc, &a.frac)) {\n-                    a.frac >>= 1;\n-                    a.frac |= DECOMPOSED_IMPLICIT_BIT;\n-                    a.exp++;\n-                }\n-                a.frac &= ~rnd_mask;\n-            }\n-        }\n-        break;\n-    default:\n-        g_assert_not_reached();\n-    }\n-    return a;\n-}\n-\n float16 float16_round_to_int(float16 a, float_status *s)\n {\n-    FloatParts64 pa, pr;\n+    FloatParts64 p;\n \n-    float16_unpack_canonical(&pa, a, s);\n-    pr = round_to_int(pa, s->float_rounding_mode, 0, s);\n-    return float16_round_pack_canonical(&pr, s);\n+    float16_unpack_canonical(&p, a, s);\n+    parts_round_to_int(&p, s->float_rounding_mode, 0, s, &float16_params);\n+    return float16_round_pack_canonical(&p, s);\n }\n \n float32 float32_round_to_int(float32 a, float_status *s)\n {\n-    FloatParts64 pa, pr;\n+    FloatParts64 p;\n \n-    float32_unpack_canonical(&pa, a, s);\n-    pr = round_to_int(pa, s->float_rounding_mode, 0, s);\n-    return float32_round_pack_canonical(&pr, s);\n+    float32_unpack_canonical(&p, a, s);\n+    parts_round_to_int(&p, s->float_rounding_mode, 0, s, &float32_params);\n+    return float32_round_pack_canonical(&p, s);\n }\n \n float64 float64_round_to_int(float64 a, float_status *s)\n {\n-    FloatParts64 pa, pr;\n+    FloatParts64 p;\n \n-    float64_unpack_canonical(&pa, a, s);\n-    pr = round_to_int(pa, s->float_rounding_mode, 0, s);\n-    return float64_round_pack_canonical(&pr, s);\n+    float64_unpack_canonical(&p, a, s);\n+    parts_round_to_int(&p, s->float_rounding_mode, 0, s, &float64_params);\n+    return float64_round_pack_canonical(&p, s);\n }\n \n-/*\n- * Rounds the bfloat16 value `a' to an integer, and returns the\n- * result as a bfloat16 value.\n- */\n-\n bfloat16 bfloat16_round_to_int(bfloat16 a, float_status *s)\n {\n-    FloatParts64 pa, pr;\n+    FloatParts64 p;\n \n-    bfloat16_unpack_canonical(&pa, a, s);\n-    pr = round_to_int(pa, s->float_rounding_mode, 0, s);\n-    return bfloat16_round_pack_canonical(&pr, s);\n+    bfloat16_unpack_canonical(&p, a, s);\n+    parts_round_to_int(&p, s->float_rounding_mode, 0, s, &bfloat16_params);\n+    return bfloat16_round_pack_canonical(&p, s);\n+}\n+\n+float128 float128_round_to_int(float128 a, float_status *s)\n+{\n+    FloatParts128 p;\n+\n+    float128_unpack_canonical(&p, a, s);\n+    parts_round_to_int(&p, s->float_rounding_mode, 0, s, &float128_params);\n+    return float128_round_pack_canonical(&p, s);\n }\n \n /*\n@@ -2444,48 +2361,58 @@ bfloat16 bfloat16_round_to_int(bfloat16 a, float_status *s)\n  * is returned.\n */\n \n-static int64_t round_to_int_and_pack(FloatParts64 in, FloatRoundMode rmode,\n+static int64_t round_to_int_and_pack(FloatParts64 p, FloatRoundMode rmode,\n                                      int scale, int64_t min, int64_t max,\n                                      float_status *s)\n {\n+    int flags = 0;\n     uint64_t r;\n-    int orig_flags = get_float_exception_flags(s);\n-    FloatParts64 p = round_to_int(in, rmode, scale, s);\n \n     switch (p.cls) {\n     case float_class_snan:\n     case float_class_qnan:\n-        s->float_exception_flags = orig_flags | float_flag_invalid;\n-        return max;\n+        flags = float_flag_invalid;\n+        r = max;\n+        break;\n+\n     case float_class_inf:\n-        s->float_exception_flags = orig_flags | float_flag_invalid;\n-        return p.sign ? min : max;\n+        flags = float_flag_invalid;\n+        r = p.sign ? min : max;\n+        break;\n+\n     case float_class_zero:\n         return 0;\n+\n     case float_class_normal:\n+        /* TODO: 62 = N - 2, frac_size for rounding */\n+        if (parts_round_to_int_normal(&p, rmode, scale, 62)) {\n+            flags = float_flag_inexact;\n+        }\n+\n         if (p.exp <= DECOMPOSED_BINARY_POINT) {\n             r = p.frac >> (DECOMPOSED_BINARY_POINT - p.exp);\n         } else {\n             r = UINT64_MAX;\n         }\n         if (p.sign) {\n-            if (r <= -(uint64_t) min) {\n-                return -r;\n+            if (r <= -(uint64_t)min) {\n+                r = -r;\n             } else {\n-                s->float_exception_flags = orig_flags | float_flag_invalid;\n-                return min;\n-            }\n-        } else {\n-            if (r <= max) {\n-                return r;\n-            } else {\n-                s->float_exception_flags = orig_flags | float_flag_invalid;\n-                return max;\n+                flags = float_flag_invalid;\n+                r = min;\n             }\n+        } else if (r > max) {\n+            flags = float_flag_invalid;\n+            r = max;\n         }\n+        break;\n+\n     default:\n         g_assert_not_reached();\n     }\n+\n+    float_raise(flags, s);\n+    return r;\n }\n \n int8_t float16_to_int8_scalbn(float16 a, FloatRoundMode rmode, int scale,\n@@ -2748,49 +2675,59 @@ int64_t bfloat16_to_int64_round_to_zero(bfloat16 a, float_status *s)\n  *  flag.\n  */\n \n-static uint64_t round_to_uint_and_pack(FloatParts64 in, FloatRoundMode rmode,\n+static uint64_t round_to_uint_and_pack(FloatParts64 p, FloatRoundMode rmode,\n                                        int scale, uint64_t max,\n                                        float_status *s)\n {\n-    int orig_flags = get_float_exception_flags(s);\n-    FloatParts64 p = round_to_int(in, rmode, scale, s);\n+    int flags = 0;\n     uint64_t r;\n \n     switch (p.cls) {\n     case float_class_snan:\n     case float_class_qnan:\n-        s->float_exception_flags = orig_flags | float_flag_invalid;\n-        return max;\n+        flags = float_flag_invalid;\n+        r = max;\n+        break;\n+\n     case float_class_inf:\n-        s->float_exception_flags = orig_flags | float_flag_invalid;\n-        return p.sign ? 0 : max;\n+        flags = float_flag_invalid;\n+        r = p.sign ? 0 : max;\n+        break;\n+\n     case float_class_zero:\n         return 0;\n+\n     case float_class_normal:\n+        /* TODO: 62 = N - 2, frac_size for rounding */\n+        if (parts_round_to_int_normal(&p, rmode, scale, 62)) {\n+            flags = float_flag_inexact;\n+            if (p.cls == float_class_zero) {\n+                r = 0;\n+                break;\n+            }\n+        }\n+\n         if (p.sign) {\n-            s->float_exception_flags = orig_flags | float_flag_invalid;\n-            return 0;\n-        }\n-\n-        if (p.exp <= DECOMPOSED_BINARY_POINT) {\n-            r = p.frac >> (DECOMPOSED_BINARY_POINT - p.exp);\n+            flags = float_flag_invalid;\n+            r = 0;\n+        } else if (p.exp > DECOMPOSED_BINARY_POINT) {\n+            flags = float_flag_invalid;\n+            r = max;\n         } else {\n-            s->float_exception_flags = orig_flags | float_flag_invalid;\n-            return max;\n+            r = p.frac >> (DECOMPOSED_BINARY_POINT - p.exp);\n+            if (r > max) {\n+                flags = float_flag_invalid;\n+                r = max;\n+            }\n         }\n+        break;\n \n-        /* For uint64 this will never trip, but if p.exp is too large\n-         * to shift a decomposed fraction we shall have exited via the\n-         * 3rd leg above.\n-         */\n-        if (r > max) {\n-            s->float_exception_flags = orig_flags | float_flag_invalid;\n-            return max;\n-        }\n-        return r;\n     default:\n         g_assert_not_reached();\n     }\n+\n+    float_raise(flags, s);\n+    return r;\n }\n \n uint8_t float16_to_uint8_scalbn(float16 a, FloatRoundMode rmode, int scale,\n@@ -6955,165 +6892,6 @@ floatx80 float128_to_floatx80(float128 a, float_status *status)\n \n }\n \n-/*----------------------------------------------------------------------------\n-| Rounds the quadruple-precision floating-point value `a' to an integer, and\n-| returns the result as a quadruple-precision floating-point value.  The\n-| operation is performed according to the IEC/IEEE Standard for Binary\n-| Floating-Point Arithmetic.\n-*----------------------------------------------------------------------------*/\n-\n-float128 float128_round_to_int(float128 a, float_status *status)\n-{\n-    bool aSign;\n-    int32_t aExp;\n-    uint64_t lastBitMask, roundBitsMask;\n-    float128 z;\n-\n-    aExp = extractFloat128Exp( a );\n-    if ( 0x402F <= aExp ) {\n-        if ( 0x406F <= aExp ) {\n-            if (    ( aExp == 0x7FFF )\n-                 && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )\n-               ) {\n-                return propagateFloat128NaN(a, a, status);\n-            }\n-            return a;\n-        }\n-        lastBitMask = 1;\n-        lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;\n-        roundBitsMask = lastBitMask - 1;\n-        z = a;\n-        switch (status->float_rounding_mode) {\n-        case float_round_nearest_even:\n-            if ( lastBitMask ) {\n-                add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );\n-                if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;\n-            }\n-            else {\n-                if ( (int64_t) z.low < 0 ) {\n-                    ++z.high;\n-                    if ( (uint64_t) ( z.low<<1 ) == 0 ) z.high &= ~1;\n-                }\n-            }\n-            break;\n-        case float_round_ties_away:\n-            if (lastBitMask) {\n-                add128(z.high, z.low, 0, lastBitMask >> 1, &z.high, &z.low);\n-            } else {\n-                if ((int64_t) z.low < 0) {\n-                    ++z.high;\n-                }\n-            }\n-            break;\n-        case float_round_to_zero:\n-            break;\n-        case float_round_up:\n-            if (!extractFloat128Sign(z)) {\n-                add128(z.high, z.low, 0, roundBitsMask, &z.high, &z.low);\n-            }\n-            break;\n-        case float_round_down:\n-            if (extractFloat128Sign(z)) {\n-                add128(z.high, z.low, 0, roundBitsMask, &z.high, &z.low);\n-            }\n-            break;\n-        case float_round_to_odd:\n-            /*\n-             * Note that if lastBitMask == 0, the last bit is the lsb\n-             * of high, and roundBitsMask == -1.\n-             */\n-            if ((lastBitMask ? z.low & lastBitMask : z.high & 1) == 0) {\n-                add128(z.high, z.low, 0, roundBitsMask, &z.high, &z.low);\n-            }\n-            break;\n-        default:\n-            abort();\n-        }\n-        z.low &= ~ roundBitsMask;\n-    }\n-    else {\n-        if ( aExp < 0x3FFF ) {\n-            if ( ( ( (uint64_t) ( a.high<<1 ) ) | a.low ) == 0 ) return a;\n-            float_raise(float_flag_inexact, status);\n-            aSign = extractFloat128Sign( a );\n-            switch (status->float_rounding_mode) {\n-            case float_round_nearest_even:\n-                if (    ( aExp == 0x3FFE )\n-                     && (   extractFloat128Frac0( a )\n-                          | extractFloat128Frac1( a ) )\n-                   ) {\n-                    return packFloat128( aSign, 0x3FFF, 0, 0 );\n-                }\n-                break;\n-            case float_round_ties_away:\n-                if (aExp == 0x3FFE) {\n-                    return packFloat128(aSign, 0x3FFF, 0, 0);\n-                }\n-                break;\n-            case float_round_down:\n-                return\n-                      aSign ? packFloat128( 1, 0x3FFF, 0, 0 )\n-                    : packFloat128( 0, 0, 0, 0 );\n-            case float_round_up:\n-                return\n-                      aSign ? packFloat128( 1, 0, 0, 0 )\n-                    : packFloat128( 0, 0x3FFF, 0, 0 );\n-\n-            case float_round_to_odd:\n-                return packFloat128(aSign, 0x3FFF, 0, 0);\n-\n-            case float_round_to_zero:\n-                break;\n-            }\n-            return packFloat128( aSign, 0, 0, 0 );\n-        }\n-        lastBitMask = 1;\n-        lastBitMask <<= 0x402F - aExp;\n-        roundBitsMask = lastBitMask - 1;\n-        z.low = 0;\n-        z.high = a.high;\n-        switch (status->float_rounding_mode) {\n-        case float_round_nearest_even:\n-            z.high += lastBitMask>>1;\n-            if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {\n-                z.high &= ~ lastBitMask;\n-            }\n-            break;\n-        case float_round_ties_away:\n-            z.high += lastBitMask>>1;\n-            break;\n-        case float_round_to_zero:\n-            break;\n-        case float_round_up:\n-            if (!extractFloat128Sign(z)) {\n-                z.high |= ( a.low != 0 );\n-                z.high += roundBitsMask;\n-            }\n-            break;\n-        case float_round_down:\n-            if (extractFloat128Sign(z)) {\n-                z.high |= (a.low != 0);\n-                z.high += roundBitsMask;\n-            }\n-            break;\n-        case float_round_to_odd:\n-            if ((z.high & lastBitMask) == 0) {\n-                z.high |= (a.low != 0);\n-                z.high += roundBitsMask;\n-            }\n-            break;\n-        default:\n-            abort();\n-        }\n-        z.high &= ~ roundBitsMask;\n-    }\n-    if ( ( z.low != a.low ) || ( z.high != a.high ) ) {\n-        float_raise(float_flag_inexact, status);\n-    }\n-    return z;\n-\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\ndiff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc\nindex f8165d92f9..b2c4624d8c 100644\n--- a/fpu/softfloat-parts.c.inc\n+++ b/fpu/softfloat-parts.c.inc\n@@ -594,3 +594,160 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatPartsN *b,\n     a->cls = float_class_inf;\n     return a;\n }\n+\n+/*\n+ * Rounds the floating-point value `a' to an integer, and returns the\n+ * result as a floating-point value. The operation is performed\n+ * according to the IEC/IEEE Standard for Binary Floating-Point\n+ * Arithmetic.\n+ *\n+ * parts_round_to_int_normal is an internal helper function for\n+ * normal numbers only, returning true for inexact but not directly\n+ * raising float_flag_inexact.\n+ */\n+static bool partsN(round_to_int_normal)(FloatPartsN *a, FloatRoundMode rmode,\n+                                        int scale, int frac_size)\n+{\n+    uint64_t frac_lsb, frac_lsbm1, rnd_even_mask, rnd_mask, inc;\n+    int shift_adj;\n+\n+    scale = MIN(MAX(scale, -0x10000), 0x10000);\n+    a->exp += scale;\n+\n+    if (a->exp < 0) {\n+        bool one;\n+\n+        /* All fractional */\n+        switch (rmode) {\n+        case float_round_nearest_even:\n+            one = false;\n+            if (a->exp == -1) {\n+                FloatPartsN tmp;\n+                /* Shift left one, discarding DECOMPOSED_IMPLICIT_BIT */\n+                frac_add(&tmp, a, a);\n+                /* Anything remaining means frac > 0.5. */\n+                one = !frac_eqz(&tmp);\n+            }\n+            break;\n+        case float_round_ties_away:\n+            one = a->exp == -1;\n+            break;\n+        case float_round_to_zero:\n+            one = false;\n+            break;\n+        case float_round_up:\n+            one = !a->sign;\n+            break;\n+        case float_round_down:\n+            one = a->sign;\n+            break;\n+        case float_round_to_odd:\n+            one = true;\n+            break;\n+        default:\n+            g_assert_not_reached();\n+        }\n+\n+        frac_clear(a);\n+        a->exp = 0;\n+        if (one) {\n+            a->frac_hi = DECOMPOSED_IMPLICIT_BIT;\n+        } else {\n+            a->cls = float_class_zero;\n+        }\n+        return true;\n+    }\n+\n+    if (a->exp >= frac_size) {\n+        /* All integral */\n+        return false;\n+    }\n+\n+    if (N > 64 && a->exp < N - 64) {\n+        /*\n+         * Rounding is not in the low word -- shift lsb to bit 2,\n+         * which leaves room for sticky and rounding bit.\n+         */\n+        shift_adj = (N - 1) - (a->exp + 2);\n+        frac_shrjam(a, shift_adj);\n+        frac_lsb = 1 << 2;\n+    } else {\n+        shift_adj = 0;\n+        frac_lsb = DECOMPOSED_IMPLICIT_BIT >> (a->exp & 63);\n+    }\n+\n+    frac_lsbm1 = frac_lsb >> 1;\n+    rnd_mask = frac_lsb - 1;\n+    rnd_even_mask = rnd_mask | frac_lsb;\n+\n+    if (!(a->frac_lo & rnd_mask)) {\n+        /* Fractional bits already clear, undo the shift above. */\n+        frac_shl(a, shift_adj);\n+        return false;\n+    }\n+\n+    switch (rmode) {\n+    case float_round_nearest_even:\n+        inc = ((a->frac_lo & rnd_even_mask) != frac_lsbm1 ? frac_lsbm1 : 0);\n+        break;\n+    case float_round_ties_away:\n+        inc = frac_lsbm1;\n+        break;\n+    case float_round_to_zero:\n+        inc = 0;\n+        break;\n+    case float_round_up:\n+        inc = a->sign ? 0 : rnd_mask;\n+        break;\n+    case float_round_down:\n+        inc = a->sign ? rnd_mask : 0;\n+        break;\n+    case float_round_to_odd:\n+        inc = a->frac_lo & frac_lsb ? 0 : rnd_mask;\n+        break;\n+    default:\n+        g_assert_not_reached();\n+    }\n+\n+    if (shift_adj == 0) {\n+        if (frac_addi(a, a, inc)) {\n+            frac_shr(a, 1);\n+            a->frac_hi |= DECOMPOSED_IMPLICIT_BIT;\n+            a->exp++;\n+        }\n+        a->frac_lo &= ~rnd_mask;\n+    } else {\n+        frac_addi(a, a, inc);\n+        a->frac_lo &= ~rnd_mask;\n+        /* Be careful shifting back, not to overflow */\n+        frac_shl(a, shift_adj - 1);\n+        if (a->frac_hi & DECOMPOSED_IMPLICIT_BIT) {\n+            a->exp++;\n+        } else {\n+            frac_add(a, a, a);\n+        }\n+    }\n+    return true;\n+}\n+\n+static void partsN(round_to_int)(FloatPartsN *a, FloatRoundMode rmode,\n+                                 int scale, float_status *s,\n+                                 const FloatFmt *fmt)\n+{\n+    switch (a->cls) {\n+    case float_class_qnan:\n+    case float_class_snan:\n+        parts_return_nan(a, s);\n+        break;\n+    case float_class_zero:\n+    case float_class_inf:\n+        break;\n+    case float_class_normal:\n+        if (parts_round_to_int_normal(a, rmode, scale, fmt->frac_size)) {\n+            float_raise(float_flag_inexact, s);\n+        }\n+        break;\n+    default:\n+        g_assert_not_reached();\n+    }\n+}\n",
    "prefixes": [
        "45/72"
    ]
}