From patchwork Sat May 27 14:19:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 686383 Delivered-To: patch@linaro.org Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp319877wrt; Sat, 27 May 2023 07:20:21 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5YF6i3d1bE/6M8/kVOjjnuCVUMBG1jQuWSxSgCJrSjNvwGOKW3QW0w7+QXIFfD9BMcq0DQ X-Received: by 2002:a05:620a:2a07:b0:75b:23a0:de93 with SMTP id o7-20020a05620a2a0700b0075b23a0de93mr2827040qkp.17.1685197221167; Sat, 27 May 2023 07:20:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685197221; cv=none; d=google.com; s=arc-20160816; b=iN0Xppsc/obFv6efSZkamPmnuHSOBjM1joKuo7QEiDawW7pvTIDhyIf6uO0RcKNgmO OKXTxAvn0Y++AEblhQy1Z04osb/Ave8RE6NsuXhhkWvwHmQnhl3bmr5eLKebR3adJEIt SqCU5LY5DzpU9hzCBKCtV/Qr7WvBtTY7Gc7tZMBUA96QuFzJrYMsFcp2DHzp2QWm6JyH ix9BVxvFgCKYQ6UvzSmX3nq5aIPOk29qOpzQveWJmJrqAGLuvhvqNRD/AcpXtvySYFOD MSciXU2m+3oclP9wUd3VmTCU2a7iYQEsvfdcfLQD5h/OZ6zKJH3oIeJL/5/Uf6Xi7Di2 LrPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=DDbFBgISj2NEyBK0D5B4JQEN40ApYglGb4D217KNjVU=; b=vuyjpHCz9AoMZKEpe6FLr6Y09h6BU9d6ENs/G7R2y7Q8pxixxljy0GkGWkSvH/Rh5g 2enP1WdoURbtoleHPcVPQ1Y+RlYbr6rt/qPK8108A/hnxNbq/6Q3tTvqlblmaQxbuUKW ZBUkdjTwSaqNUUoLSubAHebB0nHbG0kKh9fCfZUKS1rP3/2C9w2DI5dMRdwzOuPOtNLc OCvADjyJpL8gOHTBTe3yscCMMqWbTcc5AyG3AGVye1XMQ9ao8VhNoRhwDFxnUdlMrh3O yjgeyJzrdUevmzrI+X9LKklX25FnwN9WfGhOVtTAixXMGb5ig0xLoGnJKAiepB3ly8jk zVmw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DCD0ru6f; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id p15-20020ae9f30f000000b0075943884c57si1504534qkg.312.2023.05.27.07.20.20 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Sat, 27 May 2023 07:20:21 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DCD0ru6f; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q2ulJ-0007o1-9R; Sat, 27 May 2023 10:19:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q2ulI-0007ng-7g for qemu-devel@nongnu.org; Sat, 27 May 2023 10:19:16 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1q2ulG-0002GC-Id for qemu-devel@nongnu.org; Sat, 27 May 2023 10:19:16 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-256481ce1b5so430175a91.1 for ; Sat, 27 May 2023 07:19:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1685197153; x=1687789153; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=DDbFBgISj2NEyBK0D5B4JQEN40ApYglGb4D217KNjVU=; b=DCD0ru6fPCyggh9ahSI/GdOAxD46vY7QCkaJACsvPwC5QppfTrz5GjRmEoVo40edU2 YfFMChM3UlkwHHwVbe/cxOEGuF7zDpLGBpXNgnyLukz1bziN0QGU9JgOgk8AaAjFhkAN Jd8QKLUlOB7jzhi9pomUP3GFyk0taoNzA3fwUOEWSWPE+LKGiLmqd4LKZu6DeVo/qCYk +n4B/ukz83UbjzBfR8J67/7h0qE59QuM3yHsrm6+h8TgYdcHbljEXmXkkyYCkq6tFyPK 3Az0YZjXRlWfXOzJuGDGQa3s6Sp58iyL2cXDKqwZklHw9aW1idZvsuBO09UQ68So09i5 1WHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685197153; x=1687789153; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DDbFBgISj2NEyBK0D5B4JQEN40ApYglGb4D217KNjVU=; b=gCzNUO+FEqkYBvindUPOIGWj7jSOo2lR6tctgOo2oDixeWMxGr9NRrlbd6DEmywiJz kdrpFQBx2q8+zdj5cLrynNFi8omDKyMQ60N/Hi+PEz6MwoT9kIy30g7b1EWHaobWH+W5 DUpV5lw0+aN8C05428/yvzL9WpA7md5m681xzh50eH25D0YhoEl/smoUBYVrG/PFLUdR Nb6rtK0qGX1tjfXbenURz20jagIJjNhS3+pD8FvjH8u7hUvvo1jWutc9scTurIx7jaeN Qj9lsJUpQqf8pSxiz88vPUmW/LI0UXEVUIkm0nUwrB7Dy5ywsgzZzl6B4lmUQa6kNjSa vUWw== X-Gm-Message-State: AC+VfDxC7/TYT9Yz2M+ydftBJSlyXm7yUgqMtRbRS5raO0h3rVc8txV7 UFEtczhUAkJSxcgf5ZK6bj/T/IQ2AN58V3RQ4BM= X-Received: by 2002:a17:902:e884:b0:1ae:1237:874d with SMTP id w4-20020a170902e88400b001ae1237874dmr5890752plg.69.1685197152924; Sat, 27 May 2023 07:19:12 -0700 (PDT) Received: from stoup.. ([2602:ae:1598:4c01:be31:c162:a57e:7431]) by smtp.gmail.com with ESMTPSA id j20-20020a170902759400b001a988a71617sm1258992pll.192.2023.05.27.07.19.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 May 2023 07:19:12 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Cc: christoph.muellner@vrull.eu, alex.bennee@linaro.org Subject: [PATCH 1/4] fpu: Add float64_to_int{32,64}_modulo Date: Sat, 27 May 2023 07:19:07 -0700 Message-Id: <20230527141910.1885950-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230527141910.1885950-1-richard.henderson@linaro.org> References: <20230527141910.1885950-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102a.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, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org Add versions of float64_to_int* which do not saturate the result. Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée --- include/fpu/softfloat.h | 3 ++ fpu/softfloat.c | 31 ++++++++++++++++ fpu/softfloat-parts.c.inc | 78 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 3dcf20e3a2..cd130564d8 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -751,6 +751,9 @@ int16_t float64_to_int16_round_to_zero(float64, float_status *status); int32_t float64_to_int32_round_to_zero(float64, float_status *status); int64_t float64_to_int64_round_to_zero(float64, float_status *status); +int32_t float64_to_int32_modulo(float64, FloatRoundMode, float_status *status); +int64_t float64_to_int64_modulo(float64, FloatRoundMode, float_status *status); + uint16_t float64_to_uint16_scalbn(float64, FloatRoundMode, int, float_status *); uint32_t float64_to_uint32_scalbn(float64, FloatRoundMode, int, float_status *); uint64_t float64_to_uint64_scalbn(float64, FloatRoundMode, int, float_status *); diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 108f9cb224..c05819afcd 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -852,11 +852,24 @@ static uint64_t parts128_float_to_uint(FloatParts128 *p, FloatRoundMode rmode, #define parts_float_to_uint(P, R, Z, M, S) \ PARTS_GENERIC_64_128(float_to_uint, P)(P, R, Z, M, S) +static int64_t parts64_float_to_sint_modulo(FloatParts64 *p, + FloatRoundMode rmode, + int bitsm1, float_status *s); +static int64_t parts128_float_to_sint_modulo(FloatParts128 *p, + FloatRoundMode rmode, + int bitsm1, float_status *s); + +#define parts_float_to_sint_modulo(P, R, M, S) \ + PARTS_GENERIC_64_128(float_to_sint_modulo, P)(P, R, M, S) + static void parts64_sint_to_float(FloatParts64 *p, int64_t a, int scale, float_status *s); static void parts128_sint_to_float(FloatParts128 *p, int64_t a, int scale, float_status *s); +#define parts_float_to_sint(P, R, Z, MN, MX, S) \ + PARTS_GENERIC_64_128(float_to_sint, P)(P, R, Z, MN, MX, S) + #define parts_sint_to_float(P, I, Z, S) \ PARTS_GENERIC_64_128(sint_to_float, P)(P, I, Z, S) @@ -3409,6 +3422,24 @@ int64_t bfloat16_to_int64_round_to_zero(bfloat16 a, float_status *s) return bfloat16_to_int64_scalbn(a, float_round_to_zero, 0, s); } +int32_t float64_to_int32_modulo(float64 a, FloatRoundMode rmode, + float_status *s) +{ + FloatParts64 p; + + float64_unpack_canonical(&p, a, s); + return parts_float_to_sint_modulo(&p, rmode, 31, s); +} + +int64_t float64_to_int64_modulo(float64 a, FloatRoundMode rmode, + float_status *s) +{ + FloatParts64 p; + + float64_unpack_canonical(&p, a, s); + return parts_float_to_sint_modulo(&p, rmode, 63, s); +} + /* * Floating-point to unsigned integer conversions */ diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index 247400031c..527e15e6ab 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1181,6 +1181,84 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode, return r; } +/* + * Like partsN(float_to_sint), except do not saturate the result. + * Instead, return the rounded unbounded precision two's compliment result, + * modulo 2**(bitsm1 + 1). + */ +static int64_t partsN(float_to_sint_modulo)(FloatPartsN *p, + FloatRoundMode rmode, + int bitsm1, float_status *s) +{ + int flags = 0; + uint64_t r; + bool overflow = false; + + switch (p->cls) { + case float_class_snan: + flags |= float_flag_invalid_snan; + /* fall through */ + case float_class_qnan: + flags |= float_flag_invalid; + r = 0; + break; + + case float_class_inf: + overflow = true; + r = 0; + break; + + case float_class_zero: + return 0; + + case float_class_normal: + /* TODO: N - 2 is frac_size for rounding; could use input fmt. */ + if (parts_round_to_int_normal(p, rmode, 0, N - 2)) { + flags = float_flag_inexact; + } + + if (p->exp <= DECOMPOSED_BINARY_POINT) { + /* + * Because we rounded to integral, and exp < 64, + * we know frac_low is zero. + */ + r = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp); + if (p->exp < bitsm1) { + /* Result in range. */ + } else if (p->exp == bitsm1) { + /* The only in-range value is INT_MIN. */ + overflow = !p->sign || p->frac_hi != DECOMPOSED_IMPLICIT_BIT; + } else { + overflow = true; + } + } else { + /* Overflow, but there might still be bits to return. */ + int shl = p->exp - DECOMPOSED_BINARY_POINT; + if (shl < N) { + frac_shl(p, shl); + r = p->frac_hi; + } else { + r = 0; + } + overflow = true; + } + + if (p->sign) { + r = -r; + } + break; + + default: + g_assert_not_reached(); + } + + if (overflow) { + flags = float_flag_invalid | float_flag_invalid_cvti; + } + float_raise(flags, s); + return r; +} + /* * Integer to float conversions *