From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621958943; cv=none; d=zohomail.com; s=zohoarc; b=CKdaeUwCj6Eba/SeYrmGt9qtsv1A/thOk6vzIX9UTptE40b3CUzGwHxOqYZWrAQk5L2VTTsIP3DFs+ms0GyyoHHaZNTfXa7kKTAU2CsOhW6xJqEq/27zRPUerkwADjUndxumwK11GyucJ+ITFGbUthU1cVo3k6yU9DZB3FjQeCw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621958943; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=/ttITD/09WEgyyZYjSew5EYoec5er/8eI+cVyDIB5nE=; b=RcG/N1OMO11nZtwRre18e3f7XpiXvtLG47Yjf1zGAU0ediRQEnGXMdY8krdx5HrR01RgMunSukLlu3meU0d+lPm7bZQ8GnNGJIPGS8U6sq6Je9B87OL5iMSaToBxeDakHPbAMDPUuGg57qLq7LtHFSLoDCEJ4e+AaKA1+zUyW9w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621958943173246.73671671395607; Tue, 25 May 2021 09:09:03 -0700 (PDT) Received: from localhost ([::1]:55960 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZc6-0006kv-7E for importer@patchew.org; Tue, 25 May 2021 12:09:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60250) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeK-0001Po-B7 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:16 -0400 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]:38547) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeE-0006cx-91 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:16 -0400 Received: by mail-pl1-x629.google.com with SMTP id 69so16501246plc.5 for ; Tue, 25 May 2021 08:07:09 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/ttITD/09WEgyyZYjSew5EYoec5er/8eI+cVyDIB5nE=; b=daKKFRRcLaywZWL15AeJKoX+ew8njV0BnP1TXxDXjfrXUCu6nD4LcEOy/AuqsFNeGl WzZt/F+92LNsh95QeW818mV+6FxyRRA/xBkcOPyhDtPBid2IHch04WWaPFBCtJOCNkfi jmThx12PkJBXhyXyIL98JnFGG3hE/nOdLioNyDvZoqaldaUVTb2hTtLxXGYsl6EIorAI OMO/o3bOR/6+PP4lfFtikIE+iE0tNVTLs7dTEUtJs/AEZTuG8TBIyu4PNlVa8F5OyPq3 Ol3xm7wTDScwmUWfTmtoBtZFVOhXV5A6S2bN2KU/PiQkMdji4xnBtQv32AtU7FgnO6Lw zwdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/ttITD/09WEgyyZYjSew5EYoec5er/8eI+cVyDIB5nE=; b=kgDPRhgmaeEHuO4R61d5M1mbNSTZmHFSc4YubMULTaJrzDHbh4HqAV3Ug5ASH8yKCD NAZ+aIshBJxV9hFwSOWqqR3usDHyJUlgVjldmDLJAUo2vqd7aVKqStajm0eT5acQRLtG qeifIs5/xD8IrCi26rqixJtiipkp2usHxb51MrivSvJDdCsvGH3acJztaxWm6wfL51CW zpE84N9kFZOPMRKSvZQ4hzJfZTcX/2FHBOaXT2CBsGu0lmCDWNMuUv548+4p+xQgU5cT e+sAzjNge6i+Q53J+C3+SmgZctXL42cecRSzmQobtkwgEl8rtlkkD+551WRCSJo0skL8 qhmw== X-Gm-Message-State: AOAM532dTzvbuKRXJgCNoWYswktN1ZY6fv0Jcu5mLUDqJPZdjK4rhJti pYPhFl7vYxp9XPqcMPQrpkONblEfiyWVSg== X-Google-Smtp-Source: ABdhPJzBemcEoBYdfKhsV9/oMkKdDuc6UFIAT4gqp70EUxfOEBudIU+/VyRDosfNORForQaqrb8Zug== X-Received: by 2002:a17:902:a3c3:b029:f0:b297:7778 with SMTP id q3-20020a170902a3c3b02900f0b2977778mr31233860plb.16.1621955228305; Tue, 25 May 2021 08:07:08 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 01/28] softfloat: Move round_to_uint_and_pack to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:39 -0700 Message-Id: <20210525150706.294968-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::629; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x629.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Rename to parts$N_float_to_uint. Reimplement float128_to_uint{32,64}{_round_to_zero} with FloatParts128. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 357 +++++++++----------------------------- fpu/softfloat-parts.c.inc | 68 +++++++- 2 files changed, 147 insertions(+), 278 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 0dc2203477..3181678ea9 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -839,6 +839,16 @@ static int64_t parts128_float_to_sint(FloatParts128 *p= , FloatRoundMode rmode, #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) =20 +static uint64_t parts64_float_to_uint(FloatParts64 *p, FloatRoundMode rmod= e, + int scale, uint64_t max, + float_status *s); +static uint64_t parts128_float_to_uint(FloatParts128 *p, FloatRoundMode rm= ode, + int scale, uint64_t max, + float_status *s); + +#define parts_float_to_uint(P, R, Z, M, S) \ + PARTS_GENERIC_64_128(float_to_uint, P)(P, R, Z, M, S) + /* * Helper functions for softfloat-parts.c.inc, per-size operations. */ @@ -2646,80 +2656,16 @@ int64_t bfloat16_to_int64_round_to_zero(bfloat16 a,= float_status *s) } =20 /* - * Returns the result of converting the floating-point value `a' to - * the unsigned integer format. The conversion is performed according - * to the IEC/IEEE Standard for Binary Floating-Point - * Arithmetic---which means in particular that the conversion is - * rounded according to the current rounding mode. If `a' is a NaN, - * the largest unsigned integer is returned. Otherwise, if the - * conversion overflows, the largest unsigned integer is returned. If - * the 'a' is negative, the result is rounded and zero is returned; - * values that do not round to zero will raise the inexact exception - * flag. + * Floating-point to unsigned integer conversions */ =20 -static uint64_t round_to_uint_and_pack(FloatParts64 p, FloatRoundMode rmod= e, - int scale, uint64_t max, - float_status *s) -{ - int flags =3D 0; - uint64_t r; - - switch (p.cls) { - case float_class_snan: - case float_class_qnan: - flags =3D float_flag_invalid; - r =3D max; - break; - - case float_class_inf: - flags =3D float_flag_invalid; - r =3D p.sign ? 0 : max; - break; - - case float_class_zero: - return 0; - - case float_class_normal: - /* TODO: 62 =3D N - 2, frac_size for rounding */ - if (parts_round_to_int_normal(&p, rmode, scale, 62)) { - flags =3D float_flag_inexact; - if (p.cls =3D=3D float_class_zero) { - r =3D 0; - break; - } - } - - if (p.sign) { - flags =3D float_flag_invalid; - r =3D 0; - } else if (p.exp > DECOMPOSED_BINARY_POINT) { - flags =3D float_flag_invalid; - r =3D max; - } else { - r =3D p.frac >> (DECOMPOSED_BINARY_POINT - p.exp); - if (r > max) { - flags =3D float_flag_invalid; - r =3D max; - } - } - break; - - default: - g_assert_not_reached(); - } - - float_raise(flags, s); - return r; -} - uint8_t float16_to_uint8_scalbn(float16 a, FloatRoundMode rmode, int scale, float_status *s) { FloatParts64 p; =20 float16_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT8_MAX, s); + return parts_float_to_uint(&p, rmode, scale, UINT8_MAX, s); } =20 uint16_t float16_to_uint16_scalbn(float16 a, FloatRoundMode rmode, int sca= le, @@ -2728,7 +2674,7 @@ uint16_t float16_to_uint16_scalbn(float16 a, FloatRou= ndMode rmode, int scale, FloatParts64 p; =20 float16_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT16_MAX, s); + return parts_float_to_uint(&p, rmode, scale, UINT16_MAX, s); } =20 uint32_t float16_to_uint32_scalbn(float16 a, FloatRoundMode rmode, int sca= le, @@ -2737,7 +2683,7 @@ uint32_t float16_to_uint32_scalbn(float16 a, FloatRou= ndMode rmode, int scale, FloatParts64 p; =20 float16_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT32_MAX, s); + return parts_float_to_uint(&p, rmode, scale, UINT32_MAX, s); } =20 uint64_t float16_to_uint64_scalbn(float16 a, FloatRoundMode rmode, int sca= le, @@ -2746,7 +2692,7 @@ uint64_t float16_to_uint64_scalbn(float16 a, FloatRou= ndMode rmode, int scale, FloatParts64 p; =20 float16_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT64_MAX, s); + return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s); } =20 uint16_t float32_to_uint16_scalbn(float32 a, FloatRoundMode rmode, int sca= le, @@ -2755,7 +2701,7 @@ uint16_t float32_to_uint16_scalbn(float32 a, FloatRou= ndMode rmode, int scale, FloatParts64 p; =20 float32_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT16_MAX, s); + return parts_float_to_uint(&p, rmode, scale, UINT16_MAX, s); } =20 uint32_t float32_to_uint32_scalbn(float32 a, FloatRoundMode rmode, int sca= le, @@ -2764,7 +2710,7 @@ uint32_t float32_to_uint32_scalbn(float32 a, FloatRou= ndMode rmode, int scale, FloatParts64 p; =20 float32_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT32_MAX, s); + return parts_float_to_uint(&p, rmode, scale, UINT32_MAX, s); } =20 uint64_t float32_to_uint64_scalbn(float32 a, FloatRoundMode rmode, int sca= le, @@ -2773,7 +2719,7 @@ uint64_t float32_to_uint64_scalbn(float32 a, FloatRou= ndMode rmode, int scale, FloatParts64 p; =20 float32_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT64_MAX, s); + return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s); } =20 uint16_t float64_to_uint16_scalbn(float64 a, FloatRoundMode rmode, int sca= le, @@ -2782,7 +2728,7 @@ uint16_t float64_to_uint16_scalbn(float64 a, FloatRou= ndMode rmode, int scale, FloatParts64 p; =20 float64_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT16_MAX, s); + return parts_float_to_uint(&p, rmode, scale, UINT16_MAX, s); } =20 uint32_t float64_to_uint32_scalbn(float64 a, FloatRoundMode rmode, int sca= le, @@ -2791,7 +2737,7 @@ uint32_t float64_to_uint32_scalbn(float64 a, FloatRou= ndMode rmode, int scale, FloatParts64 p; =20 float64_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT32_MAX, s); + return parts_float_to_uint(&p, rmode, scale, UINT32_MAX, s); } =20 uint64_t float64_to_uint64_scalbn(float64 a, FloatRoundMode rmode, int sca= le, @@ -2800,7 +2746,52 @@ uint64_t float64_to_uint64_scalbn(float64 a, FloatRo= undMode rmode, int scale, FloatParts64 p; =20 float64_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT64_MAX, s); + return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s); +} + +uint16_t bfloat16_to_uint16_scalbn(bfloat16 a, FloatRoundMode rmode, + int scale, float_status *s) +{ + FloatParts64 p; + + bfloat16_unpack_canonical(&p, a, s); + return parts_float_to_uint(&p, rmode, scale, UINT16_MAX, s); +} + +uint32_t bfloat16_to_uint32_scalbn(bfloat16 a, FloatRoundMode rmode, + int scale, float_status *s) +{ + FloatParts64 p; + + bfloat16_unpack_canonical(&p, a, s); + return parts_float_to_uint(&p, rmode, scale, UINT32_MAX, s); +} + +uint64_t bfloat16_to_uint64_scalbn(bfloat16 a, FloatRoundMode rmode, + int scale, float_status *s) +{ + FloatParts64 p; + + bfloat16_unpack_canonical(&p, a, s); + return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s); +} + +static uint32_t float128_to_uint32_scalbn(float128 a, FloatRoundMode rmode, + int scale, float_status *s) +{ + FloatParts128 p; + + float128_unpack_canonical(&p, a, s); + return parts_float_to_uint(&p, rmode, scale, UINT32_MAX, s); +} + +static uint64_t float128_to_uint64_scalbn(float128 a, FloatRoundMode rmode, + int scale, float_status *s) +{ + FloatParts128 p; + + float128_unpack_canonical(&p, a, s); + return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s); } =20 uint8_t float16_to_uint8(float16 a, float_status *s) @@ -2853,6 +2844,16 @@ uint64_t float64_to_uint64(float64 a, float_status *= s) return float64_to_uint64_scalbn(a, s->float_rounding_mode, 0, s); } =20 +uint32_t float128_to_uint32(float128 a, float_status *s) +{ + return float128_to_uint32_scalbn(a, s->float_rounding_mode, 0, s); +} + +uint64_t float128_to_uint64(float128 a, float_status *s) +{ + return float128_to_uint64_scalbn(a, s->float_rounding_mode, 0, s); +} + uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *s) { return float16_to_uint16_scalbn(a, float_round_to_zero, 0, s); @@ -2898,36 +2899,14 @@ uint64_t float64_to_uint64_round_to_zero(float64 a,= float_status *s) return float64_to_uint64_scalbn(a, float_round_to_zero, 0, s); } =20 -/* - * Returns the result of converting the bfloat16 value `a' to - * the unsigned integer format. - */ - -uint16_t bfloat16_to_uint16_scalbn(bfloat16 a, FloatRoundMode rmode, - int scale, float_status *s) +uint32_t float128_to_uint32_round_to_zero(float128 a, float_status *s) { - FloatParts64 p; - - bfloat16_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT16_MAX, s); + return float128_to_uint32_scalbn(a, float_round_to_zero, 0, s); } =20 -uint32_t bfloat16_to_uint32_scalbn(bfloat16 a, FloatRoundMode rmode, - int scale, float_status *s) +uint64_t float128_to_uint64_round_to_zero(float128 a, float_status *s) { - FloatParts64 p; - - bfloat16_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT32_MAX, s); -} - -uint64_t bfloat16_to_uint64_scalbn(bfloat16 a, FloatRoundMode rmode, - int scale, float_status *s) -{ - FloatParts64 p; - - bfloat16_unpack_canonical(&p, a, s); - return round_to_uint_and_pack(p, rmode, scale, UINT64_MAX, s); + return float128_to_uint64_scalbn(a, float_round_to_zero, 0, s); } =20 uint16_t bfloat16_to_uint16(bfloat16 a, float_status *s) @@ -4123,66 +4102,6 @@ static int64_t roundAndPackInt64(bool zSign, uint64_= t absZ0, uint64_t absZ1, =20 } =20 -/*------------------------------------------------------------------------= ---- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input wor= ds), -| and returns the properly rounded 64-bit unsigned integer corresponding t= o the -| input. Ordinarily, the fixed-point input is simply rounded to an intege= r, -| with the inexact exception raised if the input cannot be represented exa= ctly -| as an integer. However, if the fixed-point input is too large, the inva= lid -| exception is raised and the largest unsigned integer is returned. -*-------------------------------------------------------------------------= ---*/ - -static int64_t roundAndPackUint64(bool zSign, uint64_t absZ0, - uint64_t absZ1, float_status *status) -{ - int8_t roundingMode; - bool roundNearestEven, increment; - - roundingMode =3D status->float_rounding_mode; - roundNearestEven =3D (roundingMode =3D=3D float_round_nearest_even); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - increment =3D ((int64_t)absZ1 < 0); - break; - case float_round_to_zero: - increment =3D 0; - break; - case float_round_up: - increment =3D !zSign && absZ1; - break; - case float_round_down: - increment =3D zSign && absZ1; - break; - case float_round_to_odd: - increment =3D !(absZ0 & 1) && absZ1; - break; - default: - abort(); - } - if (increment) { - ++absZ0; - if (absZ0 =3D=3D 0) { - float_raise(float_flag_invalid, status); - return UINT64_MAX; - } - if (!(absZ1 << 1) && roundNearestEven) { - absZ0 &=3D ~1; - } - } - - if (zSign && absZ0) { - float_raise(float_flag_invalid, status); - return 0; - } - - if (absZ1) { - float_raise(float_flag_inexact, status); - } - return absZ0; -} - /*------------------------------------------------------------------------= ---- | Normalizes the subnormal single-precision floating-point value represent= ed | by the denormalized significand `aSig'. The normalized exponent and @@ -6536,122 +6455,6 @@ floatx80 floatx80_sqrt(floatx80 a, float_status *st= atus) 0, zExp, zSig0, zSig1, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the quadruple-precision floating-point = value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. If the conversion overflows, the -| largest unsigned integer is returned. If 'a' is negative, the value is -| rounded and zero is returned; negative values that do not round to zero -| will raise the inexact exception. -*-------------------------------------------------------------------------= ---*/ - -uint64_t float128_to_uint64(float128 a, float_status *status) -{ - bool aSign; - int aExp; - int shiftCount; - uint64_t aSig0, aSig1; - - aSig0 =3D extractFloat128Frac0(a); - aSig1 =3D extractFloat128Frac1(a); - aExp =3D extractFloat128Exp(a); - aSign =3D extractFloat128Sign(a); - if (aSign && (aExp > 0x3FFE)) { - float_raise(float_flag_invalid, status); - if (float128_is_any_nan(a)) { - return UINT64_MAX; - } else { - return 0; - } - } - if (aExp) { - aSig0 |=3D UINT64_C(0x0001000000000000); - } - shiftCount =3D 0x402F - aExp; - if (shiftCount <=3D 0) { - if (0x403E < aExp) { - float_raise(float_flag_invalid, status); - return UINT64_MAX; - } - shortShift128Left(aSig0, aSig1, -shiftCount, &aSig0, &aSig1); - } else { - shift64ExtraRightJamming(aSig0, aSig1, shiftCount, &aSig0, &aSig1); - } - return roundAndPackUint64(aSign, aSig0, aSig1, status); -} - -uint64_t float128_to_uint64_round_to_zero(float128 a, float_status *status) -{ - uint64_t v; - signed char current_rounding_mode =3D status->float_rounding_mode; - - set_float_rounding_mode(float_round_to_zero, status); - v =3D float128_to_uint64(a, status); - set_float_rounding_mode(current_rounding_mode, status); - - return v; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the 32-bit unsigned integer format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, -| if the conversion overflows, the largest unsigned integer is returned. -| If 'a' is negative, the value is rounded and zero is returned; negative -| values that do not round to zero will raise the inexact exception. -*-------------------------------------------------------------------------= ---*/ - -uint32_t float128_to_uint32_round_to_zero(float128 a, float_status *status) -{ - uint64_t v; - uint32_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float128_to_uint64_round_to_zero(a, status); - if (v > 0xffffffff) { - res =3D 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the quadruple-precision floating-point = value -| `a' to the 32-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. If the conversion overflows, the -| largest unsigned integer is returned. If 'a' is negative, the value is -| rounded and zero is returned; negative values that do not round to zero -| will raise the inexact exception. -*-------------------------------------------------------------------------= ---*/ - -uint32_t float128_to_uint32(float128 a, float_status *status) -{ - uint64_t v; - uint32_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float128_to_uint64(a, status); - if (v > 0xffffffff) { - res =3D 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - /*------------------------------------------------------------------------= ---- | Returns the result of converting the quadruple-precision floating-point | value `a' to the extended double-precision floating-point format. The diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index a897a5a743..c6e327547f 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -761,7 +761,7 @@ static void partsN(round_to_int)(FloatPartsN *a, FloatR= oundMode rmode, * the largest positive integer is returned. Otherwise, if the * conversion overflows, the largest integer with the same sign as `a' * is returned. -*/ + */ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode, int scale, int64_t min, int64_t max, float_status *s) @@ -815,3 +815,69 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, F= loatRoundMode rmode, float_raise(flags, s); return r; } + +/* + * Returns the result of converting the floating-point value `a' to + * the unsigned integer format. The conversion is performed according + * to the IEC/IEEE Standard for Binary Floating-Point + * Arithmetic---which means in particular that the conversion is + * rounded according to the current rounding mode. If `a' is a NaN, + * the largest unsigned integer is returned. Otherwise, if the + * conversion overflows, the largest unsigned integer is returned. If + * the 'a' is negative, the result is rounded and zero is returned; + * values that do not round to zero will raise the inexact exception + * flag. + */ +static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode, + int scale, uint64_t max, float_statu= s *s) +{ + int flags =3D 0; + uint64_t r; + + switch (p->cls) { + case float_class_snan: + case float_class_qnan: + flags =3D float_flag_invalid; + r =3D max; + break; + + case float_class_inf: + flags =3D float_flag_invalid; + r =3D p->sign ? 0 : max; + 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, scale, N - 2)) { + flags =3D float_flag_inexact; + if (p->cls =3D=3D float_class_zero) { + r =3D 0; + break; + } + } + + if (p->sign) { + flags =3D float_flag_invalid; + r =3D 0; + } else if (p->exp > DECOMPOSED_BINARY_POINT) { + flags =3D float_flag_invalid; + r =3D max; + } else { + r =3D p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp); + if (r > max) { + flags =3D float_flag_invalid; + r =3D max; + } + } + break; + + default: + g_assert_not_reached(); + } + + float_raise(flags, s); + return r; +} --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959844; cv=none; d=zohomail.com; s=zohoarc; b=Nyy24WhGKny3y4w+OgNuJtT7DDYyv4+FX0eRSHgt8izUn4UZVwqrGgTFagxF4mcrsDOypHHkR1KgccfrfD+3z0SMAoih63ftZiHlnfTtXV07LnuZKz5dvT0QhNCLewyb8cY/ggPGz05f5sFhjMrDX5V2df2EwMPAmpwHzGvcwI0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959844; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=rGDd4IrgxvYUwN/P21Hl5FXEtH+AR/o/zuzvqPcST80=; b=TFZsSunQDhgkFj0St2QPYfM071JJacOqzxyvvq1xr1YHQu8Bj1mrpzgZIBk62gTMK3nPR+pVL29LM6+rIA6LDBmIDqjSTYPtmjGAACwt8YeWLZs0dpfnL0F5SV78/m00/PzJsKmJkhjI4DW9SZ8FZPfIw4spXEiFF5bl8WJST9Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959844469182.699908147541; Tue, 25 May 2021 09:24:04 -0700 (PDT) Received: from localhost ([::1]:47566 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZqd-0006pi-Dn for importer@patchew.org; Tue, 25 May 2021 12:24:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60288) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeO-0001Uw-4d for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:20 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]:52803) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeE-0006d1-CZ for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:19 -0400 Received: by mail-pj1-x102c.google.com with SMTP id q6so17013435pjj.2 for ; Tue, 25 May 2021 08:07:09 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rGDd4IrgxvYUwN/P21Hl5FXEtH+AR/o/zuzvqPcST80=; b=I8yzv1wq757NIPDwnMio/+AxYdSBxOvyRi1A8SdCyrBIRMzofpJIH4jJznULi6Vsbo JSCpuFSpOVbkXQRD9XKOTAdEJua12Em2CBdESEVs9eQZfa5Z6k7ddAwl1mcenODuApIm njL+AdBgLEI45MeW1HRKOGbX1XVAivEpf4WqUhTnHLVs23yCVt039Rf/2LLWJTGX3Gwc TRbqYLo7p1FexSRvzhHUEW+9DhrpiN9mFGp87dC6BEaY0ZtyWxeqfDRYonl75wz44srm Ea9JVgWOrTpIqQlEABpCKHFb649z1JsPZBvj2PgVSBd+DGd3eXvR3IlPnwLP02ON9/SJ 41eQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rGDd4IrgxvYUwN/P21Hl5FXEtH+AR/o/zuzvqPcST80=; b=iSbX3XBdVmfuG+jR5X1M5BhEfcLc+ZFKzZ+j/Z+LOAAFA7YbrNhrio+/ECJ8r3ZWf1 KWXQwmTdwzCotpnmm3c0XOKRf152xYYFUTNdTGkymLDhCndExvgBuRQZE7XjVaFjD0nt LvGzQbfVpgBG/2DDK8Lly4I1KjKg4CTl3i8hpaOhoiDV8ulfqm1rRO+FGLkkSbLedvYn giuIBmTXuIS+NLLluDFvY7GPy+UQJPyzF3VjvpMRNsk/0y7e960rIfNMZaHp1lyC3ZOR XTSfE0nXNoc4wtKsqNRlbTAX9h9R36pUCEnvIAXduV1ID85uM99XPOJlCaMsCd+rzEzb qCQw== X-Gm-Message-State: AOAM531Im/MJBazkfN9MVf53nEy0Lj6CvdNvH6I31gV8XdbCW9hUieDq 6zxDaUbmSELi2sQVVA0rYhSWB7vb1CUHvQ== X-Google-Smtp-Source: ABdhPJwZsJm8PfLKm3VQweFDVtoO1h3Cwr6pWMJ9/ghKaAr2kjR+aCviR0M/cwwqChDRqciONilXWA== X-Received: by 2002:a17:90a:9d88:: with SMTP id k8mr5235831pjp.64.1621955229060; Tue, 25 May 2021 08:07:09 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 02/28] softfloat: Move int_to_float to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:40 -0700 Message-Id: <20210525150706.294968-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102c.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Rename to parts$N_sint_to_float. Reimplement int{32,64}_to_float128 with FloatParts128. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e Reviewed-by: David Hildenbrand --- fpu/softfloat.c | 136 +++++++++++--------------------------- fpu/softfloat-parts.c.inc | 32 +++++++++ 2 files changed, 70 insertions(+), 98 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3181678ea9..6404a2997f 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -849,6 +849,14 @@ 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) =20 +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_sint_to_float(P, I, Z, S) \ + PARTS_GENERIC_64_128(sint_to_float, P)(P, I, Z, S) + /* * Helper functions for softfloat-parts.c.inc, per-size operations. */ @@ -2940,42 +2948,15 @@ uint64_t bfloat16_to_uint64_round_to_zero(bfloat16 = a, float_status *s) } =20 /* - * Integer to float conversions - * - * Returns the result of converting the two's complement integer `a' - * to the floating-point format. The conversion is performed according - * to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. + * Signed integer to floating-point conversions */ =20 -static FloatParts64 int_to_float(int64_t a, int scale, float_status *statu= s) -{ - FloatParts64 r =3D { .sign =3D false }; - - if (a =3D=3D 0) { - r.cls =3D float_class_zero; - } else { - uint64_t f =3D a; - int shift; - - r.cls =3D float_class_normal; - if (a < 0) { - f =3D -f; - r.sign =3D true; - } - shift =3D clz64(f); - scale =3D MIN(MAX(scale, -0x10000), 0x10000); - - r.exp =3D DECOMPOSED_BINARY_POINT - shift + scale; - r.frac =3D f << shift; - } - - return r; -} - float16 int64_to_float16_scalbn(int64_t a, int scale, float_status *status) { - FloatParts64 pa =3D int_to_float(a, scale, status); - return float16_round_pack_canonical(&pa, status); + FloatParts64 p; + + parts_sint_to_float(&p, a, scale, status); + return float16_round_pack_canonical(&p, status); } =20 float16 int32_to_float16_scalbn(int32_t a, int scale, float_status *status) @@ -3010,8 +2991,10 @@ float16 int8_to_float16(int8_t a, float_status *stat= us) =20 float32 int64_to_float32_scalbn(int64_t a, int scale, float_status *status) { - FloatParts64 pa =3D int_to_float(a, scale, status); - return float32_round_pack_canonical(&pa, status); + FloatParts64 p; + + parts64_sint_to_float(&p, a, scale, status); + return float32_round_pack_canonical(&p, status); } =20 float32 int32_to_float32_scalbn(int32_t a, int scale, float_status *status) @@ -3041,8 +3024,10 @@ float32 int16_to_float32(int16_t a, float_status *st= atus) =20 float64 int64_to_float64_scalbn(int64_t a, int scale, float_status *status) { - FloatParts64 pa =3D int_to_float(a, scale, status); - return float64_round_pack_canonical(&pa, status); + FloatParts64 p; + + parts_sint_to_float(&p, a, scale, status); + return float64_round_pack_canonical(&p, status); } =20 float64 int32_to_float64_scalbn(int32_t a, int scale, float_status *status) @@ -3070,15 +3055,12 @@ float64 int16_to_float64(int16_t a, float_status *s= tatus) return int64_to_float64_scalbn(a, 0, status); } =20 -/* - * Returns the result of converting the two's complement integer `a' - * to the bfloat16 format. - */ - bfloat16 int64_to_bfloat16_scalbn(int64_t a, int scale, float_status *stat= us) { - FloatParts64 pa =3D int_to_float(a, scale, status); - return bfloat16_round_pack_canonical(&pa, status); + FloatParts64 p; + + parts_sint_to_float(&p, a, scale, status); + return bfloat16_round_pack_canonical(&p, status); } =20 bfloat16 int32_to_bfloat16_scalbn(int32_t a, int scale, float_status *stat= us) @@ -3106,6 +3088,19 @@ bfloat16 int16_to_bfloat16(int16_t a, float_status *= status) return int64_to_bfloat16_scalbn(a, 0, status); } =20 +float128 int64_to_float128(int64_t a, float_status *status) +{ + FloatParts128 p; + + parts_sint_to_float(&p, a, 0, status); + return float128_round_pack_canonical(&p, status); +} + +float128 int32_to_float128(int32_t a, float_status *status) +{ + return int64_to_float128(a, status); +} + /* * Unsigned Integer to float conversions * @@ -4956,28 +4951,6 @@ floatx80 int32_to_floatx80(int32_t a, float_status *= status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the 32-bit two's complement integer `a'= to -| the quadruple-precision floating-point format. The conversion is perfor= med -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float128 int32_to_float128(int32_t a, float_status *status) -{ - bool zSign; - uint32_t absA; - int8_t shiftCount; - uint64_t zSig0; - - if ( a =3D=3D 0 ) return packFloat128( 0, 0, 0, 0 ); - zSign =3D ( a < 0 ); - absA =3D zSign ? - a : a; - shiftCount =3D clz32(absA) + 17; - zSig0 =3D absA; - return packFloat128( zSign, 0x402E - shiftCount, zSig0<cls =3D float_class_zero; + return; + } + + p->cls =3D float_class_normal; + if (a < 0) { + f =3D -f; + p->sign =3D true; + } + shift =3D clz64(f); + scale =3D MIN(MAX(scale, -0x10000), 0x10000); + + p->exp =3D DECOMPOSED_BINARY_POINT - shift + scale; + p->frac_hi =3D f << shift; +} --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959743; cv=none; d=zohomail.com; s=zohoarc; b=Qykn7gOvuxIy/3BTT/C+Zvdiey9bb+Aw50+XoYjRiRPckurNx7amp7FDEAt7zXCVNRJ7aqsWJc/HgowEl9NeYFU8FAFSa6nbnnHSrT/2y7YTqSXJSA9RE9NtWPq9g9AcakSo0u9y/HsbPj/xVzR7NG23iLkiNmDo4GTRC2Mkb/Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959743; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=uI7SP4Waz/iN5MUyXkTADhvd6hV2rHFBbWY60pbiMEg=; b=oD01bndBdZkQB1vIInVYbSk44jkAk5XOeIfADJAbY62D9q5NylBsvayVdPcq1Kz4y0lKUZka8AOlxeMA9dRZcoCECHC2rSfbv+DPOqK0R17nbOsTLxEKFS/xVe8lJWELTpennLJZvxAOTSBXqeldGks7/1+Xwe2I2+CcDSZPNQY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959743675897.7156817794738; Tue, 25 May 2021 09:22:23 -0700 (PDT) Received: from localhost ([::1]:41502 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZp0-0002oT-WA for importer@patchew.org; Tue, 25 May 2021 12:22:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60274) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeN-0001TU-J4 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:19 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]:46670) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeG-0006d6-9p for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:18 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d20so2211826pls.13 for ; Tue, 25 May 2021 08:07:10 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uI7SP4Waz/iN5MUyXkTADhvd6hV2rHFBbWY60pbiMEg=; b=DqwIV3hV80PE6LktFCa/zxeQDADQnrHgykJdYu4ZGqWQxmyLgctJJJoxUx+U4OYUgS VqBM/1fNz478sKGdYktPrJ86j5BP2NC1KrlsGKALyLZDHju3AJddPZPUekrbRfymQPzI 9QgxXT33g2WSuLTZEyXSXBNpFcPKuUscliYmrD3a25KC9vV1p0njREkbkn54HUGuYHDt Yhe0kG4sijOJ/uITsHkZa7fc3YQm3gT6/DmfJMvHxB4tugLcJKldYcHtRmlJSYNm15Gd hXtLJSjUsnHyni/ETEUAe75SEoRwgjzEBPx6ZTlUNfuj/BbSOez/9llZs54dHKAKMa5t hqTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uI7SP4Waz/iN5MUyXkTADhvd6hV2rHFBbWY60pbiMEg=; b=MMewIE1IZaR7p51MjfpqF2XU86oc9OqcoWqczbivjG3T51s40OWsocOJWq+2rXZxez TtWOfRNUW/6YN2mLqMEfijDvtFqdiFcUFBF7rfcjQKWyOEFRXyo6JSyzvw9fcOhIj2oI KFj0T/R18bn+yNMWftcN9o6ku7kDg15NnLPObOftSA2ggaaUj4C8Jf0BYg//sJtCTIsA fRpmEOHxcId+cw0GSwgv2dp+ksyf8EgmQ4yZjgLCh3lPNtIqdfe31Rg6fEeBV+RiKW+P 2DHYM0vDOlDv0GbvFARfa7WqlWFr6f4Lvpk4Pq6w2yu2ReH12j/Gakf3M+NWkVa44hbI w1/g== X-Gm-Message-State: AOAM531+IJBk6acL5geZiDPVw2DahXgKVcegspNMslyA3qUm4pQO3NFX 12M8gHeM0RTXzi2vA57gevfEye4kacYubg== X-Google-Smtp-Source: ABdhPJwuZJxyMggDYNrkLKT2dmrtphjQfWJsxvOK8kNcZroXaYiu4QoX0R5oMGv5lRb32Sl9v/Il1A== X-Received: by 2002:a17:902:b78a:b029:fc:f326:7de0 with SMTP id e10-20020a170902b78ab02900fcf3267de0mr318833pls.28.1621955229528; Tue, 25 May 2021 08:07:09 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 03/28] softfloat: Move uint_to_float to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:41 -0700 Message-Id: <20210525150706.294968-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62b.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Rename to parts$N_uint_to_float. Reimplement uint64_to_float128 with FloatParts128. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e Reviewed-by: David Hildenbrand --- fpu/softfloat.c | 83 ++++++++++++++++----------------------- fpu/softfloat-parts.c.inc | 23 +++++++++++ 2 files changed, 56 insertions(+), 50 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6404a2997f..db14bd09aa 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -857,6 +857,14 @@ static void parts128_sint_to_float(FloatParts128 *p, i= nt64_t a, #define parts_sint_to_float(P, I, Z, S) \ PARTS_GENERIC_64_128(sint_to_float, P)(P, I, Z, S) =20 +static void parts64_uint_to_float(FloatParts64 *p, uint64_t a, + int scale, float_status *s); +static void parts128_uint_to_float(FloatParts128 *p, uint64_t a, + int scale, float_status *s); + +#define parts_uint_to_float(P, I, Z, S) \ + PARTS_GENERIC_64_128(uint_to_float, P)(P, I, Z, S) + /* * Helper functions for softfloat-parts.c.inc, per-size operations. */ @@ -3102,35 +3110,15 @@ float128 int32_to_float128(int32_t a, float_status = *status) } =20 /* - * Unsigned Integer to float conversions - * - * Returns the result of converting the unsigned integer `a' to the - * floating-point format. The conversion is performed according to the - * IEC/IEEE Standard for Binary Floating-Point Arithmetic. + * Unsigned Integer to floating-point conversions */ =20 -static FloatParts64 uint_to_float(uint64_t a, int scale, float_status *sta= tus) -{ - FloatParts64 r =3D { .sign =3D false }; - int shift; - - if (a =3D=3D 0) { - r.cls =3D float_class_zero; - } else { - scale =3D MIN(MAX(scale, -0x10000), 0x10000); - shift =3D clz64(a); - r.cls =3D float_class_normal; - r.exp =3D DECOMPOSED_BINARY_POINT - shift + scale; - r.frac =3D a << shift; - } - - return r; -} - float16 uint64_to_float16_scalbn(uint64_t a, int scale, float_status *stat= us) { - FloatParts64 pa =3D uint_to_float(a, scale, status); - return float16_round_pack_canonical(&pa, status); + FloatParts64 p; + + parts_uint_to_float(&p, a, scale, status); + return float16_round_pack_canonical(&p, status); } =20 float16 uint32_to_float16_scalbn(uint32_t a, int scale, float_status *stat= us) @@ -3165,8 +3153,10 @@ float16 uint8_to_float16(uint8_t a, float_status *st= atus) =20 float32 uint64_to_float32_scalbn(uint64_t a, int scale, float_status *stat= us) { - FloatParts64 pa =3D uint_to_float(a, scale, status); - return float32_round_pack_canonical(&pa, status); + FloatParts64 p; + + parts_uint_to_float(&p, a, scale, status); + return float32_round_pack_canonical(&p, status); } =20 float32 uint32_to_float32_scalbn(uint32_t a, int scale, float_status *stat= us) @@ -3196,8 +3186,10 @@ float32 uint16_to_float32(uint16_t a, float_status *= status) =20 float64 uint64_to_float64_scalbn(uint64_t a, int scale, float_status *stat= us) { - FloatParts64 pa =3D uint_to_float(a, scale, status); - return float64_round_pack_canonical(&pa, status); + FloatParts64 p; + + parts_uint_to_float(&p, a, scale, status); + return float64_round_pack_canonical(&p, status); } =20 float64 uint32_to_float64_scalbn(uint32_t a, int scale, float_status *stat= us) @@ -3225,15 +3217,12 @@ float64 uint16_to_float64(uint16_t a, float_status = *status) return uint64_to_float64_scalbn(a, 0, status); } =20 -/* - * Returns the result of converting the unsigned integer `a' to the - * bfloat16 format. - */ - bfloat16 uint64_to_bfloat16_scalbn(uint64_t a, int scale, float_status *st= atus) { - FloatParts64 pa =3D uint_to_float(a, scale, status); - return bfloat16_round_pack_canonical(&pa, status); + FloatParts64 p; + + parts_uint_to_float(&p, a, scale, status); + return bfloat16_round_pack_canonical(&p, status); } =20 bfloat16 uint32_to_bfloat16_scalbn(uint32_t a, int scale, float_status *st= atus) @@ -3261,6 +3250,14 @@ bfloat16 uint16_to_bfloat16(uint16_t a, float_status= *status) return uint64_to_bfloat16_scalbn(a, 0, status); } =20 +float128 uint64_to_float128(uint64_t a, float_status *status) +{ + FloatParts128 p; + + parts_uint_to_float(&p, a, 0, status); + return float128_round_pack_canonical(&p, status); +} + /* Float Min/Max */ /* min() and max() functions. These can't be implemented as * 'compare and pick one input' because that would mishandle @@ -4972,20 +4969,6 @@ floatx80 int64_to_floatx80(int64_t a, float_status *= status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the 64-bit unsigned integer `a' -| to the quadruple-precision floating-point format. The conversion is per= formed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float128 uint64_to_float128(uint64_t a, float_status *status) -{ - if (a =3D=3D 0) { - return float128_zero; - } - return normalizeRoundAndPackFloat128(0, 0x406E, 0, a, status); -} - /*------------------------------------------------------------------------= ---- | Returns the result of converting the single-precision floating-point val= ue | `a' to the extended double-precision floating-point format. The convers= ion diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index 8102de1307..f3c4f8c8d2 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -913,3 +913,26 @@ static void partsN(sint_to_float)(FloatPartsN *p, int6= 4_t a, p->exp =3D DECOMPOSED_BINARY_POINT - shift + scale; p->frac_hi =3D f << shift; } + +/* + * Unsigned Integer to float conversions + * + * Returns the result of converting the unsigned integer `a' to the + * floating-point format. The conversion is performed according to the + * IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ +static void partsN(uint_to_float)(FloatPartsN *p, uint64_t a, + int scale, float_status *status) +{ + memset(p, 0, sizeof(*p)); + + if (a =3D=3D 0) { + p->cls =3D float_class_zero; + } else { + int shift =3D clz64(a); + scale =3D MIN(MAX(scale, -0x10000), 0x10000); + p->cls =3D float_class_normal; + p->exp =3D DECOMPOSED_BINARY_POINT - shift + scale; + p->frac_hi =3D a << shift; + } +} --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959605; cv=none; d=zohomail.com; s=zohoarc; b=RuttDPtkxMDq1p+hmrDk6lT1Bf62RYZXwcYIb/9d/1A2efa0l98JSRwauseGwZThwirTWDyA/Uq+JI6kM5Hg24fMKnkkiymft+A7z7Du8RdGob9ZG0FdJ3FTyAxB7YAoyAZw8jLpSByoDgT+p2bohxdNYaGQAVwBqDCHm58Mj4Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959605; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=cwk6k6WelU2y/W9DtVCo3TZQRRzAyY6JxxIHIEVoyWE=; b=aJ3dxpCQm/XzXvfQZV+6dpeUQ6iJZG5nWp71r81uYyXteFqoks/J5QSvQtXC4/CwnkyQa2OxkpBLBXHmcE+SW1bE5kV1qePAJq6HQ8FiPqUEGO4eo+4jZOdNxTqEBEeG2Oy50+Xkmqp9WKiSaP+BGG8nUaFwKgM+es7YGa+e4Oc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959605190596.9369331430194; Tue, 25 May 2021 09:20:05 -0700 (PDT) Received: from localhost ([::1]:60832 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZml-0005G7-KD for importer@patchew.org; Tue, 25 May 2021 12:20:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60282) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeN-0001UD-7e for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:19 -0400 Received: from mail-pg1-x530.google.com ([2607:f8b0:4864:20::530]:45875) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeG-0006dG-9o for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:18 -0400 Received: by mail-pg1-x530.google.com with SMTP id q15so22958499pgg.12 for ; Tue, 25 May 2021 08:07:11 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cwk6k6WelU2y/W9DtVCo3TZQRRzAyY6JxxIHIEVoyWE=; b=xSdbYx+ETf7JwnmVhAOcOOb5/3vAL77+h7Jx8b6ClmhsANtk6Do+pXyecWXdjupRuB XRGqCPccLuURyiTc8A7ex9buqaZrOqyM5UIKU2bZylIaBHWQGCKRkDDpNg3Cpb48+hFQ bn8oXPWGi2Fa40Mkkehqgw+IAvYuzi8B5nuaqau7B5H6zGdTWY4jejAxpDpIujEzhCLc mqth0HOtTHkDzv4Z5/HQeKKz3pKFW4AMcydrTZnfPSHQeb7KKA8OHMcjDMxl2u1C80U4 VxcJ1MS09IlhoiTYsNLM2ocnYTTOd9U4Rh9sz1TFT/uynZRyA8CX5T7Fl1Rpqhw/7zWD f5kA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cwk6k6WelU2y/W9DtVCo3TZQRRzAyY6JxxIHIEVoyWE=; b=jTtCMaGm1/nmIjeFMD85NcG5K3Qs7MAZgoBlZsWMazd/LjpTf7vacbqdIQDb1kQT8I l3Xhh/RDcoPKyGXDVXys75TIjAgJhGzbbevOelfnOnYZSIIMWxXpVoiToDL219qOkjb7 0VZAe8YKjeYZcTUpxe7Rmt1pKYP8qhGH19Mhf4Wa4SpNeUw1JPjrdEQEPp+VdLAEfFfR z8HSd8fM8q2/sikxOr5C67/DWvdL0Gm897hbd9IN8mMjhC2uH1z672kShLLpcgZfIqHN LLAVk2QRCzNziCth9pO7/W/jsoSX7Q78P3I8F3a4pE1xMxrcvZ2rLT3K64xRrritKkLf HETw== X-Gm-Message-State: AOAM531+nVMOdgfNgAC9Edq5epu4SneEpUsmZI+LwBnZyRfB+TpFglyp cGd3b64LR7Ldi8yJzHgzPVbEVgLIwzD2pQ== X-Google-Smtp-Source: ABdhPJyte7SQZJ3RRrGu7LWrSslE1TSCfITI2I3lsDygMEfe+96v52mpRWWnBHmzi14PStMlF1o8ug== X-Received: by 2002:a62:8810:0:b029:2db:1af8:fa81 with SMTP id l16-20020a6288100000b02902db1af8fa81mr30649805pfd.46.1621955230086; Tue, 25 May 2021 08:07:10 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 04/28] softfloat: Move minmax_flags to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:42 -0700 Message-Id: <20210525150706.294968-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::530; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x530.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Rename to parts$N_minmax. Combine 3 bool arguments to a bitmask, return a tri-state value to indicate nan vs unchanged operand. Introduce ftype_minmax functions as a common optimization point. Fold bfloat16 expansions into the same macro as the other types. Signed-off-by: Richard Henderson Reviewed-by: David Hildenbrand --- fpu/softfloat.c | 216 ++++++++++++++++---------------------- fpu/softfloat-parts.c.inc | 81 ++++++++++++++ 2 files changed, 170 insertions(+), 127 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index db14bd09aa..2dadded0b5 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -482,6 +482,15 @@ enum { float_cmask_anynan =3D float_cmask_qnan | float_cmask_snan, }; =20 +/* Flags for parts_minmax. */ +enum { + /* Set for minimum; clear for maximum. */ + minmax_ismin =3D 1, + /* Set for the IEEE 754-2008 minNum() and maxNum() operations. */ + minmax_isnum =3D 2, + /* Set for the IEEE 754-2008 minNumMag() and minNumMag() operations. */ + minmax_ismag =3D 4, +}; =20 /* Simple helpers for checking if, or what kind of, NaN we have */ static inline __attribute__((unused)) bool is_nan(FloatClass c) @@ -865,6 +874,14 @@ static void parts128_uint_to_float(FloatParts128 *p, u= int64_t a, #define parts_uint_to_float(P, I, Z, S) \ PARTS_GENERIC_64_128(uint_to_float, P)(P, I, Z, S) =20 +static int parts64_minmax(FloatParts64 *a, FloatParts64 *b, + float_status *s, int flags, const FloatFmt *fmt); +static int parts128_minmax(FloatParts128 *a, FloatParts128 *b, + float_status *s, int flags, const FloatFmt *fmt= ); + +#define parts_minmax(A, B, S, Z, F) \ + PARTS_GENERIC_64_128(minmax, A)(A, B, S, Z, F) + /* * Helper functions for softfloat-parts.c.inc, per-size operations. */ @@ -3258,145 +3275,90 @@ float128 uint64_to_float128(uint64_t a, float_stat= us *status) return float128_round_pack_canonical(&p, status); } =20 -/* Float Min/Max */ -/* min() and max() functions. These can't be implemented as - * 'compare and pick one input' because that would mishandle - * NaNs and +0 vs -0. - * - * minnum() and maxnum() functions. These are similar to the min() - * and max() functions but if one of the arguments is a QNaN and - * the other is numerical then the numerical argument is returned. - * SNaNs will get quietened before being returned. - * minnum() and maxnum correspond to the IEEE 754-2008 minNum() - * and maxNum() operations. min() and max() are the typical min/max - * semantics provided by many CPUs which predate that specification. - * - * minnummag() and maxnummag() functions correspond to minNumMag() - * and minNumMag() from the IEEE-754 2008. +/* + * Minimum and maximum */ -static FloatParts64 minmax_floats(FloatParts64 a, FloatParts64 b, bool ism= in, - bool ieee, bool ismag, float_status *s) + +static float16 float16_minmax(float16 a, float16 b, float_status *s, int f= lags) { - if (unlikely(is_nan(a.cls) || is_nan(b.cls))) { - if (ieee) { - /* Takes two floating-point values `a' and `b', one of - * which is a NaN, and returns the appropriate NaN - * result. If either `a' or `b' is a signaling NaN, - * the invalid exception is raised. - */ - if (is_snan(a.cls) || is_snan(b.cls)) { - return *parts_pick_nan(&a, &b, s); - } else if (is_nan(a.cls) && !is_nan(b.cls)) { - return b; - } else if (is_nan(b.cls) && !is_nan(a.cls)) { - return a; - } - } - return *parts_pick_nan(&a, &b, s); - } else { - int a_exp, b_exp; + FloatParts64 pa, pb; + int which; =20 - switch (a.cls) { - case float_class_normal: - a_exp =3D a.exp; - break; - case float_class_inf: - a_exp =3D INT_MAX; - break; - case float_class_zero: - a_exp =3D INT_MIN; - break; - default: - g_assert_not_reached(); - break; - } - switch (b.cls) { - case float_class_normal: - b_exp =3D b.exp; - break; - case float_class_inf: - b_exp =3D INT_MAX; - break; - case float_class_zero: - b_exp =3D INT_MIN; - break; - default: - g_assert_not_reached(); - break; - } - - if (ismag && (a_exp !=3D b_exp || a.frac !=3D b.frac)) { - bool a_less =3D a_exp < b_exp; - if (a_exp =3D=3D b_exp) { - a_less =3D a.frac < b.frac; - } - return a_less ^ ismin ? b : a; - } - - if (a.sign =3D=3D b.sign) { - bool a_less =3D a_exp < b_exp; - if (a_exp =3D=3D b_exp) { - a_less =3D a.frac < b.frac; - } - return a.sign ^ a_less ^ ismin ? b : a; - } else { - return a.sign ^ ismin ? b : a; - } + float16_unpack_canonical(&pa, a, s); + float16_unpack_canonical(&pb, b, s); + which =3D parts_minmax(&pa, &pb, s, flags, &float16_params); + if (unlikely(which < 0)) { + /* Some sort of nan, need to repack default and silenced nans. */ + return float16_round_pack_canonical(&pa, s); } + return which ? b : a; } =20 -#define MINMAX(sz, name, ismin, isiee, ismag) \ -float ## sz float ## sz ## _ ## name(float ## sz a, float ## sz b, \ - float_status *s) \ -{ \ - FloatParts64 pa, pb, pr; \ - float ## sz ## _unpack_canonical(&pa, a, s); \ - float ## sz ## _unpack_canonical(&pb, b, s); \ - pr =3D minmax_floats(pa, pb, ismin, isiee, ismag, s); \ - return float ## sz ## _round_pack_canonical(&pr, s); \ +static bfloat16 bfloat16_minmax(bfloat16 a, bfloat16 b, + float_status *s, int flags) +{ + FloatParts64 pa, pb; + int which; + + bfloat16_unpack_canonical(&pa, a, s); + bfloat16_unpack_canonical(&pb, b, s); + which =3D parts_minmax(&pa, &pb, s, flags, &float16_params); + if (unlikely(which < 0)) { + /* Some sort of nan, need to repack default and silenced nans. */ + return bfloat16_round_pack_canonical(&pa, s); + } + return which ? b : a; } =20 -MINMAX(16, min, true, false, false) -MINMAX(16, minnum, true, true, false) -MINMAX(16, minnummag, true, true, true) -MINMAX(16, max, false, false, false) -MINMAX(16, maxnum, false, true, false) -MINMAX(16, maxnummag, false, true, true) +static float32 float32_minmax(float32 a, float32 b, float_status *s, int f= lags) +{ + FloatParts64 pa, pb; + int which; =20 -MINMAX(32, min, true, false, false) -MINMAX(32, minnum, true, true, false) -MINMAX(32, minnummag, true, true, true) -MINMAX(32, max, false, false, false) -MINMAX(32, maxnum, false, true, false) -MINMAX(32, maxnummag, false, true, true) - -MINMAX(64, min, true, false, false) -MINMAX(64, minnum, true, true, false) -MINMAX(64, minnummag, true, true, true) -MINMAX(64, max, false, false, false) -MINMAX(64, maxnum, false, true, false) -MINMAX(64, maxnummag, false, true, true) - -#undef MINMAX - -#define BF16_MINMAX(name, ismin, isiee, ismag) \ -bfloat16 bfloat16_ ## name(bfloat16 a, bfloat16 b, float_status *s) \ -{ \ - FloatParts64 pa, pb, pr; \ - bfloat16_unpack_canonical(&pa, a, s); \ - bfloat16_unpack_canonical(&pb, b, s); \ - pr =3D minmax_floats(pa, pb, ismin, isiee, ismag, s); \ - return bfloat16_round_pack_canonical(&pr, s); \ + float32_unpack_canonical(&pa, a, s); + float32_unpack_canonical(&pb, b, s); + which =3D parts_minmax(&pa, &pb, s, flags, &float32_params); + if (unlikely(which < 0)) { + /* Some sort of nan, need to repack default and silenced nans. */ + return float32_round_pack_canonical(&pa, s); + } + return which ? b : a; } =20 -BF16_MINMAX(min, true, false, false) -BF16_MINMAX(minnum, true, true, false) -BF16_MINMAX(minnummag, true, true, true) -BF16_MINMAX(max, false, false, false) -BF16_MINMAX(maxnum, false, true, false) -BF16_MINMAX(maxnummag, false, true, true) +static float64 float64_minmax(float64 a, float64 b, float_status *s, int f= lags) +{ + FloatParts64 pa, pb; + int which; =20 -#undef BF16_MINMAX + float64_unpack_canonical(&pa, a, s); + float64_unpack_canonical(&pb, b, s); + which =3D parts_minmax(&pa, &pb, s, flags, &float64_params); + if (unlikely(which < 0)) { + /* Some sort of nan, need to repack default and silenced nans. */ + return float64_round_pack_canonical(&pa, s); + } + return which ? b : a; +} + +#define MINMAX_1(type, name, flags) \ + type type##_##name(type a, type b, float_status *s) \ + { return type##_minmax(a, b, s, flags); } + +#define MINMAX_2(type) \ + MINMAX_1(type, max, 0) \ + MINMAX_1(type, maxnum, minmax_isnum) \ + MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \ + MINMAX_1(type, min, minmax_ismin) \ + MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \ + MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag) + +MINMAX_2(float16) +MINMAX_2(bfloat16) +MINMAX_2(float32) +MINMAX_2(float64) + +#undef MINMAX_1 +#undef MINMAX_2 =20 /* Floating point compare */ static FloatRelation compare_floats(FloatParts64 a, FloatParts64 b, bool i= s_quiet, diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index f3c4f8c8d2..d68ab8fee0 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -936,3 +936,84 @@ static void partsN(uint_to_float)(FloatPartsN *p, uint= 64_t a, p->frac_hi =3D a << shift; } } + +/* + * Float min/max. + * + * Return -1 to return the chosen nan in *a; + * return 0 to use the a input unchanged; 1 to use the b input unchanged. + */ +static int partsN(minmax)(FloatPartsN *a, FloatPartsN *b, + float_status *s, int flags, const FloatFmt *fmt) +{ + int ab_mask =3D float_cmask(a->cls) | float_cmask(b->cls); + int a_exp, b_exp, cmp; + + if (unlikely(ab_mask & float_cmask_anynan)) { + /* + * For minnum/maxnum, if one operand is a QNaN, and the other + * operand is numerical, then return numerical argument. + */ + if ((flags & minmax_isnum) + && !(ab_mask & float_cmask_snan) + && (ab_mask & ~float_cmask_qnan)) { + return is_nan(a->cls); + } + *a =3D *parts_pick_nan(a, b, s); + return -1; + } + + a_exp =3D a->exp; + b_exp =3D b->exp; + + if (unlikely(ab_mask !=3D float_cmask_normal)) { + switch (a->cls) { + case float_class_normal: + break; + case float_class_inf: + a_exp =3D INT16_MAX; + break; + case float_class_zero: + a_exp =3D INT16_MIN; + break; + default: + g_assert_not_reached(); + break; + } + switch (b->cls) { + case float_class_normal: + break; + case float_class_inf: + b_exp =3D INT16_MAX; + break; + case float_class_zero: + b_exp =3D INT16_MIN; + break; + default: + g_assert_not_reached(); + break; + } + } + + /* Compare magnitudes. */ + cmp =3D a_exp - b_exp; + if (cmp =3D=3D 0) { + cmp =3D frac_cmp(a, b); + } + + /* + * Take the sign into account. + * For ismag, only do this if the magnitudes are equal. + */ + if (!(flags & minmax_ismag) || cmp =3D=3D 0) { + if (a->sign !=3D b->sign) { + /* For differing signs, the negative operand is less. */ + cmp =3D a->sign ? -1 : 1; + } else if (a->sign) { + /* For two negative operands, invert the magnitude comparison.= */ + cmp =3D -cmp; + } + } + + return (cmp < 0) ^ !!(flags & minmax_ismin); +} --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959939; cv=none; d=zohomail.com; s=zohoarc; b=UI0CJop4iQuLGu5o13hFLzOKq7hSj6o2E/HX1MtJFjlJkAJlXcZB8inwyi1Q0g9RsxpXRJjCK5f+0roAsQyQcwqYEiy0ZOVmLjj51K3BIICJqcN/8A4odO3kn85wnlruy86JZLEHgjfLklqC4wOO8pEeBO4Nq7uOa1KiUxK2V/Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959939; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=xT+gSFFP0Pvgx6/sc6D9cAa4M58V2yFxoT6V+q8WC7g=; b=nNOzzKcDO9bhCbCGeWO1PV0CLtf/RAQC9xPjapsCj21/iOXCnq+VUZF769SNBPHSFuy97+7QUmnkVBU/zBpfI0LXS2bDgiyFNdJpLxk/ahD0MqDvw5RfYQ1tiPoNV0WeN+AbKXee8PcyMxNBUeCij64HzEsjgv+cNDWwLVlgiKs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959939103788.4380045402022; Tue, 25 May 2021 09:25:39 -0700 (PDT) Received: from localhost ([::1]:50390 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZs9-0000EO-V4 for importer@patchew.org; Tue, 25 May 2021 12:25:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60322) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0001ZR-0a for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:22 -0400 Received: from mail-pg1-x52d.google.com ([2607:f8b0:4864:20::52d]:33475) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeG-0006dd-Dt for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:21 -0400 Received: by mail-pg1-x52d.google.com with SMTP id i5so23003718pgm.0 for ; Tue, 25 May 2021 08:07:11 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xT+gSFFP0Pvgx6/sc6D9cAa4M58V2yFxoT6V+q8WC7g=; b=v2ywlVESGuw0X0HiWixI4/bkksvmXtCANsoC43fR6EhTJmog+ey8HK7WH+VW8eKkwE hjfeupTmNkMiUH+QwCV2l2BIAGJG21sUm6CItqLTvgC7LNnU0nbLt9dDMFPZzXAmgu3x hOZ3gkO+Xnq8+cOPvOmfCPtXTrj3QZanQ8RPfdOxyExYAdleQMXhUsixfmdys0TxydHZ eCw7n6SJ3kIwCc2tSgrxYFlkDWzUGpKXRymNgNovIjrO6ee6CYQ8Omo4gPzC11DUvLiV 0brfd+h18knJanlOzYGMzSIvdp4phVNzsVee9HygWFRtFjUnyhDOuGuUtbZSE5LNfUdo Kv/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xT+gSFFP0Pvgx6/sc6D9cAa4M58V2yFxoT6V+q8WC7g=; b=W95HrnM4hiSx18emZ7Wif7vGr53j83XniW38KTvN9zJzeAFelsAS33+SPZlT8lJnUU IixUy7/8N7sFgaXczDmjzx2k+9uiANapRkRK83sbGkPMaFCRKyy068dlCsurTuIh8ajN qMbUqsJJinmkN083TqZ5n1v4Tn1JJKEFkJWyyDUWj1k2X5UYO92tzWXzdnJD+80Z0Gaz AoOB3O/EAgR7iSLuLn8SHCm/CmO9IkNvXv1ElTihdZ/z7ePSy3bs83MG5FfPOLgPgmfB lhOSwDbhkfqf1t2AO3fJls8163KC5V51VGq5uoMbzO/JRKxwGEsgILYb04sYKm0YLN90 8+9A== X-Gm-Message-State: AOAM533PW+3vy7uHZoLIVA7pjxtuQjoyzq4ZKk+VS+rs6+C2GxHWHFaQ AMzwttA60qpZ7c1Hq1wtM2sCBznS7OLT9A== X-Google-Smtp-Source: ABdhPJy1zOve/edND+nsLTEZjVIQeBBJZcFwmXKmLZXad3BkcOj2RI766TvgRlywGet8Serg0VElFQ== X-Received: by 2002:aa7:9216:0:b029:2e5:6989:4f1a with SMTP id 22-20020aa792160000b02902e569894f1amr21153138pfo.50.1621955230734; Tue, 25 May 2021 08:07:10 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 05/28] softfloat: Move compare_floats to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:43 -0700 Message-Id: <20210525150706.294968-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::52d; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52d.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Rename to parts$N_compare. Rename all of the intermediate functions to ftype_do_compare. Rename the hard-float functions to ftype_hs_compare. Convert float128 to FloatParts128. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 208 ++++++++++++++------------------------ fpu/softfloat-parts.c.inc | 57 +++++++++++ 2 files changed, 133 insertions(+), 132 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 2dadded0b5..3c2c3ec8f8 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -882,6 +882,14 @@ static int parts128_minmax(FloatParts128 *a, FloatPart= s128 *b, #define parts_minmax(A, B, S, Z, F) \ PARTS_GENERIC_64_128(minmax, A)(A, B, S, Z, F) =20 +static int parts64_compare(FloatParts64 *a, FloatParts64 *b, + float_status *s, bool q); +static int parts128_compare(FloatParts128 *a, FloatParts128 *b, + float_status *s, bool q); + +#define parts_compare(A, B, S, Q) \ + PARTS_GENERIC_64_128(compare, A)(A, B, S, Q) + /* * Helper functions for softfloat-parts.c.inc, per-size operations. */ @@ -3360,92 +3368,42 @@ MINMAX_2(float64) #undef MINMAX_1 #undef MINMAX_2 =20 -/* Floating point compare */ -static FloatRelation compare_floats(FloatParts64 a, FloatParts64 b, bool i= s_quiet, - float_status *s) +/* + * Floating point compare + */ + +static FloatRelation QEMU_FLATTEN +float16_do_compare(float16 a, float16 b, float_status *s, bool is_quiet) { - if (is_nan(a.cls) || is_nan(b.cls)) { - if (!is_quiet || - a.cls =3D=3D float_class_snan || - b.cls =3D=3D float_class_snan) { - float_raise(float_flag_invalid, s); - } - return float_relation_unordered; - } + FloatParts64 pa, pb; =20 - if (a.cls =3D=3D float_class_zero) { - if (b.cls =3D=3D float_class_zero) { - return float_relation_equal; - } - return b.sign ? float_relation_greater : float_relation_less; - } else if (b.cls =3D=3D float_class_zero) { - return a.sign ? float_relation_less : float_relation_greater; - } - - /* The only really important thing about infinity is its sign. If - * both are infinities the sign marks the smallest of the two. - */ - if (a.cls =3D=3D float_class_inf) { - if ((b.cls =3D=3D float_class_inf) && (a.sign =3D=3D b.sign)) { - return float_relation_equal; - } - return a.sign ? float_relation_less : float_relation_greater; - } else if (b.cls =3D=3D float_class_inf) { - return b.sign ? float_relation_greater : float_relation_less; - } - - if (a.sign !=3D b.sign) { - return a.sign ? float_relation_less : float_relation_greater; - } - - if (a.exp =3D=3D b.exp) { - if (a.frac =3D=3D b.frac) { - return float_relation_equal; - } - if (a.sign) { - return a.frac > b.frac ? - float_relation_less : float_relation_greater; - } else { - return a.frac > b.frac ? - float_relation_greater : float_relation_less; - } - } else { - if (a.sign) { - return a.exp > b.exp ? float_relation_less : float_relation_gr= eater; - } else { - return a.exp > b.exp ? float_relation_greater : float_relation= _less; - } - } + float16_unpack_canonical(&pa, a, s); + float16_unpack_canonical(&pb, b, s); + return parts_compare(&pa, &pb, s, is_quiet); } =20 -#define COMPARE(name, attr, sz) \ -static int attr \ -name(float ## sz a, float ## sz b, bool is_quiet, float_status *s) \ -{ \ - FloatParts64 pa, pb; \ - float ## sz ## _unpack_canonical(&pa, a, s); \ - float ## sz ## _unpack_canonical(&pb, b, s); \ - return compare_floats(pa, pb, is_quiet, s); \ -} - -COMPARE(soft_f16_compare, QEMU_FLATTEN, 16) -COMPARE(soft_f32_compare, QEMU_SOFTFLOAT_ATTR, 32) -COMPARE(soft_f64_compare, QEMU_SOFTFLOAT_ATTR, 64) - -#undef COMPARE - FloatRelation float16_compare(float16 a, float16 b, float_status *s) { - return soft_f16_compare(a, b, false, s); + return float16_do_compare(a, b, s, false); } =20 FloatRelation float16_compare_quiet(float16 a, float16 b, float_status *s) { - return soft_f16_compare(a, b, true, s); + return float16_do_compare(a, b, s, true); +} + +static FloatRelation QEMU_SOFTFLOAT_ATTR +float32_do_compare(float32 a, float32 b, float_status *s, bool is_quiet) +{ + FloatParts64 pa, pb; + + float32_unpack_canonical(&pa, a, s); + float32_unpack_canonical(&pb, b, s); + return parts_compare(&pa, &pb, s, is_quiet); } =20 static FloatRelation QEMU_FLATTEN -f32_compare(float32 xa, float32 xb, bool is_quiet, float_status *s) +float32_hs_compare(float32 xa, float32 xb, float_status *s, bool is_quiet) { union_float32 ua, ub; =20 @@ -3466,25 +3424,36 @@ f32_compare(float32 xa, float32 xb, bool is_quiet, = float_status *s) if (likely(isless(ua.h, ub.h))) { return float_relation_less; } - /* The only condition remaining is unordered. + /* + * The only condition remaining is unordered. * Fall through to set flags. */ soft: - return soft_f32_compare(ua.s, ub.s, is_quiet, s); + return float32_do_compare(ua.s, ub.s, s, is_quiet); } =20 FloatRelation float32_compare(float32 a, float32 b, float_status *s) { - return f32_compare(a, b, false, s); + return float32_hs_compare(a, b, s, false); } =20 FloatRelation float32_compare_quiet(float32 a, float32 b, float_status *s) { - return f32_compare(a, b, true, s); + return float32_hs_compare(a, b, s, true); +} + +static FloatRelation QEMU_SOFTFLOAT_ATTR +float64_do_compare(float64 a, float64 b, float_status *s, bool is_quiet) +{ + FloatParts64 pa, pb; + + float64_unpack_canonical(&pa, a, s); + float64_unpack_canonical(&pb, b, s); + return parts_compare(&pa, &pb, s, is_quiet); } =20 static FloatRelation QEMU_FLATTEN -f64_compare(float64 xa, float64 xb, bool is_quiet, float_status *s) +float64_hs_compare(float64 xa, float64 xb, float_status *s, bool is_quiet) { union_float64 ua, ub; =20 @@ -3505,41 +3474,62 @@ f64_compare(float64 xa, float64 xb, bool is_quiet, = float_status *s) if (likely(isless(ua.h, ub.h))) { return float_relation_less; } - /* The only condition remaining is unordered. + /* + * The only condition remaining is unordered. * Fall through to set flags. */ soft: - return soft_f64_compare(ua.s, ub.s, is_quiet, s); + return float64_do_compare(ua.s, ub.s, s, is_quiet); } =20 FloatRelation float64_compare(float64 a, float64 b, float_status *s) { - return f64_compare(a, b, false, s); + return float64_hs_compare(a, b, s, false); } =20 FloatRelation float64_compare_quiet(float64 a, float64 b, float_status *s) { - return f64_compare(a, b, true, s); + return float64_hs_compare(a, b, s, true); } =20 static FloatRelation QEMU_FLATTEN -soft_bf16_compare(bfloat16 a, bfloat16 b, bool is_quiet, float_status *s) +bfloat16_do_compare(bfloat16 a, bfloat16 b, float_status *s, bool is_quiet) { FloatParts64 pa, pb; =20 bfloat16_unpack_canonical(&pa, a, s); bfloat16_unpack_canonical(&pb, b, s); - return compare_floats(pa, pb, is_quiet, s); + return parts_compare(&pa, &pb, s, is_quiet); } =20 FloatRelation bfloat16_compare(bfloat16 a, bfloat16 b, float_status *s) { - return soft_bf16_compare(a, b, false, s); + return bfloat16_do_compare(a, b, s, false); } =20 FloatRelation bfloat16_compare_quiet(bfloat16 a, bfloat16 b, float_status = *s) { - return soft_bf16_compare(a, b, true, s); + return bfloat16_do_compare(a, b, s, true); +} + +static FloatRelation QEMU_FLATTEN +float128_do_compare(float128 a, float128 b, float_status *s, bool is_quiet) +{ + FloatParts128 pa, pb; + + float128_unpack_canonical(&pa, a, s); + float128_unpack_canonical(&pb, b, s); + return parts_compare(&pa, &pb, s, is_quiet); +} + +FloatRelation float128_compare(float128 a, float128 b, float_status *s) +{ + return float128_do_compare(a, b, s, false); +} + +FloatRelation float128_compare_quiet(float128 a, float128 b, float_status = *s) +{ + return float128_do_compare(a, b, s, true); } =20 /* Multiply A by 2 raised to the power N. */ @@ -6612,52 +6602,6 @@ FloatRelation floatx80_compare_quiet(floatx80 a, flo= atx80 b, return floatx80_compare_internal(a, b, 1, status); } =20 -static inline FloatRelation -float128_compare_internal(float128 a, float128 b, bool is_quiet, - float_status *status) -{ - bool aSign, bSign; - - if (( ( extractFloat128Exp( a ) =3D=3D 0x7fff ) && - ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) || - ( ( extractFloat128Exp( b ) =3D=3D 0x7fff ) && - ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) { - if (!is_quiet || - float128_is_signaling_nan(a, status) || - float128_is_signaling_nan(b, status)) { - float_raise(float_flag_invalid, status); - } - return float_relation_unordered; - } - aSign =3D extractFloat128Sign( a ); - bSign =3D extractFloat128Sign( b ); - if ( aSign !=3D bSign ) { - if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) =3D=3D 0 ) { - /* zero case */ - return float_relation_equal; - } else { - return 1 - (2 * aSign); - } - } else { - if (a.low =3D=3D b.low && a.high =3D=3D b.high) { - return float_relation_equal; - } else { - return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low = ) )); - } - } -} - -FloatRelation float128_compare(float128 a, float128 b, float_status *statu= s) -{ - return float128_compare_internal(a, b, 0, status); -} - -FloatRelation float128_compare_quiet(float128 a, float128 b, - float_status *status) -{ - return float128_compare_internal(a, b, 1, status); -} - floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) { bool aSign; diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index d68ab8fee0..6f9ae7f887 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1017,3 +1017,60 @@ static int partsN(minmax)(FloatPartsN *a, FloatParts= N *b, =20 return (cmp < 0) ^ !!(flags & minmax_ismin); } + +/* + * Floating point compare + */ +static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b, + float_status *s, bool is_quiet) +{ + int ab_mask =3D float_cmask(a->cls) | float_cmask(b->cls); + int cmp; + + if (likely(ab_mask =3D=3D float_cmask_normal)) { + if (a->sign !=3D b->sign) { + goto a_sign; + } + if (a->exp !=3D b->exp) { + cmp =3D a->exp < b->exp ? -1 : 1; + } else { + cmp =3D frac_cmp(a, b); + } + if (a->sign) { + cmp =3D -cmp; + } + return cmp; + } + + if (unlikely(ab_mask & float_cmask_anynan)) { + if (!is_quiet || (ab_mask & float_cmask_snan)) { + float_raise(float_flag_invalid, s); + } + return float_relation_unordered; + } + + if (ab_mask & float_cmask_zero) { + if (ab_mask =3D=3D float_cmask_zero) { + return float_relation_equal; + } else if (a->cls =3D=3D float_class_zero) { + goto b_sign; + } else { + goto a_sign; + } + } + + if (ab_mask =3D=3D float_cmask_inf) { + if (a->sign =3D=3D b->sign) { + return float_relation_equal; + } + } else if (b->cls =3D=3D float_class_inf) { + goto b_sign; + } else { + g_assert(a->cls =3D=3D float_class_inf); + } + + a_sign: + return a->sign ? float_relation_less : float_relation_greater; + b_sign: + return b->sign ? float_relation_greater : float_relation_less; +} --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621960066; cv=none; d=zohomail.com; s=zohoarc; b=MxnZ9esuAwBjbSrZb2TYt6FyFaQxY1PH2zIeoFmhqxirIGpQ52byb/65PoiGH0q8F+C/NRyz329DRGakFwpVlQmkKfRXJY8Hx1y7nSe52fWaaKhXmQ7OwWyc/7PRZtAK6+mXR6i00gC1S33dMquJWbRoXIvsRsOFaBAnjuUFrbA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621960066; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=UZW48CzleAWs3EEYVj0CQeurJ7gxS/XtjXLc9QsEbJM=; b=gH9T6Jk7jgR9Ile8+zcktH3Xx8EzwhlJakQk4XmcBXSmbdbEZonhbKNJnW91jCnRrw2MeuUuZSgrOSLbxp3mAZ4WbEZWR8/lOsulFYvUlGvl/+VAQp+rzwzl3HXnNws6wzJEk765D/eP0IFcbvOjKTpaNRxmoRcPCZNyWx7xgno= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621960066731838.6327502972192; Tue, 25 May 2021 09:27:46 -0700 (PDT) Received: from localhost ([::1]:56426 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZuD-0004Ro-Gp for importer@patchew.org; Tue, 25 May 2021 12:27:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60368) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeR-0001eP-4Y for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:23 -0400 Received: from mail-pj1-x1034.google.com ([2607:f8b0:4864:20::1034]:51054) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeH-0006dy-Fh for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:22 -0400 Received: by mail-pj1-x1034.google.com with SMTP id t11so17029864pjm.0 for ; Tue, 25 May 2021 08:07:12 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UZW48CzleAWs3EEYVj0CQeurJ7gxS/XtjXLc9QsEbJM=; b=hHvEcnXEF89YB+M/st1LxzueXdcmbdKouEWdTTBU/yTuI+fNECFsNM8rSmane6HNVy NADDYe7eNC41RY2ZA/Wwnaw4SK5rHPA9/Nm7HGmEPHVeZpD8kPE/edsYBqImOLsRRSgM Jz+DSMDnTZXBqmpulREDABArK3wu4xPqnDPwizv+4uN9Kw82HWYNwdOukozAQTtH09qS ROhmXXk6PURv7th90fyF9K4wcXz5lHsi5EejmCtskY/0ddtsVfU04Oxf4HKHuOReT1iT tHaWctONIRgnijp63J/SGI8RgXFRfs/0JOxeAhFYgDTFbdv+jsu17M0YAUJ+VKWyKkzg kUfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UZW48CzleAWs3EEYVj0CQeurJ7gxS/XtjXLc9QsEbJM=; b=eAbJw2dW4vgjKmcgZWm+jCdgb5aAUlS2idGpKErBLAIu7gWRdH4jvphBYAZ3wnG+of 94u+gf6lS5jH/CDVjQTxCNZ+e917poNPufgeRCKmTsPwq4OzTy1rUvQKZqx/hTzDDPYI 1hMOcdcM2Atuw9V7c17rVaj3TtvrksDW0wjs2miGGeYmGzCOjPzYO20dE71PFyUxNUDg c8dyZiWEA8fWPTNqNDN59X78mWaP6/hnJmda3JYO+poFMlI32zeqKWOw4i8CwC2S2IVG n9Txx2x8/1AlbhOLZ7/wy6L0aPVif5PrL3g5iPCw4dLFmeoWsNWWUqccq2VmeQgun9h5 tsRg== X-Gm-Message-State: AOAM532dDXvv6rkEsXOqieOHMhB9Ph9rTOVzAxAJDYK2YxKtUfMFyQAZ oIGT6FXL8FdZA5XpSBFL4plelVRwcP28DQ== X-Google-Smtp-Source: ABdhPJzCa0rR8ei/LZqI1kgh3a+95Uy/a8VnJUE+gJjBnHD1EUb4jJHT6+Nnz01g5c6rYeq97ajEbw== X-Received: by 2002:a17:903:3106:b029:ee:fa93:9546 with SMTP id w6-20020a1709033106b02900eefa939546mr31070909plc.23.1621955231425; Tue, 25 May 2021 08:07:11 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 06/28] softfloat: Move scalbn_decomposed to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:44 -0700 Message-Id: <20210525150706.294968-7-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1034; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1034.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Rename to parts$N_scalbn. Reimplement float128_scalbn with FloatParts128. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 103 +++++++++++++------------------------- fpu/softfloat-parts.c.inc | 21 ++++++++ 2 files changed, 55 insertions(+), 69 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3c2c3ec8f8..45194f5d14 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -890,6 +890,12 @@ static int parts128_compare(FloatParts128 *a, FloatPar= ts128 *b, #define parts_compare(A, B, S, Q) \ PARTS_GENERIC_64_128(compare, A)(A, B, S, Q) =20 +static void parts64_scalbn(FloatParts64 *a, int n, float_status *s); +static void parts128_scalbn(FloatParts128 *a, int n, float_status *s); + +#define parts_scalbn(A, N, S) \ + PARTS_GENERIC_64_128(scalbn, A)(A, N, S) + /* * Helper functions for softfloat-parts.c.inc, per-size operations. */ @@ -3532,58 +3538,53 @@ FloatRelation float128_compare_quiet(float128 a, fl= oat128 b, float_status *s) return float128_do_compare(a, b, s, true); } =20 -/* Multiply A by 2 raised to the power N. */ -static FloatParts64 scalbn_decomposed(FloatParts64 a, int n, float_status = *s) -{ - if (unlikely(is_nan(a.cls))) { - parts_return_nan(&a, s); - } - if (a.cls =3D=3D float_class_normal) { - /* The largest float type (even though not supported by FloatParts= 64) - * is float128, which has a 15 bit exponent. Bounding N to 16 bits - * still allows rounding to infinity, without allowing overflow - * within the int32_t that backs FloatParts64.exp. - */ - n =3D MIN(MAX(n, -0x10000), 0x10000); - a.exp +=3D n; - } - return a; -} +/* + * Scale by 2**N + */ =20 float16 float16_scalbn(float16 a, int n, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; =20 - float16_unpack_canonical(&pa, a, status); - pr =3D scalbn_decomposed(pa, n, status); - return float16_round_pack_canonical(&pr, status); + float16_unpack_canonical(&p, a, status); + parts_scalbn(&p, n, status); + return float16_round_pack_canonical(&p, status); } =20 float32 float32_scalbn(float32 a, int n, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; =20 - float32_unpack_canonical(&pa, a, status); - pr =3D scalbn_decomposed(pa, n, status); - return float32_round_pack_canonical(&pr, status); + float32_unpack_canonical(&p, a, status); + parts_scalbn(&p, n, status); + return float32_round_pack_canonical(&p, status); } =20 float64 float64_scalbn(float64 a, int n, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; =20 - float64_unpack_canonical(&pa, a, status); - pr =3D scalbn_decomposed(pa, n, status); - return float64_round_pack_canonical(&pr, status); + float64_unpack_canonical(&p, a, status); + parts_scalbn(&p, n, status); + return float64_round_pack_canonical(&p, status); } =20 bfloat16 bfloat16_scalbn(bfloat16 a, int n, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; =20 - bfloat16_unpack_canonical(&pa, a, status); - pr =3D scalbn_decomposed(pa, n, status); - return bfloat16_round_pack_canonical(&pr, status); + bfloat16_unpack_canonical(&p, a, status); + parts_scalbn(&p, n, status); + return bfloat16_round_pack_canonical(&p, status); +} + +float128 float128_scalbn(float128 a, int n, float_status *status) +{ + FloatParts128 p; + + float128_unpack_canonical(&p, a, status); + parts_scalbn(&p, n, status); + return float128_round_pack_canonical(&p, status); } =20 /* @@ -6641,42 +6642,6 @@ floatx80 floatx80_scalbn(floatx80 a, int n, float_st= atus *status) aSign, aExp, aSig, 0, status); } =20 -float128 float128_scalbn(float128 a, int n, float_status *status) -{ - bool aSign; - int32_t aExp; - uint64_t aSig0, aSig1; - - aSig1 =3D extractFloat128Frac1( a ); - aSig0 =3D extractFloat128Frac0( a ); - aExp =3D extractFloat128Exp( a ); - aSign =3D extractFloat128Sign( a ); - if ( aExp =3D=3D 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return propagateFloat128NaN(a, a, status); - } - return a; - } - if (aExp !=3D 0) { - aSig0 |=3D UINT64_C(0x0001000000000000); - } else if (aSig0 =3D=3D 0 && aSig1 =3D=3D 0) { - return a; - } else { - aExp++; - } - - if (n > 0x10000) { - n =3D 0x10000; - } else if (n < -0x10000) { - n =3D -0x10000; - } - - aExp +=3D n - 1; - return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1 - , status); - -} - static void __attribute__((constructor)) softfloat_init(void) { union_float64 ua, ub, uc, ur; diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index 6f9ae7f887..6b553c70a5 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1074,3 +1074,24 @@ static FloatRelation partsN(compare)(FloatPartsN *a,= FloatPartsN *b, b_sign: return b->sign ? float_relation_greater : float_relation_less; } + +/* + * Multiply A by 2 raised to the power N. + */ +static void partsN(scalbn)(FloatPartsN *a, int n, float_status *s) +{ + switch (a->cls) { + case float_class_snan: + case float_class_qnan: + parts_return_nan(a, s); + break; + case float_class_zero: + case float_class_inf: + break; + case float_class_normal: + a->exp +=3D MIN(MAX(n, -0x10000), 0x10000); + break; + default: + g_assert_not_reached(); + } +} --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621958963; cv=none; d=zohomail.com; s=zohoarc; b=ic1OjlI/xwmVBOQtJYk71Sk/hqJeDYDlW3rV4DIq16vE1zCki8Cc2DnLPkiqQHhH8aXR1ULST/WQTlN/BToNbpo4wsAZDrxphGFuzK2jWaoE9u6jw51JYNylmx4oTn3trjRaAt8/2C/Bp2GesSQj1PPtrLO+/7JJQ0JDLuosibg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621958963; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=fdULbYDtSQ0qO12yTrczqlpVqQdGOokmp8V6XGHT0DA=; b=W+3AbLRkglKlmNHf+JdLDC6JbXSs4Lwp90izGfWH4DzaqaVQWeWOzIT89WTVNm4HKfDXlROrMQdJhaLOGq3DfhZCZtrWDSuXgGJ+OEDJF8MHTj+Z+SeRf38L++ApQFqEVOIkDkPKVOmYyhFl1o2kQKhMUAKxWYjjDR4NM+hlDMg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621958963245960.5007462204492; Tue, 25 May 2021 09:09:23 -0700 (PDT) Received: from localhost ([::1]:56900 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZcP-0007Qk-Uk for importer@patchew.org; Tue, 25 May 2021 12:09:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60346) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0001b8-B5 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:22 -0400 Received: from mail-pf1-x432.google.com ([2607:f8b0:4864:20::432]:36702) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeH-0006e5-Fw for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:21 -0400 Received: by mail-pf1-x432.google.com with SMTP id c12so12247284pfl.3 for ; Tue, 25 May 2021 08:07:13 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fdULbYDtSQ0qO12yTrczqlpVqQdGOokmp8V6XGHT0DA=; b=phzhwqxwRMH2S7DNfV8VkX/iUNxJAmI6Xzdd6VoRKQBcIHbNw1ZTdpXAIHCddS1RzI 6dzd4PAIT9BPmPSjOti22EGqM/8zgfos6fzbcVXiEK+MR9o7C1unlL/srgUReq7Qt73K qQejz7st+e6FkK7eUpZm2AoZ2jnJZ917ADNR69lQHEyFRRNegj5637KsBaPl1I2l+mdo HXDIS887GMFJ93scYX3Gj7/rLXiXTZJGtXImq3ts8Ar7TXgA8W5xOEUrMBXyTiwKkWat ElfQ145GPruH3FAHno/9G1O/boBCU2eZEseubRPVhmvZKNY+TadceWcEps/pzlb5niRM i1Ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fdULbYDtSQ0qO12yTrczqlpVqQdGOokmp8V6XGHT0DA=; b=k4E4KeZpfQx4NJRJHAy52o3K8KvI5ogu4eZERUYzLBZ9IMvrmwOfccqMJWserPW6c5 0LkLmYY4C/WeWgZv19umXSIgHnnKs6Xwlyo6V9wKCMe1JzWtfn24fJVYmsjSBtDcd2K0 y2okYBNOr/DnvZ7q4prUiqNefsF5UoR9pEZJj8zmP6O3sZFIR3jsCIWvOQt0pxVQ21wI 9HqQ9mTVxVG7Ay4hP9kJRu9ZCEN+HGQXcwjW/qiRUkc8LRgGgWKHsVyoQAejqxwFYZgW kUkC/bjuml8BX7FJocFwTjrY4geC7hqnxVJgFW7PzvWkv7KYNV67EwjQsj3kZskiNAka YJiw== X-Gm-Message-State: AOAM532ecwtjIQAqNqoc+nF8czcMoQ54YfGUaytmWetBf0rlswjdlN0a rmh9HAzeqB1TbI1J/HYyvbYgyBSjiyI/Zg== X-Google-Smtp-Source: ABdhPJxKf2FhrfWA4gxUJAdyUNUIS2Z8Sprx3wwOsmLnstZkjVCB85oNVE5GX6IYXERMzoH5GFtr6A== X-Received: by 2002:aa7:921a:0:b029:2cf:b55b:9d52 with SMTP id 26-20020aa7921a0000b02902cfb55b9d52mr29673144pfo.35.1621955232022; Tue, 25 May 2021 08:07:12 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 07/28] softfloat: Move sqrt_float to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:45 -0700 Message-Id: <20210525150706.294968-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::432; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x432.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Rename to parts$N_sqrt. Reimplement float128_sqrt with FloatParts128. Reimplement with the inverse sqrt newton-raphson algorithm from musl. This is significantly faster than even the berkeley sqrt n-r algorithm, because it does not use division instructions, only multiplication. Ordinarily, changing algorithms at the same time as migrating code is a bad idea, but this is the only way I found that didn't break one of the routines at the same time. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e Tested-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 207 ++++++++++---------------------------- fpu/softfloat-parts.c.inc | 206 +++++++++++++++++++++++++++++++++++++ 2 files changed, 261 insertions(+), 152 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 45194f5d14..50af8e4e09 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -820,6 +820,12 @@ static FloatParts128 *parts128_div(FloatParts128 *a, F= loatParts128 *b, #define parts_div(A, B, S) \ PARTS_GENERIC_64_128(div, A)(A, B, S) =20 +static void parts64_sqrt(FloatParts64 *a, float_status *s, const FloatFmt = *f); +static void parts128_sqrt(FloatParts128 *a, float_status *s, const FloatFm= t *f); + +#define parts_sqrt(A, S, F) \ + PARTS_GENERIC_64_128(sqrt, A)(A, S, F) + static bool parts64_round_to_int_normal(FloatParts64 *a, FloatRoundMode rm, int scale, int frac_size); static bool parts128_round_to_int_normal(FloatParts128 *a, FloatRoundMode = r, @@ -1386,6 +1392,30 @@ static void frac128_widen(FloatParts256 *r, FloatPar= ts128 *a) =20 #define frac_widen(A, B) FRAC_GENERIC_64_128(widen, B)(A, B) =20 +/* + * Reciprocal sqrt table. 1 bit of exponent, 6-bits of mantessa. + * From https://git.musl-libc.org/cgit/musl/tree/src/math/sqrt_data.c + * and thus MIT licenced. + */ +static const uint16_t rsqrt_tab[128] =3D { + 0xb451, 0xb2f0, 0xb196, 0xb044, 0xaef9, 0xadb6, 0xac79, 0xab43, + 0xaa14, 0xa8eb, 0xa7c8, 0xa6aa, 0xa592, 0xa480, 0xa373, 0xa26b, + 0xa168, 0xa06a, 0x9f70, 0x9e7b, 0x9d8a, 0x9c9d, 0x9bb5, 0x9ad1, + 0x99f0, 0x9913, 0x983a, 0x9765, 0x9693, 0x95c4, 0x94f8, 0x9430, + 0x936b, 0x92a9, 0x91ea, 0x912e, 0x9075, 0x8fbe, 0x8f0a, 0x8e59, + 0x8daa, 0x8cfe, 0x8c54, 0x8bac, 0x8b07, 0x8a64, 0x89c4, 0x8925, + 0x8889, 0x87ee, 0x8756, 0x86c0, 0x862b, 0x8599, 0x8508, 0x8479, + 0x83ec, 0x8361, 0x82d8, 0x8250, 0x81c9, 0x8145, 0x80c2, 0x8040, + 0xff02, 0xfd0e, 0xfb25, 0xf947, 0xf773, 0xf5aa, 0xf3ea, 0xf234, + 0xf087, 0xeee3, 0xed47, 0xebb3, 0xea27, 0xe8a3, 0xe727, 0xe5b2, + 0xe443, 0xe2dc, 0xe17a, 0xe020, 0xdecb, 0xdd7d, 0xdc34, 0xdaf1, + 0xd9b3, 0xd87b, 0xd748, 0xd61a, 0xd4f1, 0xd3cd, 0xd2ad, 0xd192, + 0xd07b, 0xcf69, 0xce5b, 0xcd51, 0xcc4a, 0xcb48, 0xca4a, 0xc94f, + 0xc858, 0xc764, 0xc674, 0xc587, 0xc49d, 0xc3b7, 0xc2d4, 0xc1f4, + 0xc116, 0xc03c, 0xbf65, 0xbe90, 0xbdbe, 0xbcef, 0xbc23, 0xbb59, + 0xba91, 0xb9cc, 0xb90a, 0xb84a, 0xb78c, 0xb6d0, 0xb617, 0xb560, +}; + #define partsN(NAME) glue(glue(glue(parts,N),_),NAME) #define FloatPartsN glue(FloatParts,N) #define FloatPartsW glue(FloatParts,W) @@ -3589,103 +3619,35 @@ float128 float128_scalbn(float128 a, int n, float_= status *status) =20 /* * Square Root - * - * The old softfloat code did an approximation step before zeroing in - * on the final result. However for simpleness we just compute the - * square root by iterating down from the implicit bit to enough extra - * bits to ensure we get a correctly rounded result. - * - * This does mean however the calculation is slower than before, - * especially for 64 bit floats. */ =20 -static FloatParts64 sqrt_float(FloatParts64 a, float_status *s, const Floa= tFmt *p) -{ - uint64_t a_frac, r_frac, s_frac; - int bit, last_bit; - - if (is_nan(a.cls)) { - parts_return_nan(&a, s); - return a; - } - if (a.cls =3D=3D float_class_zero) { - return a; /* sqrt(+-0) =3D +-0 */ - } - if (a.sign) { - float_raise(float_flag_invalid, s); - parts_default_nan(&a, s); - return a; - } - if (a.cls =3D=3D float_class_inf) { - return a; /* sqrt(+inf) =3D +inf */ - } - - assert(a.cls =3D=3D float_class_normal); - - /* We need two overflow bits at the top. Adding room for that is a - * right shift. If the exponent is odd, we can discard the low bit - * by multiplying the fraction by 2; that's a left shift. Combine - * those and we shift right by 1 if the exponent is odd, otherwise 2. - */ - a_frac =3D a.frac >> (2 - (a.exp & 1)); - a.exp >>=3D 1; - - /* Bit-by-bit computation of sqrt. */ - r_frac =3D 0; - s_frac =3D 0; - - /* Iterate from implicit bit down to the 3 extra bits to compute a - * properly rounded result. Remember we've inserted two more bits - * at the top, so these positions are two less. - */ - bit =3D DECOMPOSED_BINARY_POINT - 2; - last_bit =3D MAX(p->frac_shift - 4, 0); - do { - uint64_t q =3D 1ULL << bit; - uint64_t t_frac =3D s_frac + q; - if (t_frac <=3D a_frac) { - s_frac =3D t_frac + q; - a_frac -=3D t_frac; - r_frac +=3D q; - } - a_frac <<=3D 1; - } while (--bit >=3D last_bit); - - /* Undo the right shift done above. If there is any remaining - * fraction, the result is inexact. Set the sticky bit. - */ - a.frac =3D (r_frac << 2) + (a_frac !=3D 0); - - return a; -} - float16 QEMU_FLATTEN float16_sqrt(float16 a, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; =20 - float16_unpack_canonical(&pa, a, status); - pr =3D sqrt_float(pa, status, &float16_params); - return float16_round_pack_canonical(&pr, status); + float16_unpack_canonical(&p, a, status); + parts_sqrt(&p, status, &float16_params); + return float16_round_pack_canonical(&p, status); } =20 static float32 QEMU_SOFTFLOAT_ATTR soft_f32_sqrt(float32 a, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; =20 - float32_unpack_canonical(&pa, a, status); - pr =3D sqrt_float(pa, status, &float32_params); - return float32_round_pack_canonical(&pr, status); + float32_unpack_canonical(&p, a, status); + parts_sqrt(&p, status, &float32_params); + return float32_round_pack_canonical(&p, status); } =20 static float64 QEMU_SOFTFLOAT_ATTR soft_f64_sqrt(float64 a, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; =20 - float64_unpack_canonical(&pa, a, status); - pr =3D sqrt_float(pa, status, &float64_params); - return float64_round_pack_canonical(&pr, status); + float64_unpack_canonical(&p, a, status); + parts_sqrt(&p, status, &float64_params); + return float64_round_pack_canonical(&p, status); } =20 float32 QEMU_FLATTEN float32_sqrt(float32 xa, float_status *s) @@ -3744,11 +3706,20 @@ float64 QEMU_FLATTEN float64_sqrt(float64 xa, float= _status *s) =20 bfloat16 QEMU_FLATTEN bfloat16_sqrt(bfloat16 a, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; =20 - bfloat16_unpack_canonical(&pa, a, status); - pr =3D sqrt_float(pa, status, &bfloat16_params); - return bfloat16_round_pack_canonical(&pr, status); + bfloat16_unpack_canonical(&p, a, status); + parts_sqrt(&p, status, &bfloat16_params); + return bfloat16_round_pack_canonical(&p, status); +} + +float128 QEMU_FLATTEN float128_sqrt(float128 a, float_status *status) +{ + FloatParts128 p; + + float128_unpack_canonical(&p, a, status); + parts_sqrt(&p, status, &float128_params); + return float128_round_pack_canonical(&p, status); } =20 /*------------------------------------------------------------------------= ---- @@ -6476,74 +6447,6 @@ float128 float128_rem(float128 a, float128 b, float_= status *status) status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the square root of the quadruple-precision floating-point value = `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float128 float128_sqrt(float128 a, float_status *status) -{ - bool aSign; - int32_t aExp, zExp; - uint64_t aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; - uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3; - - aSig1 =3D extractFloat128Frac1( a ); - aSig0 =3D extractFloat128Frac0( a ); - aExp =3D extractFloat128Exp( a ); - aSign =3D extractFloat128Sign( a ); - if ( aExp =3D=3D 0x7FFF ) { - if (aSig0 | aSig1) { - return propagateFloat128NaN(a, a, status); - } - if ( ! aSign ) return a; - goto invalid; - } - if ( aSign ) { - if ( ( aExp | aSig0 | aSig1 ) =3D=3D 0 ) return a; - invalid: - float_raise(float_flag_invalid, status); - return float128_default_nan(status); - } - if ( aExp =3D=3D 0 ) { - if ( ( aSig0 | aSig1 ) =3D=3D 0 ) return packFloat128( 0, 0, 0, 0 = ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - zExp =3D ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE; - aSig0 |=3D UINT64_C(0x0001000000000000); - zSig0 =3D estimateSqrt32( aExp, aSig0>>17 ); - shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 ); - zSig0 =3D estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 = ); - doubleZSig0 =3D zSig0<<1; - mul64To128( zSig0, zSig0, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (int64_t) rem0 < 0 ) { - --zSig0; - doubleZSig0 -=3D 2; - add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); - } - zSig1 =3D estimateDiv128To64( rem1, 0, doubleZSig0 ); - if ( ( zSig1 & 0x1FFF ) <=3D 5 ) { - if ( zSig1 =3D=3D 0 ) zSig1 =3D 1; - mul64To128( doubleZSig0, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - mul64To128( zSig1, zSig1, &term2, &term3 ); - sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); - while ( (int64_t) rem1 < 0 ) { - --zSig1; - shortShift128Left( 0, zSig1, 1, &term2, &term3 ); - term3 |=3D 1; - term2 |=3D doubleZSig0; - add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3= ); - } - zSig1 |=3D ( ( rem1 | rem2 | rem3 ) !=3D 0 ); - } - shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2= ); - return roundAndPackFloat128(0, zExp, zSig0, zSig1, zSig2, status); - -} - static inline FloatRelation floatx80_compare_internal(floatx80 a, floatx80 b, bool is_quiet, float_status *status) diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index 6b553c70a5..840ccfdf20 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -595,6 +595,212 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, Float= PartsN *b, return a; } =20 +/* + * Square Root + * + * The base algorithm is lifted from + * https://git.musl-libc.org/cgit/musl/tree/src/math/sqrtf.c + * https://git.musl-libc.org/cgit/musl/tree/src/math/sqrt.c + * https://git.musl-libc.org/cgit/musl/tree/src/math/sqrtl.c + * and is thus MIT licenced. + */ +static void partsN(sqrt)(FloatPartsN *a, float_status *status, + const FloatFmt *fmt) +{ + const uint32_t three32 =3D 3u << 30; + const uint64_t three64 =3D 3ull << 62; + uint32_t d32, m32, r32, s32, u32; /* 32-bit computation */ + uint64_t d64, m64, r64, s64, u64; /* 64-bit computation */ + uint64_t dh, dl, rh, rl, sh, sl, uh, ul; /* 128-bit computation */ + uint64_t d0h, d0l, d1h, d1l, d2h, d2l; + uint64_t discard; + bool exp_odd; + size_t index; + + if (unlikely(a->cls !=3D float_class_normal)) { + switch (a->cls) { + case float_class_snan: + case float_class_qnan: + parts_return_nan(a, status); + return; + case float_class_zero: + return; + case float_class_inf: + if (unlikely(a->sign)) { + goto d_nan; + } + return; + default: + g_assert_not_reached(); + } + } + + if (unlikely(a->sign)) { + goto d_nan; + } + + /* + * Argument reduction. + * x =3D 4^e frac; with integer e, and frac in [1, 4) + * m =3D frac fixed point at bit 62, since we're in base 4. + * If base-2 exponent is odd, exchange that for multiply by 2, + * which results in no shift. + */ + exp_odd =3D a->exp & 1; + index =3D extract64(a->frac_hi, 57, 6) | (!exp_odd << 6); + if (!exp_odd) { + frac_shr(a, 1); + } + + /* + * Approximate r ~=3D 1/sqrt(m) and s ~=3D sqrt(m) when m in [1, 4). + * + * Initial estimate: + * 7-bit lookup table (1-bit exponent and 6-bit significand). + * + * The relative error (e =3D r0*sqrt(m)-1) of a linear estimate + * (r0 =3D a*m + b) is |e| < 0.085955 ~ 0x1.6p-4 at best; + * a table lookup is faster and needs one less iteration. + * The 7-bit table gives |e| < 0x1.fdp-9. + * + * A Newton-Raphson iteration for r is + * s =3D m*r + * d =3D s*r + * u =3D 3 - d + * r =3D r*u/2 + * + * Fixed point representations: + * m, s, d, u, three are all 2.30; r is 0.32 + */ + m64 =3D a->frac_hi; + m32 =3D m64 >> 32; + + r32 =3D rsqrt_tab[index] << 16; + /* |r*sqrt(m) - 1| < 0x1.FDp-9 */ + + s32 =3D ((uint64_t)m32 * r32) >> 32; + d32 =3D ((uint64_t)s32 * r32) >> 32; + u32 =3D three32 - d32; + + if (N =3D=3D 64) { + /* float64 or smaller */ + + r32 =3D ((uint64_t)r32 * u32) >> 31; + /* |r*sqrt(m) - 1| < 0x1.7Bp-16 */ + + s32 =3D ((uint64_t)m32 * r32) >> 32; + d32 =3D ((uint64_t)s32 * r32) >> 32; + u32 =3D three32 - d32; + + if (fmt->frac_size <=3D 23) { + /* float32 or smaller */ + + s32 =3D ((uint64_t)s32 * u32) >> 32; /* 3.29 */ + s32 =3D (s32 - 1) >> 6; /* 9.23 */ + /* s < sqrt(m) < s + 0x1.08p-23 */ + + /* compute nearest rounded result to 2.23 bits */ + uint32_t d0 =3D (m32 << 16) - s32 * s32; + uint32_t d1 =3D s32 - d0; + uint32_t d2 =3D d1 + s32 + 1; + s32 +=3D d1 >> 31; + a->frac_hi =3D (uint64_t)s32 << (64 - 25); + + /* increment or decrement for inexact */ + if (d2 !=3D 0) { + a->frac_hi +=3D ((int32_t)(d1 ^ d2) < 0 ? -1 : 1); + } + goto done; + } + + /* float64 */ + + r64 =3D (uint64_t)r32 * u32 * 2; + /* |r*sqrt(m) - 1| < 0x1.37-p29; convert to 64-bit arithmetic */ + mul64To128(m64, r64, &s64, &discard); + mul64To128(s64, r64, &d64, &discard); + u64 =3D three64 - d64; + + mul64To128(s64, u64, &s64, &discard); /* 3.61 */ + s64 =3D (s64 - 2) >> 9; /* 12.52 */ + + /* Compute nearest rounded result */ + uint64_t d0 =3D (m64 << 42) - s64 * s64; + uint64_t d1 =3D s64 - d0; + uint64_t d2 =3D d1 + s64 + 1; + s64 +=3D d1 >> 63; + a->frac_hi =3D s64 << (64 - 54); + + /* increment or decrement for inexact */ + if (d2 !=3D 0) { + a->frac_hi +=3D ((int64_t)(d1 ^ d2) < 0 ? -1 : 1); + } + goto done; + } + + r64 =3D (uint64_t)r32 * u32 * 2; + /* |r*sqrt(m) - 1| < 0x1.7Bp-16; convert to 64-bit arithmetic */ + + mul64To128(m64, r64, &s64, &discard); + mul64To128(s64, r64, &d64, &discard); + u64 =3D three64 - d64; + mul64To128(u64, r64, &r64, &discard); + r64 <<=3D 1; + /* |r*sqrt(m) - 1| < 0x1.a5p-31 */ + + mul64To128(m64, r64, &s64, &discard); + mul64To128(s64, r64, &d64, &discard); + u64 =3D three64 - d64; + mul64To128(u64, r64, &rh, &rl); + add128(rh, rl, rh, rl, &rh, &rl); + /* |r*sqrt(m) - 1| < 0x1.c001p-59; change to 128-bit arithmetic */ + + mul128To256(a->frac_hi, a->frac_lo, rh, rl, &sh, &sl, &discard, &disca= rd); + mul128To256(sh, sl, rh, rl, &dh, &dl, &discard, &discard); + sub128(three64, 0, dh, dl, &uh, &ul); + mul128To256(uh, ul, sh, sl, &sh, &sl, &discard, &discard); /* 3.125 */ + /* -0x1p-116 < s - sqrt(m) < 0x3.8001p-125 */ + + sub128(sh, sl, 0, 4, &sh, &sl); + shift128Right(sh, sl, 13, &sh, &sl); /* 16.112 */ + /* s < sqrt(m) < s + 1ulp */ + + /* Compute nearest rounded result */ + mul64To128(sl, sl, &d0h, &d0l); + d0h +=3D 2 * sh * sl; + sub128(a->frac_lo << 34, 0, d0h, d0l, &d0h, &d0l); + sub128(sh, sl, d0h, d0l, &d1h, &d1l); + add128(sh, sl, 0, 1, &d2h, &d2l); + add128(d2h, d2l, d1h, d1l, &d2h, &d2l); + add128(sh, sl, 0, d1h >> 63, &sh, &sl); + shift128Left(sh, sl, 128 - 114, &sh, &sl); + + /* increment or decrement for inexact */ + if (d2h | d2l) { + if ((int64_t)(d1h ^ d2h) < 0) { + sub128(sh, sl, 0, 1, &sh, &sl); + } else { + add128(sh, sl, 0, 1, &sh, &sl); + } + } + a->frac_lo =3D sl; + a->frac_hi =3D sh; + + done: + /* Convert back from base 4 to base 2. */ + a->exp >>=3D 1; + if (!(a->frac_hi & DECOMPOSED_IMPLICIT_BIT)) { + frac_add(a, a, a); + } else { + a->exp +=3D 1; + } + return; + + d_nan: + float_raise(float_flag_invalid, status); + parts_default_nan(a, status); +} + /* * Rounds the floating-point value `a' to an integer, and returns the * result as a floating-point value. The operation is performed --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621960136; cv=none; d=zohomail.com; s=zohoarc; b=W+CS4+EgvRnrRj0ELOQYKQZ03rKO8nYI96IkX++DzMtsaopf82HEx/PuAPsKlsIgm3KejWvSSofTIcfFo5spoubdinXqOMmob/ujQuFi8oS3pz2AuNJhFMjMyjCu7aVYy3UWvIC7JPgPxuxoSPl8vblZ50Qbzt0fKQ9XOMR8Jcc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621960136; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=zLpvJW2BRkZR5YJ9c51EUMDgKNW3YnVi2U2Lfv7yp2o=; b=CwYOkCl19x91EGhbRnzXq+JobJm2U4GhTbLFheU4sSmz4FshPpk93QXXQEoVcZbRtrU5joCA50goHJRv3vlFsohZjjiHYaE0eCGu9xsb0327uzcUBhyLOg2Y7r0+ZLvEl2oYQE6Ew9yYAHmwE963VG5kfMozyPCOH3WsPwlYCIQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621960136120200.1475158071878; Tue, 25 May 2021 09:28:56 -0700 (PDT) Received: from localhost ([::1]:59024 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZvK-0006Gc-0D for importer@patchew.org; Tue, 25 May 2021 12:28:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60420) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeT-0001mG-7j for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:25 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]:51045) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeI-0006ei-9H for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:24 -0400 Received: by mail-pj1-x102a.google.com with SMTP id t11so17029923pjm.0 for ; Tue, 25 May 2021 08:07:13 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zLpvJW2BRkZR5YJ9c51EUMDgKNW3YnVi2U2Lfv7yp2o=; b=hQajEDCYCjOC6Ay9h42E0EQZ6Y9uX031Qfk6Ih+VdYGd+CsCyVjsftuJ8qIYEtVZbS gSnSt8uH4Ul5mNN4x6ns1iLVknbY11erwgestkj1ESwJBOegJuNusB7+bm12Y975TbS6 JDPorFjBHopQSdXRbUFp6zH4q36ItyRAQqGM/+aOUgEDhxVLM197sw24mL0syKvPFkWO mSrjySfkNyQiqLaHLZotYdxgtbiJFwhkeVINBjCwsHP+CqtU1XWWUFJA2B84Rsc1U57W 2dCkAMbtWQfWfcOl5HLk5TprcNuU1UOY+/1zb0VoTHITnFdIkxWnhNBbz7YO6kG5LTCa cnsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zLpvJW2BRkZR5YJ9c51EUMDgKNW3YnVi2U2Lfv7yp2o=; b=d/c3qtrAwQ3duJyepo5gePh8Xo5yFp/XG9YjTZchG/eoamuJazKm2BY/9jSH+SUc/O J65LTk6CbsqxG95IiFPR90w9/df9gIqORvaMa6OaITXU5n+du2pjTacxyWhY+Zu33a2H zjs4kEk8EWjXbQ0pXIlxUGc4Rt0iBI9LdO2jL6qw6gAh2YDIRAv4LLUEN61oog3FFDk3 fuPwdfoIs+EgxbSJaNn8ijDhi3VxwZRjv1yDkYEjncwSraSfS4dEPDV1BojhTtQeu8zF QkSRhY3LA6AU/y1r52TSGN72xJ0t8HYGFncDPqxR2PE+o8VTzWs6uCVrrpJ/ugZ3UIrL puoQ== X-Gm-Message-State: AOAM532rk4TogULJ/aUTHJuNeRAYhQGxyDphrLoS4tDcVYDGXciD6neB 34cPhJR+6Jz0H+oMYc1NaW0ykYTCSBpr1Q== X-Google-Smtp-Source: ABdhPJwgSDOnqkwbn0FAwiyuQwHDMhLrSnqH0NRD3TWw9GcLpeLXHXRBxlJx8BeDLWrFp5mmZC9hbQ== X-Received: by 2002:a17:90a:ba07:: with SMTP id s7mr31054163pjr.129.1621955232557; Tue, 25 May 2021 08:07:12 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 08/28] softfloat: Split out parts_uncanon_normal Date: Tue, 25 May 2021 08:06:46 -0700 Message-Id: <20210525150706.294968-9-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" We will need to treat the non-normal cases of floatx80 specially, so split out the normal case that we can reuse. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 8 ++++++ fpu/softfloat-parts.c.inc | 56 ++++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 50af8e4e09..2f2bea84da 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -764,6 +764,14 @@ static void parts128_canonicalize(FloatParts128 *p, fl= oat_status *status, #define parts_canonicalize(A, S, F) \ PARTS_GENERIC_64_128(canonicalize, A)(A, S, F) =20 +static void parts64_uncanon_normal(FloatParts64 *p, float_status *status, + const FloatFmt *fmt); +static void parts128_uncanon_normal(FloatParts128 *p, float_status *status, + const FloatFmt *fmt); + +#define parts_uncanon_normal(A, S, F) \ + PARTS_GENERIC_64_128(uncanon_normal, A)(A, S, F) + static void parts64_uncanon(FloatParts64 *p, float_status *status, const FloatFmt *fmt); static void parts128_uncanon(FloatParts128 *p, float_status *status, diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index 840ccfdf20..d72fe3ab08 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -140,8 +140,8 @@ static void partsN(canonicalize)(FloatPartsN *p, float_= status *status, * fraction; these bits will be removed. The exponent will be biased * by EXP_BIAS and must be bounded by [EXP_MAX-1, 0]. */ -static void partsN(uncanon)(FloatPartsN *p, float_status *s, - const FloatFmt *fmt) +static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s, + const FloatFmt *fmt) { const int exp_max =3D fmt->exp_max; const int frac_shift =3D fmt->frac_shift; @@ -153,29 +153,6 @@ static void partsN(uncanon)(FloatPartsN *p, float_stat= us *s, bool overflow_norm; int exp, flags =3D 0; =20 - if (unlikely(p->cls !=3D float_class_normal)) { - switch (p->cls) { - case float_class_zero: - p->exp =3D 0; - frac_clear(p); - return; - case float_class_inf: - g_assert(!fmt->arm_althp); - p->exp =3D fmt->exp_max; - frac_clear(p); - return; - case float_class_qnan: - case float_class_snan: - g_assert(!fmt->arm_althp); - p->exp =3D fmt->exp_max; - frac_shr(p, fmt->frac_shift); - return; - default: - break; - } - g_assert_not_reached(); - } - switch (s->float_rounding_mode) { case float_round_nearest_even: overflow_norm =3D false; @@ -282,6 +259,35 @@ static void partsN(uncanon)(FloatPartsN *p, float_stat= us *s, float_raise(flags, s); } =20 +static void partsN(uncanon)(FloatPartsN *p, float_status *s, + const FloatFmt *fmt) +{ + if (likely(p->cls =3D=3D float_class_normal)) { + parts_uncanon_normal(p, s, fmt); + } else { + switch (p->cls) { + case float_class_zero: + p->exp =3D 0; + frac_clear(p); + return; + case float_class_inf: + g_assert(!fmt->arm_althp); + p->exp =3D fmt->exp_max; + frac_clear(p); + return; + case float_class_qnan: + case float_class_snan: + g_assert(!fmt->arm_althp); + p->exp =3D fmt->exp_max; + frac_shr(p, fmt->frac_shift); + return; + default: + break; + } + g_assert_not_reached(); + } +} + /* * Returns the result of adding or subtracting the values of the * floating-point values `a' and `b'. The operation is performed --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959110; cv=none; d=zohomail.com; s=zohoarc; b=Dq8TkAQ8nwrjFR7pDwV9IeyVVNF3QAlAhNhj0xEXiQRc4ytLNAoO+QKA4/Bk9UwbdEZD4Zr5Myts8k67BIe6dK8R2hHHVltrYFRc1bj44pE3VvfY/3DPFjCRD8NO6f3LWdSneN3D3Qk0eIgBACB6dxRpF9byOeLpjn12k8nv7aQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959110; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=o+y2XL8VpmUirN1zSziSG8ebnfy7nnAzZqTrnTQJTMM=; b=Tqj7VRrPd6pgjmSznD6AanPMtMWip8/qkYOydcl09TkiSJq111GSSEEfAjKjB2qVEafx8B0RpgI/JyoYM72KJsHYSUpn8zpCmmQBfRUBCtLBIguPjlv2MaDvVLXwM007yg/kIGssYU7lcVmsfs2Gjo3S838ghiN8PhaEprEgf+Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959110562984.7297425513382; Tue, 25 May 2021 09:11:50 -0700 (PDT) Received: from localhost ([::1]:36222 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZen-0004QS-RS for importer@patchew.org; Tue, 25 May 2021 12:11:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60374) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeR-0001fF-C6 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:23 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]:42684) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeK-0006g6-3F for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:23 -0400 Received: by mail-pj1-x102e.google.com with SMTP id j6-20020a17090adc86b02900cbfe6f2c96so13344498pjv.1 for ; Tue, 25 May 2021 08:07:14 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=o+y2XL8VpmUirN1zSziSG8ebnfy7nnAzZqTrnTQJTMM=; b=ApVgzULSBQZRvZLCXwLwEz5nCLWO9rqyRm17cxKYJLkDT9hAzlZ/bnozPOpvLN1H0p +zAm0kXBjKe1DKbbAlcdQqOFaLUp6Y/xIYM8ewKOhglf0qNoRn2lDRsja/i0lMuXUxo9 4TZMtjPVHd0K7SMI3+x2hHUwkUEEugGB4R5J7udjVuUs0mOTr1RpKaXaJ6kJ5Rm9L0+V htFS9jyJecVssCXQgi4k2YpwFjyjzhmpQjloeMFuCWlnznK44WbL81422Bq628kpS9w3 W0CS1C3NhEfGoHABfrqGHNnzg/0DJxoBDQmrmjCUNaKJafQuY45qvMfD7JjoztsQaJmf 9kQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=o+y2XL8VpmUirN1zSziSG8ebnfy7nnAzZqTrnTQJTMM=; b=kseec/MCzw0kwWSShTd2PvIFFmizTgYPlfFvU30+s0HlpIBifzaTf0lntPLtDjH4Ne RKqPLJoqgvmozFlqLmvrUFIj62zivuSjBbKb+bxGBTCS+wzZn/v6NMhkdFnxruHh9iIc KeNoCluSGXC9Ihs0aOmlJ8iIV6K65xnPFR7qN43bebT0zDPbU30mmQv0JI7VKxMdjQse d0EelyHvsRO2xJVMXBIZXyDAfYWfhgB5p7WXvY5zOZv65kg8TX60dQRcNJAB7lit3hjJ noGki55o4WDqjVEVJxFIPSpCkJ4ivWVttV2SC8NmNdVCv+bRLhLc4zKhIHF1Z8LTKp8u DJsA== X-Gm-Message-State: AOAM5315JtZceJ9AllhNhuCy4+SEh3bhnTcPcbD9Cga2QvfQYzYkmp3W 6eQHh8HfWovB7FDD2h3A2Pw84EoIh6NHdA== X-Google-Smtp-Source: ABdhPJyjpcWscHcJpY4mellAXnn1TEIg3wMpaqBFX/BiRx7gd1yYQrd/D1KxPsPmv8tNaPL1GeY0Ew== X-Received: by 2002:a17:90a:6ace:: with SMTP id b14mr5321259pjm.142.1621955233362; Tue, 25 May 2021 08:07:13 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 09/28] softfloat: Reduce FloatFmt Date: Tue, 25 May 2021 08:06:47 -0700 Message-Id: <20210525150706.294968-10-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102e; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102e.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Remove frac_lsb, frac_lsbm1, roundeven_mask. Compute these from round_mask in parts$N_uncanon_normal. With floatx80, round_mask will not be tied to frac_shift. Everything else is easily computable. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 29 ++++++++++++----------------- fpu/softfloat-parts.c.inc | 6 +++--- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 2f2bea84da..f6adc2c5ec 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -563,9 +563,7 @@ typedef struct { * frac_size: the size of the fraction field * frac_shift: shift to normalise the fraction with DECOMPOSED_BINARY_PO= INT * The following are computed based the size of fraction - * frac_lsb: least significant bit of fraction - * frac_lsbm1: the bit below the least significant bit (for rounding) - * round_mask/roundeven_mask: masks used for rounding + * round_mask: bits below lsb which must be rounded * The following optional modifiers are available: * arm_althp: handle ARM Alternative Half Precision */ @@ -575,24 +573,21 @@ typedef struct { int exp_max; int frac_size; int frac_shift; - uint64_t frac_lsb; - uint64_t frac_lsbm1; - uint64_t round_mask; - uint64_t roundeven_mask; bool arm_althp; + uint64_t round_mask; } FloatFmt; =20 /* Expand fields based on the size of exponent and fraction */ -#define FLOAT_PARAMS(E, F) \ - .exp_size =3D E, \ - .exp_bias =3D ((1 << E) - 1) >> 1, \ - .exp_max =3D (1 << E) - 1, \ - .frac_size =3D F, \ - .frac_shift =3D (-F - 1) & 63, \ - .frac_lsb =3D 1ull << ((-F - 1) & 63), \ - .frac_lsbm1 =3D 1ull << ((-F - 2) & 63), \ - .round_mask =3D (1ull << ((-F - 1) & 63)) - 1, \ - .roundeven_mask =3D (2ull << ((-F - 1) & 63)) - 1 +#define FLOAT_PARAMS_(E, F) \ + .exp_size =3D E, \ + .exp_bias =3D ((1 << E) - 1) >> 1, \ + .exp_max =3D (1 << E) - 1, \ + .frac_size =3D F + +#define FLOAT_PARAMS(E, F) \ + FLOAT_PARAMS_(E, F), \ + .frac_shift =3D (-F - 1) & 63, \ + .round_mask =3D (1ull << ((-F - 1) & 63)) - 1 =20 static const FloatFmt float16_params =3D { FLOAT_PARAMS(5, 10) diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index d72fe3ab08..b456c1c30c 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -145,10 +145,10 @@ static void partsN(uncanon_normal)(FloatPartsN *p, fl= oat_status *s, { const int exp_max =3D fmt->exp_max; const int frac_shift =3D fmt->frac_shift; - const uint64_t frac_lsb =3D fmt->frac_lsb; - const uint64_t frac_lsbm1 =3D fmt->frac_lsbm1; const uint64_t round_mask =3D fmt->round_mask; - const uint64_t roundeven_mask =3D fmt->roundeven_mask; + const uint64_t frac_lsb =3D round_mask + 1; + const uint64_t frac_lsbm1 =3D round_mask ^ (round_mask >> 1); + const uint64_t roundeven_mask =3D round_mask | frac_lsb; uint64_t inc; bool overflow_norm; int exp, flags =3D 0; --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621960291; cv=none; d=zohomail.com; s=zohoarc; b=PLKU6mJW63iXT/N2c8kYivNPdh2D8sN5eH6WKymRbTiCW6UiuzwQoeTfhVdMPL7ZCTf99jbVrJ2TlG9AC4QckwotqBv7OAY96bAVSJWB0sSAXmm49zAYyiXM7tcNRAF6EnnnIXu2vNZN/Jhv1/f9n3kWGi9DOPYSfnGjHMqUudA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621960291; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=wY8IKnf1330G4VebCabYJygcdJcSuxRpeosyc8jlfgA=; b=D7rQSAo60cG+bf7Izc03GgNwSbEVgEeVOjdjHZnqPW2OVtwoS+07xEioWRvJ+b70ywCTYPXm+Z0Uh5i6PAfzvPK/kjyCQu2/bGjGJLzZ8JkkdifNsecgTvwf98GCH84kLboN27DFtlgrIjF0qmMs0F8ZVO0enTKVKMJuIHJMSEY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621960291717259.29961235779774; Tue, 25 May 2021 09:31:31 -0700 (PDT) Received: from localhost ([::1]:36996 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZxq-000272-Gw for importer@patchew.org; Tue, 25 May 2021 12:31:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60452) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeU-0001pb-DP for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:26 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]:51047) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeK-0006gk-3m for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:25 -0400 Received: by mail-pj1-x102c.google.com with SMTP id t11so17030002pjm.0 for ; Tue, 25 May 2021 08:07:15 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wY8IKnf1330G4VebCabYJygcdJcSuxRpeosyc8jlfgA=; b=zA0CNSY7dQDsokSLX3egJSPk0Azntzu0p/ErqcNgGeNHaEKgHltX4FLF1Arhj+0Ifj b5sgfpZyilkTl0ZV/sBTYAewk6KA1aKmrKD06E7obyHutGMQdOrp0CQSY/zfD2mvPB4i 4fcovbyMts/wVih8ux5ucAUweVVwiLoFf68hYGwhtNSMHFMNlYjFIlo47K06QIUCBl7A iH1naC9/rt6VoifYyuMMPpxExSQT1ywk46HP/ed/5pahOClrNPt3YfCGjEX9oHBjPncB qwZQ5J7o45IKDvCaZJNzO8wMd/h4Lo5DwMdOYpSQbpTSe13OzrcDgqDJty0CvCJf9yrU 9E0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wY8IKnf1330G4VebCabYJygcdJcSuxRpeosyc8jlfgA=; b=E2FN94+DOD6V4omqtWpKwJk6BhM5aAQsi5DkXGPn+VNYShskFJVIADcLAQfLyvRge8 rtvy6k+gjCa/kw90SzSdmPf6bcaGH3utdddeWI+qLEBZKNDsssMIrLPuRA4xSYsf2qQg kkHOwPn8Dtkrt2Fe1CrV+Fpg2CrpwgMkPgRcgULWHQsGS47PaFpeuz1J7vYL1rxNdtrF 0eGze7rmOah+odaFlM/HUamSUA39rO4U/aI2NZeQjSOA/LYKPB12rGJDldGIMK9S1gWx 1DaddstBtgjJl55ZM0FgLYFONhJXr4RqEPo2A80nFAHLLOJKZ1pHfg5fVGuxmJK3A8/G xSaQ== X-Gm-Message-State: AOAM5305rIQnPGcC4KuRIfV7NfVwm0BnaVeP0tC6k2CK2vFDvaQuowv0 olDSnqah+BclNAyGC/FgO2CtPuCqcPSLoQ== X-Google-Smtp-Source: ABdhPJyzntGqzRhgxOTbAgtVu7mjg3LzqRNALy0/in5eNhP+a56u0gBRxFj7GstyLVAT4PQ5s6CByQ== X-Received: by 2002:a17:90a:6285:: with SMTP id d5mr31343831pjj.3.1621955234291; Tue, 25 May 2021 08:07:14 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 10/28] softfloat: Introduce Floatx80RoundPrec Date: Tue, 25 May 2021 08:06:48 -0700 Message-Id: <20210525150706.294968-11-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102c.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Use an enumeration instead of raw 32/64/80 values. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- include/fpu/softfloat-helpers.h | 5 +- include/fpu/softfloat-types.h | 10 +++- include/fpu/softfloat.h | 4 +- fpu/softfloat.c | 32 ++++++------ linux-user/arm/nwfpe/fpa11.c | 41 +++++++-------- target/i386/tcg/fpu_helper.c | 79 +++++++++++++++++------------ target/m68k/fpu_helper.c | 50 +++++++++--------- target/m68k/softfloat.c | 90 ++++++++++++++++++++------------- tests/fp/fp-test.c | 5 +- 9 files changed, 182 insertions(+), 134 deletions(-) diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helper= s.h index 2f0674fbdd..34f4cf92ae 100644 --- a/include/fpu/softfloat-helpers.h +++ b/include/fpu/softfloat-helpers.h @@ -69,7 +69,7 @@ static inline void set_float_exception_flags(int val, flo= at_status *status) status->float_exception_flags =3D val; } =20 -static inline void set_floatx80_rounding_precision(int val, +static inline void set_floatx80_rounding_precision(FloatX80RoundPrec val, float_status *status) { status->floatx80_rounding_precision =3D val; @@ -120,7 +120,8 @@ static inline int get_float_exception_flags(float_statu= s *status) return status->float_exception_flags; } =20 -static inline int get_floatx80_rounding_precision(float_status *status) +static inline FloatX80RoundPrec +get_floatx80_rounding_precision(float_status *status) { return status->floatx80_rounding_precision; } diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h index 8a3f20fae9..1f83378c20 100644 --- a/include/fpu/softfloat-types.h +++ b/include/fpu/softfloat-types.h @@ -152,6 +152,14 @@ enum { float_flag_output_denormal =3D 128 }; =20 +/* + * Rounding precision for floatx80. + */ +typedef enum __attribute__((__packed__)) { + floatx80_precision_x, + floatx80_precision_d, + floatx80_precision_s, +} FloatX80RoundPrec; =20 /* * Floating Point Status. Individual architectures may maintain @@ -163,7 +171,7 @@ enum { typedef struct float_status { FloatRoundMode float_rounding_mode; uint8_t float_exception_flags; - signed char floatx80_rounding_precision; + FloatX80RoundPrec floatx80_rounding_precision; bool tininess_before_rounding; /* should denormalised results go to zero and set the inexact flag? */ bool flush_to_zero; diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 53f2c2ea3c..94f7841b9f 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -1152,7 +1152,7 @@ floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b,= float_status *status); | Floating-Point Arithmetic. *-------------------------------------------------------------------------= ---*/ =20 -floatx80 roundAndPackFloatx80(int8_t roundingPrecision, bool zSign, +floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zS= ign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status); =20 @@ -1165,7 +1165,7 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecisio= n, bool zSign, | normalized. *-------------------------------------------------------------------------= ---*/ =20 -floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision, +floatx80 normalizeRoundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status); diff --git a/fpu/softfloat.c b/fpu/softfloat.c index f6adc2c5ec..d7477212be 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -4345,10 +4345,10 @@ void normalizeFloatx80Subnormal(uint64_t aSig, int3= 2_t *zExpPtr, | a subnormal number, and the underflow and inexact exceptions are raised = if | the abstract input cannot be represented exactly as a subnormal extended | double-precision floating-point number. -| If `roundingPrecision' is 32 or 64, the result is rounded to the same -| number of bits as single or double precision, respectively. Otherwise, = the -| result is rounded to the full precision of the extended double-precision -| format. +| If `roundingPrecision' is floatx80_precision_s or floatx80_precision= _d, +| the result is rounded to the same number of bits as single or double +| precision, respectively. Otherwise, the result is rounded to the full +| precision of the extended double-precision format. | The input significand must be normalized or smaller. If the input | significand is not normalized, `zExp' must be 0; in that case, the result | returned is a subnormal number, and it must not require rounding. The @@ -4356,27 +4356,29 @@ void normalizeFloatx80Subnormal(uint64_t aSig, int3= 2_t *zExpPtr, | Floating-Point Arithmetic. *-------------------------------------------------------------------------= ---*/ =20 -floatx80 roundAndPackFloatx80(int8_t roundingPrecision, bool zSign, +floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zS= ign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status) { - int8_t roundingMode; + FloatRoundMode roundingMode; bool roundNearestEven, increment, isTiny; int64_t roundIncrement, roundMask, roundBits; =20 roundingMode =3D status->float_rounding_mode; roundNearestEven =3D ( roundingMode =3D=3D float_round_nearest_even ); - if ( roundingPrecision =3D=3D 80 ) goto precision80; - if ( roundingPrecision =3D=3D 64 ) { + switch (roundingPrecision) { + case floatx80_precision_x: + goto precision80; + case floatx80_precision_d: roundIncrement =3D UINT64_C(0x0000000000000400); roundMask =3D UINT64_C(0x00000000000007FF); - } - else if ( roundingPrecision =3D=3D 32 ) { + break; + case floatx80_precision_s: roundIncrement =3D UINT64_C(0x0000008000000000); roundMask =3D UINT64_C(0x000000FFFFFFFFFF); - } - else { - goto precision80; + break; + default: + g_assert_not_reached(); } zSig0 |=3D ( zSig1 !=3D 0 ); switch (roundingMode) { @@ -4553,7 +4555,7 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecisio= n, bool zSign, | normalized. *-------------------------------------------------------------------------= ---*/ =20 -floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision, +floatx80 normalizeRoundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status) @@ -6206,7 +6208,7 @@ floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool= mod, uint64_t *quotient, } return normalizeRoundAndPackFloatx80( - 80, zSign, bExp + expDiff, aSig0, aSig1, status); + floatx80_precision_x, zSign, bExp + expDiff, aSig0, aSig1, sta= tus); =20 } =20 diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c index f6f8163eab..9a93610d24 100644 --- a/linux-user/arm/nwfpe/fpa11.c +++ b/linux-user/arm/nwfpe/fpa11.c @@ -97,37 +97,38 @@ void SetRoundingMode(const unsigned int opcode) =20 void SetRoundingPrecision(const unsigned int opcode) { - int rounding_precision; - FPA11 *fpa11 =3D GET_FPA11(); + FloatX80RoundPrec rounding_precision; + FPA11 *fpa11 =3D GET_FPA11(); #ifdef MAINTAIN_FPCR - fpa11->fpcr &=3D ~MASK_ROUNDING_PRECISION; + fpa11->fpcr &=3D ~MASK_ROUNDING_PRECISION; #endif - switch (opcode & MASK_ROUNDING_PRECISION) - { - case ROUND_SINGLE: - rounding_precision =3D 32; + switch (opcode & MASK_ROUNDING_PRECISION) { + case ROUND_SINGLE: + rounding_precision =3D floatx80_precision_s; #ifdef MAINTAIN_FPCR - fpa11->fpcr |=3D ROUND_SINGLE; + fpa11->fpcr |=3D ROUND_SINGLE; #endif - break; + break; =20 - case ROUND_DOUBLE: - rounding_precision =3D 64; + case ROUND_DOUBLE: + rounding_precision =3D floatx80_precision_d; #ifdef MAINTAIN_FPCR - fpa11->fpcr |=3D ROUND_DOUBLE; + fpa11->fpcr |=3D ROUND_DOUBLE; #endif - break; + break; =20 - case ROUND_EXTENDED: - rounding_precision =3D 80; + case ROUND_EXTENDED: + rounding_precision =3D floatx80_precision_x; #ifdef MAINTAIN_FPCR - fpa11->fpcr |=3D ROUND_EXTENDED; + fpa11->fpcr |=3D ROUND_EXTENDED; #endif - break; + break; =20 - default: rounding_precision =3D 80; - } - set_floatx80_rounding_precision(rounding_precision, &fpa11->fp_status); + default: + rounding_precision =3D floatx80_precision_x; + break; + } + set_floatx80_rounding_precision(rounding_precision, &fpa11->fp_status); } =20 /* Emulate the instruction in the opcode. */ diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c index 1b30f1bb73..4e11965067 100644 --- a/target/i386/tcg/fpu_helper.c +++ b/target/i386/tcg/fpu_helper.c @@ -673,38 +673,40 @@ uint32_t helper_fnstcw(CPUX86State *env) =20 void update_fp_status(CPUX86State *env) { - int rnd_type; + FloatRoundMode rnd_mode; + FloatX80RoundPrec rnd_prec; =20 /* set rounding mode */ switch (env->fpuc & FPU_RC_MASK) { default: case FPU_RC_NEAR: - rnd_type =3D float_round_nearest_even; + rnd_mode =3D float_round_nearest_even; break; case FPU_RC_DOWN: - rnd_type =3D float_round_down; + rnd_mode =3D float_round_down; break; case FPU_RC_UP: - rnd_type =3D float_round_up; + rnd_mode =3D float_round_up; break; case FPU_RC_CHOP: - rnd_type =3D float_round_to_zero; + rnd_mode =3D float_round_to_zero; break; } - set_float_rounding_mode(rnd_type, &env->fp_status); + set_float_rounding_mode(rnd_mode, &env->fp_status); + switch ((env->fpuc >> 8) & 3) { case 0: - rnd_type =3D 32; + rnd_prec =3D floatx80_precision_s; break; case 2: - rnd_type =3D 64; + rnd_prec =3D floatx80_precision_d; break; case 3: default: - rnd_type =3D 80; + rnd_prec =3D floatx80_precision_x; break; } - set_floatx80_rounding_precision(rnd_type, &env->fp_status); + set_floatx80_rounding_precision(rnd_prec, &env->fp_status); } =20 void helper_fldcw(CPUX86State *env, uint32_t val) @@ -1074,7 +1076,8 @@ void helper_f2xm1(CPUX86State *env) &sig2); /* This result is inexact. */ sig1 |=3D 1; - ST0 =3D normalizeRoundAndPackFloatx80(80, sign, exp, sig0, sig= 1, + ST0 =3D normalizeRoundAndPackFloatx80(floatx80_precision_x, + sign, exp, sig0, sig1, &env->fp_status); } } else { @@ -1083,9 +1086,10 @@ void helper_f2xm1(CPUX86State *env) int32_t n, aexp, bexp; uint64_t asig0, asig1, asig2, bsig0, bsig1; FloatRoundMode save_mode =3D env->fp_status.float_rounding_mode; - signed char save_prec =3D env->fp_status.floatx80_rounding_precisi= on; + FloatX80RoundPrec save_prec =3D + env->fp_status.floatx80_rounding_precision; env->fp_status.float_rounding_mode =3D float_round_nearest_even; - env->fp_status.floatx80_rounding_precision =3D 80; + env->fp_status.floatx80_rounding_precision =3D floatx80_precision_= x; =20 /* Find the nearest multiple of 1/32 to the argument. */ tmp =3D floatx80_scalbn(ST0, 5, &env->fp_status); @@ -1183,7 +1187,8 @@ void helper_f2xm1(CPUX86State *env) env->fp_status.float_rounding_mode =3D save_mode; /* This result is inexact. */ asig1 |=3D 1; - ST0 =3D normalizeRoundAndPackFloatx80(80, asign, aexp, asig0, = asig1, + ST0 =3D normalizeRoundAndPackFloatx80(floatx80_precision_x, + asign, aexp, asig0, asig1, &env->fp_status); } =20 @@ -1301,8 +1306,9 @@ void helper_fpatan(CPUX86State *env) * division is exact, the result of fpatan is still inexact * (and underflowing where appropriate). */ - signed char save_prec =3D env->fp_status.floatx80_rounding_precisi= on; - env->fp_status.floatx80_rounding_precision =3D 80; + FloatX80RoundPrec save_prec =3D + env->fp_status.floatx80_rounding_precision; + env->fp_status.floatx80_rounding_precision =3D floatx80_precision_= x; ST1 =3D floatx80_div(ST1, ST0, &env->fp_status); env->fp_status.floatx80_rounding_precision =3D save_prec; if (!floatx80_is_zero(ST1) && @@ -1321,7 +1327,8 @@ void helper_fpatan(CPUX86State *env) if (exp =3D=3D 0) { normalizeFloatx80Subnormal(sig, &exp, &sig); } - ST1 =3D normalizeRoundAndPackFloatx80(80, sign, exp, sig - 1, + ST1 =3D normalizeRoundAndPackFloatx80(floatx80_precision_x, + sign, exp, sig - 1, -1, &env->fp_status); } } else { @@ -1377,9 +1384,10 @@ void helper_fpatan(CPUX86State *env) uint64_t azsig2, azsig3, axsig0, axsig1; floatx80 x8; FloatRoundMode save_mode =3D env->fp_status.float_rounding_mod= e; - signed char save_prec =3D env->fp_status.floatx80_rounding_pre= cision; + FloatX80RoundPrec save_prec =3D + env->fp_status.floatx80_rounding_precision; env->fp_status.float_rounding_mode =3D float_round_nearest_eve= n; - env->fp_status.floatx80_rounding_precision =3D 80; + env->fp_status.floatx80_rounding_precision =3D floatx80_precis= ion_x; =20 if (arg0_exp =3D=3D 0) { normalizeFloatx80Subnormal(arg0_sig, &arg0_exp, &arg0_sig); @@ -1448,7 +1456,8 @@ void helper_fpatan(CPUX86State *env) * Split x as x =3D t + y, where t =3D n/8 is the nearest * multiple of 1/8 to x. */ - x8 =3D normalizeRoundAndPackFloatx80(80, false, xexp + 3, xsig= 0, + x8 =3D normalizeRoundAndPackFloatx80(floatx80_precision_x, + false, xexp + 3, xsig0, xsig1, &env->fp_status); n =3D floatx80_to_int32(x8, &env->fp_status); if (n =3D=3D 0) { @@ -1569,7 +1578,7 @@ void helper_fpatan(CPUX86State *env) /* Compute z^2. */ mul128To256(zsig0, zsig1, zsig0, zsig1, &z2sig0, &z2sig1, &z2sig2, &z2sig3); - z2 =3D normalizeRoundAndPackFloatx80(80, false, + z2 =3D normalizeRoundAndPackFloatx80(floatx80_precision_x,= false, zexp + zexp - 0x3ffe, z2sig0, z2sig1, &env->fp_status); @@ -1689,7 +1698,7 @@ void helper_fpatan(CPUX86State *env) } /* This result is inexact. */ rsig1 |=3D 1; - ST1 =3D normalizeRoundAndPackFloatx80(80, rsign, rexp, + ST1 =3D normalizeRoundAndPackFloatx80(floatx80_precision_x, rsign,= rexp, rsig0, rsig1, &env->fp_status); } =20 @@ -1890,7 +1899,8 @@ static void helper_fyl2x_common(CPUX86State *env, flo= atx80 arg, int32_t *exp, */ mul128To256(tsig0, tsig1, tsig0, tsig1, &t2sig0, &t2sig1, &t2sig2, &t2sig3); - t2 =3D normalizeRoundAndPackFloatx80(80, false, texp + texp - 0x3ffe, + t2 =3D normalizeRoundAndPackFloatx80(floatx80_precision_x, false, + texp + texp - 0x3ffe, t2sig0, t2sig1, &env->fp_status); =20 /* Compute the lower parts of the polynomial expansion. */ @@ -2004,15 +2014,17 @@ void helper_fyl2xp1(CPUX86State *env) exp +=3D arg1_exp - 0x3ffe; /* This result is inexact. */ sig1 |=3D 1; - ST1 =3D normalizeRoundAndPackFloatx80(80, arg0_sign ^ arg1_sign, e= xp, + ST1 =3D normalizeRoundAndPackFloatx80(floatx80_precision_x, + arg0_sign ^ arg1_sign, exp, sig0, sig1, &env->fp_status); } else { int32_t aexp; uint64_t asig0, asig1, asig2; FloatRoundMode save_mode =3D env->fp_status.float_rounding_mode; - signed char save_prec =3D env->fp_status.floatx80_rounding_precisi= on; + FloatX80RoundPrec save_prec =3D + env->fp_status.floatx80_rounding_precision; env->fp_status.float_rounding_mode =3D float_round_nearest_even; - env->fp_status.floatx80_rounding_precision =3D 80; + env->fp_status.floatx80_rounding_precision =3D floatx80_precision_= x; =20 helper_fyl2x_common(env, ST0, &aexp, &asig0, &asig1); /* @@ -2027,7 +2039,8 @@ void helper_fyl2xp1(CPUX86State *env) /* This result is inexact. */ asig1 |=3D 1; env->fp_status.float_rounding_mode =3D save_mode; - ST1 =3D normalizeRoundAndPackFloatx80(80, arg0_sign ^ arg1_sign, a= exp, + ST1 =3D normalizeRoundAndPackFloatx80(floatx80_precision_x, + arg0_sign ^ arg1_sign, aexp, asig0, asig1, &env->fp_status); env->fp_status.floatx80_rounding_precision =3D save_prec; } @@ -2111,9 +2124,10 @@ void helper_fyl2x(CPUX86State *env) int32_t int_exp; floatx80 arg0_m1; FloatRoundMode save_mode =3D env->fp_status.float_rounding_mode; - signed char save_prec =3D env->fp_status.floatx80_rounding_precisi= on; + FloatX80RoundPrec save_prec =3D + env->fp_status.floatx80_rounding_precision; env->fp_status.float_rounding_mode =3D float_round_nearest_even; - env->fp_status.floatx80_rounding_precision =3D 80; + env->fp_status.floatx80_rounding_precision =3D floatx80_precision_= x; =20 if (arg0_exp =3D=3D 0) { normalizeFloatx80Subnormal(arg0_sig, &arg0_exp, &arg0_sig); @@ -2170,7 +2184,8 @@ void helper_fyl2x(CPUX86State *env) /* This result is inexact. */ asig1 |=3D 1; env->fp_status.float_rounding_mode =3D save_mode; - ST1 =3D normalizeRoundAndPackFloatx80(80, asign ^ arg1_sign, a= exp, + ST1 =3D normalizeRoundAndPackFloatx80(floatx80_precision_x, + asign ^ arg1_sign, aexp, asig0, asig1, &env->fp_sta= tus); } =20 @@ -2252,12 +2267,12 @@ void helper_fscale(CPUX86State *env) } } else { int n; - signed char save =3D env->fp_status.floatx80_rounding_precision; + FloatX80RoundPrec save =3D env->fp_status.floatx80_rounding_precis= ion; uint8_t save_flags =3D get_float_exception_flags(&env->fp_status); set_float_exception_flags(0, &env->fp_status); n =3D floatx80_to_int32_round_to_zero(ST1, &env->fp_status); set_float_exception_flags(save_flags, &env->fp_status); - env->fp_status.floatx80_rounding_precision =3D 80; + env->fp_status.floatx80_rounding_precision =3D floatx80_precision_= x; ST0 =3D floatx80_scalbn(ST0, n, &env->fp_status); env->fp_status.floatx80_rounding_precision =3D save; } diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index 797000e748..fdc4937e29 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -94,13 +94,13 @@ static void m68k_restore_precision_mode(CPUM68KState *e= nv) { switch (env->fpcr & FPCR_PREC_MASK) { case FPCR_PREC_X: /* extended */ - set_floatx80_rounding_precision(80, &env->fp_status); + set_floatx80_rounding_precision(floatx80_precision_x, &env->fp_sta= tus); break; case FPCR_PREC_S: /* single */ - set_floatx80_rounding_precision(32, &env->fp_status); + set_floatx80_rounding_precision(floatx80_precision_s, &env->fp_sta= tus); break; case FPCR_PREC_D: /* double */ - set_floatx80_rounding_precision(64, &env->fp_status); + set_floatx80_rounding_precision(floatx80_precision_d, &env->fp_sta= tus); break; case FPCR_PREC_U: /* undefined */ default: @@ -111,9 +111,9 @@ static void m68k_restore_precision_mode(CPUM68KState *e= nv) static void cf_restore_precision_mode(CPUM68KState *env) { if (env->fpcr & FPCR_PREC_S) { /* single */ - set_floatx80_rounding_precision(32, &env->fp_status); + set_floatx80_rounding_precision(floatx80_precision_s, &env->fp_sta= tus); } else { /* double */ - set_floatx80_rounding_precision(64, &env->fp_status); + set_floatx80_rounding_precision(floatx80_precision_d, &env->fp_sta= tus); } } =20 @@ -166,8 +166,8 @@ void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val) =20 #define PREC_BEGIN(prec) \ do { \ - int old; \ - old =3D get_floatx80_rounding_precision(&env->fp_status); \ + FloatX80RoundPrec old =3D \ + get_floatx80_rounding_precision(&env->fp_status); \ set_floatx80_rounding_precision(prec, &env->fp_status) \ =20 #define PREC_END() \ @@ -176,14 +176,14 @@ void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val) =20 void HELPER(fsround)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d =3D floatx80_round(val->d, &env->fp_status); PREC_END(); } =20 void HELPER(fdround)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d =3D floatx80_round(val->d, &env->fp_status); PREC_END(); } @@ -195,14 +195,14 @@ void HELPER(fsqrt)(CPUM68KState *env, FPReg *res, FPR= eg *val) =20 void HELPER(fssqrt)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d =3D floatx80_sqrt(val->d, &env->fp_status); PREC_END(); } =20 void HELPER(fdsqrt)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d =3D floatx80_sqrt(val->d, &env->fp_status); PREC_END(); } @@ -214,14 +214,14 @@ void HELPER(fabs)(CPUM68KState *env, FPReg *res, FPRe= g *val) =20 void HELPER(fsabs)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d =3D floatx80_round(floatx80_abs(val->d), &env->fp_status); PREC_END(); } =20 void HELPER(fdabs)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d =3D floatx80_round(floatx80_abs(val->d), &env->fp_status); PREC_END(); } @@ -233,14 +233,14 @@ void HELPER(fneg)(CPUM68KState *env, FPReg *res, FPRe= g *val) =20 void HELPER(fsneg)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d =3D floatx80_round(floatx80_chs(val->d), &env->fp_status); PREC_END(); } =20 void HELPER(fdneg)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d =3D floatx80_round(floatx80_chs(val->d), &env->fp_status); PREC_END(); } @@ -252,14 +252,14 @@ void HELPER(fadd)(CPUM68KState *env, FPReg *res, FPRe= g *val0, FPReg *val1) =20 void HELPER(fsadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d =3D floatx80_add(val0->d, val1->d, &env->fp_status); PREC_END(); } =20 void HELPER(fdadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d =3D floatx80_add(val0->d, val1->d, &env->fp_status); PREC_END(); } @@ -271,14 +271,14 @@ void HELPER(fsub)(CPUM68KState *env, FPReg *res, FPRe= g *val0, FPReg *val1) =20 void HELPER(fssub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d =3D floatx80_sub(val1->d, val0->d, &env->fp_status); PREC_END(); } =20 void HELPER(fdsub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d =3D floatx80_sub(val1->d, val0->d, &env->fp_status); PREC_END(); } @@ -290,14 +290,14 @@ void HELPER(fmul)(CPUM68KState *env, FPReg *res, FPRe= g *val0, FPReg *val1) =20 void HELPER(fsmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d =3D floatx80_mul(val0->d, val1->d, &env->fp_status); PREC_END(); } =20 void HELPER(fdmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d =3D floatx80_mul(val0->d, val1->d, &env->fp_status); PREC_END(); } @@ -307,7 +307,7 @@ void HELPER(fsglmul)(CPUM68KState *env, FPReg *res, FPR= eg *val0, FPReg *val1) FloatRoundMode rounding_mode =3D get_float_rounding_mode(&env->fp_stat= us); floatx80 a, b; =20 - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); set_float_rounding_mode(float_round_to_zero, &env->fp_status); a =3D floatx80_round(val0->d, &env->fp_status); b =3D floatx80_round(val1->d, &env->fp_status); @@ -323,14 +323,14 @@ void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPRe= g *val0, FPReg *val1) =20 void HELPER(fsdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d =3D floatx80_div(val1->d, val0->d, &env->fp_status); PREC_END(); } =20 void HELPER(fddiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d =3D floatx80_div(val1->d, val0->d, &env->fp_status); PREC_END(); } @@ -340,7 +340,7 @@ void HELPER(fsgldiv)(CPUM68KState *env, FPReg *res, FPR= eg *val0, FPReg *val1) FloatRoundMode rounding_mode =3D get_float_rounding_mode(&env->fp_stat= us); floatx80 a, b; =20 - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); set_float_rounding_mode(float_round_to_zero, &env->fp_status); a =3D floatx80_round(val1->d, &env->fp_status); b =3D floatx80_round(val0->d, &env->fp_status); diff --git a/target/m68k/softfloat.c b/target/m68k/softfloat.c index b6d0ed7acf..02dcc03d15 100644 --- a/target/m68k/softfloat.c +++ b/target/m68k/softfloat.c @@ -227,7 +227,8 @@ floatx80 floatx80_lognp1(floatx80 a, float_status *stat= us) int32_t aExp; uint64_t aSig, fSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact, j, k; floatx80 fp0, fp1, fp2, fp3, f, logof2, klog2, saveu; @@ -270,7 +271,7 @@ floatx80 floatx80_lognp1(floatx80 a, float_status *stat= us) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 compact =3D floatx80_make_compact(aExp, aSig); =20 @@ -426,7 +427,8 @@ floatx80 floatx80_logn(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig, fSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact, j, k, adjk; floatx80 fp0, fp1, fp2, fp3, f, logof2, klog2, saveu; @@ -469,7 +471,7 @@ floatx80 floatx80_logn(floatx80 a, float_status *status) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 compact =3D floatx80_make_compact(aExp, aSig); =20 @@ -594,7 +596,8 @@ floatx80 floatx80_log10(floatx80 a, float_status *statu= s) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 floatx80 fp0, fp1; =20 @@ -626,7 +629,7 @@ floatx80 floatx80_log10(floatx80 a, float_status *statu= s) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 fp0 =3D floatx80_logn(a, status); fp1 =3D packFloatx80(0, 0x3FFD, UINT64_C(0xDE5BD8A937287195)); /* INV_= L10 */ @@ -651,7 +654,8 @@ floatx80 floatx80_log2(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 floatx80 fp0, fp1; =20 @@ -686,7 +690,7 @@ floatx80 floatx80_log2(floatx80 a, float_status *status) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 if (aSig =3D=3D one_sig) { /* X is 2^k */ status->float_rounding_mode =3D user_rnd_mode; @@ -718,7 +722,8 @@ floatx80 floatx80_etox(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact, n, j, k, m, m1; floatx80 fp0, fp1, fp2, fp3, l2, scale, adjscale; @@ -746,7 +751,7 @@ floatx80 floatx80_etox(floatx80 a, float_status *status) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 adjflag =3D 0; =20 @@ -902,7 +907,8 @@ floatx80 floatx80_twotox(floatx80 a, float_status *stat= us) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact, n, j, l, m, m1; floatx80 fp0, fp1, fp2, fp3, adjfact, fact1, fact2; @@ -929,7 +935,7 @@ floatx80 floatx80_twotox(floatx80 a, float_status *stat= us) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 fp0 =3D a; =20 @@ -1052,7 +1058,8 @@ floatx80 floatx80_tentox(floatx80 a, float_status *st= atus) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact, n, j, l, m, m1; floatx80 fp0, fp1, fp2, fp3, adjfact, fact1, fact2; @@ -1079,7 +1086,7 @@ floatx80 floatx80_tentox(floatx80 a, float_status *st= atus) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 fp0 =3D a; =20 @@ -1207,7 +1214,8 @@ floatx80 floatx80_tan(floatx80 a, float_status *statu= s) int32_t aExp, xExp; uint64_t aSig, xSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact, l, n, j; floatx80 fp0, fp1, fp2, fp3, fp4, fp5, invtwopi, twopi1, twopi2; @@ -1233,7 +1241,7 @@ floatx80 floatx80_tan(floatx80 a, float_status *statu= s) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 compact =3D floatx80_make_compact(aExp, aSig); =20 @@ -1417,7 +1425,8 @@ floatx80 floatx80_sin(floatx80 a, float_status *statu= s) int32_t aExp, xExp; uint64_t aSig, xSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact, l, n, j; floatx80 fp0, fp1, fp2, fp3, fp4, fp5, x, invtwopi, twopi1, twopi2; @@ -1443,7 +1452,7 @@ floatx80 floatx80_sin(floatx80 a, float_status *statu= s) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 compact =3D floatx80_make_compact(aExp, aSig); =20 @@ -1656,7 +1665,8 @@ floatx80 floatx80_cos(floatx80 a, float_status *statu= s) int32_t aExp, xExp; uint64_t aSig, xSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact, l, n, j; floatx80 fp0, fp1, fp2, fp3, fp4, fp5, x, invtwopi, twopi1, twopi2; @@ -1682,7 +1692,7 @@ floatx80 floatx80_cos(floatx80 a, float_status *statu= s) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 compact =3D floatx80_make_compact(aExp, aSig); =20 @@ -1893,7 +1903,8 @@ floatx80 floatx80_atan(floatx80 a, float_status *stat= us) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact, tbl_index; floatx80 fp0, fp1, fp2, fp3, xsave; @@ -1920,7 +1931,7 @@ floatx80 floatx80_atan(floatx80 a, float_status *stat= us) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 if (compact < 0x3FFB8000 || compact > 0x4002FFFF) { /* |X| >=3D 16 or |X| < 1/16 */ @@ -2090,7 +2101,8 @@ floatx80 floatx80_asin(floatx80 a, float_status *stat= us) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact; floatx80 fp0, fp1, fp2, one; @@ -2124,7 +2136,7 @@ floatx80 floatx80_asin(floatx80 a, float_status *stat= us) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 one =3D packFloatx80(0, one_exp, one_sig); fp0 =3D a; @@ -2155,7 +2167,8 @@ floatx80 floatx80_acos(floatx80 a, float_status *stat= us) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact; floatx80 fp0, fp1, one; @@ -2193,7 +2206,7 @@ floatx80 floatx80_acos(floatx80 a, float_status *stat= us) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 one =3D packFloatx80(0, one_exp, one_sig); fp0 =3D a; @@ -2224,7 +2237,8 @@ floatx80 floatx80_atanh(floatx80 a, float_status *sta= tus) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact; floatx80 fp0, fp1, fp2, one; @@ -2257,7 +2271,7 @@ floatx80 floatx80_atanh(floatx80 a, float_status *sta= tus) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 one =3D packFloatx80(0, one_exp, one_sig); fp2 =3D packFloatx80(aSign, 0x3FFE, one_sig); /* SIGN(X) * (1/2) */ @@ -2289,7 +2303,8 @@ floatx80 floatx80_etoxm1(floatx80 a, float_status *st= atus) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact, n, j, m, m1; floatx80 fp0, fp1, fp2, fp3, l2, sc, onebysc; @@ -2316,7 +2331,7 @@ floatx80 floatx80_etoxm1(floatx80 a, float_status *st= atus) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 if (aExp >=3D 0x3FFD) { /* |X| >=3D 1/4 */ compact =3D floatx80_make_compact(aExp, aSig); @@ -2541,7 +2556,8 @@ floatx80 floatx80_tanh(floatx80 a, float_status *stat= us) int32_t aExp, vExp; uint64_t aSig, vSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact; floatx80 fp0, fp1; @@ -2565,7 +2581,7 @@ floatx80 floatx80_tanh(floatx80 a, float_status *stat= us) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 compact =3D floatx80_make_compact(aExp, aSig); =20 @@ -2656,7 +2672,8 @@ floatx80 floatx80_sinh(floatx80 a, float_status *stat= us) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact; floatx80 fp0, fp1, fp2; @@ -2681,7 +2698,7 @@ floatx80 floatx80_sinh(floatx80 a, float_status *stat= us) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 compact =3D floatx80_make_compact(aExp, aSig); =20 @@ -2744,7 +2761,8 @@ floatx80 floatx80_cosh(floatx80 a, float_status *stat= us) int32_t aExp; uint64_t aSig; =20 - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; =20 int32_t compact; floatx80 fp0, fp1; @@ -2767,7 +2785,7 @@ floatx80 floatx80_cosh(floatx80 a, float_status *stat= us) user_rnd_mode =3D status->float_rounding_mode; user_rnd_prec =3D status->floatx80_rounding_precision; status->float_rounding_mode =3D float_round_nearest_even; - status->floatx80_rounding_precision =3D 80; + status->floatx80_rounding_precision =3D floatx80_precision_x; =20 compact =3D floatx80_make_compact(aExp, aSig); =20 diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c index ff131afbde..1be3a9788a 100644 --- a/tests/fp/fp-test.c +++ b/tests/fp/fp-test.c @@ -963,18 +963,21 @@ static void QEMU_NORETURN run_test(void) verCases_usesExact =3D !!(attrs & FUNC_ARG_EXACT); =20 for (k =3D 0; k < 3; k++) { + FloatX80RoundPrec qsf_prec80 =3D floatx80_precision_s; int prec80 =3D 32; int l; =20 if (k =3D=3D 1) { prec80 =3D 64; + qsf_prec80 =3D floatx80_precision_d; } else if (k =3D=3D 2) { prec80 =3D 80; + qsf_prec80 =3D floatx80_precision_x; } =20 verCases_roundingPrecision =3D 0; slow_extF80_roundingPrecision =3D prec80; - qsf.floatx80_rounding_precision =3D prec80; + qsf.floatx80_rounding_precision =3D qsf_prec80; =20 if (attrs & FUNC_EFF_ROUNDINGPRECISION) { verCases_roundingPrecision =3D prec80; --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959118; cv=none; d=zohomail.com; s=zohoarc; b=nxLyclZ844AtKWiqu0SJShBvaglPBm4Lg808uH8lh4tJxjHoHV/ZIztT5UV7g31eCvLXwdVrnjfe0sP9om6LUYEy2kpXgInTcXLGuHRzh80M+vVyHhg7zGVCJI6JtxxIejQn7IeY5BxSeaXWeXATqKSMusOCWXrQsRW1bF2T8/s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959118; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=hRoARebbIM30+5QjLTpQyHKZOtTassCJ5Yf1wssASeE=; b=HX6JlDHCkl7P1byxV5sKRiQ3wZXXaqwKA0G2KG8O2/tgGZ0SoK1nPzXjtcRYI4guoc9PrjWomIHJxbCH988WGSfuNDszXZFmCB/a9ewq0rbXG44NGhmc64oOb4hGDnAPGuTw4ntH8fgP2eNXQVSZRkvUQ+JDLGovqvFVAzbZMGU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959118647673.3369026422077; Tue, 25 May 2021 09:11:58 -0700 (PDT) Received: from localhost ([::1]:37082 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZev-00051M-NT for importer@patchew.org; Tue, 25 May 2021 12:11:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60384) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeR-0001go-Mj for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:23 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]:42880) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeK-0006go-3m for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:23 -0400 Received: by mail-pl1-x62c.google.com with SMTP id v13so16483479ple.9 for ; Tue, 25 May 2021 08:07:15 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=hRoARebbIM30+5QjLTpQyHKZOtTassCJ5Yf1wssASeE=; b=bAAI/GPx7i7Cv+CE5CxC9LxUX8N/E9378LDG81oB7pd0dn6kFP9IgLTvbi4s07JwSj vsPsfGa2d6M4jK8m03e/rp9DqUeeMGD8houhXP7CEzFiSi0yJWx0CNVyGnZS7R9tyWhG ITxNpt98GmxRLuHw7yHjXWtqnh5Q+pchncHNl9MkMWDEaGJApXbbwdzyQOV97h+v1Qx3 +TTU0IAqxFeMxxZvT92zD5cpeLY7eajYxMSvZrtBkizxjrCq4bBLeHLlj+o0v9QneW5n iSXJ6ogjIKQuxn+pp+Qmp5wA0jC1K0J+iTvVEP958vul+g88/L3+yJ9vwkwOSNPhPwRG pdDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hRoARebbIM30+5QjLTpQyHKZOtTassCJ5Yf1wssASeE=; b=EF6M0D/IgvNpJhoSgZG/Efwtm/S5YuOt0x5OB65gk9WEGZxPjWJlIfZh47PBpp9OLF C0U/tUDdU8N/lQZ63iGneb1nduHsy8iEaI7SQvsvQsCTTDDAWFKfG309BSqQRHgUuMJ0 PNzAOOuE/KwyxBX2N80kA477VLnXJ6uQ5b0/BhKJ228flm2Nyrkk9su9KTVS/1W4Z5rL cRKdgljfcL2qFoBcTM6/KM7+12EKYCGLN2xKuN9hztMmfqc5lmn0kIefEduFO55gXKuW jUI9Akqvl4S2WMytb80qxtV2g+VEHxg/mqy07JcWVJ1sSe1megZQQwTC6lEU57BZelih UE3Q== X-Gm-Message-State: AOAM533RmKfrBd0yvYugfS/eR+umS3YNrGTFHlewqrfYOlGZSvMVe4VJ R9JpWqVJ7NMtC7hZPJnPWM+5BGF+sepkoQ== X-Google-Smtp-Source: ABdhPJyYkibfLE6BjxFSBO+yPcPZKgpg4CxHpZbbhp30W6Ym5QF52OM2jJqwP1l00rvwG79MsLDIRQ== X-Received: by 2002:a17:90a:4a89:: with SMTP id f9mr5324280pjh.50.1621955234822; Tue, 25 May 2021 08:07:14 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 11/28] softfloat: Adjust parts_uncanon_normal for floatx80 Date: Tue, 25 May 2021 08:06:49 -0700 Message-Id: <20210525150706.294968-12-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62c.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" With floatx80_precision_x, the rounding happens across the break between words. Notice this case with frac_lsb =3D round_mask + 1 -> 0 and check the bits in frac_hi as needed. In addition, since frac_shift =3D=3D 0, we won't implicitly clear round_mask via the right-shift, so explicitly clear those bits. This fixes rounding for floatx80_precision_[sd]. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat-parts.c.inc | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index b456c1c30c..8a7f22d6b5 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -156,7 +156,13 @@ static void partsN(uncanon_normal)(FloatPartsN *p, flo= at_status *s, switch (s->float_rounding_mode) { case float_round_nearest_even: overflow_norm =3D false; - inc =3D ((p->frac_lo & roundeven_mask) !=3D frac_lsbm1 ? frac_lsbm= 1 : 0); + if (N > 64 && frac_lsb =3D=3D 0) { + inc =3D ((p->frac_hi & 1) || (p->frac_lo & round_mask) !=3D fr= ac_lsbm1 + ? frac_lsbm1 : 0); + } else { + inc =3D ((p->frac_lo & roundeven_mask) !=3D frac_lsbm1 + ? frac_lsbm1 : 0); + } break; case float_round_ties_away: overflow_norm =3D false; @@ -176,7 +182,11 @@ static void partsN(uncanon_normal)(FloatPartsN *p, flo= at_status *s, break; case float_round_to_odd: overflow_norm =3D true; - inc =3D p->frac_lo & frac_lsb ? 0 : round_mask; + if (N > 64 && frac_lsb =3D=3D 0) { + inc =3D p->frac_hi & 1 ? 0 : round_mask; + } else { + inc =3D p->frac_lo & frac_lsb ? 0 : round_mask; + } break; default: g_assert_not_reached(); @@ -191,8 +201,8 @@ static void partsN(uncanon_normal)(FloatPartsN *p, floa= t_status *s, p->frac_hi |=3D DECOMPOSED_IMPLICIT_BIT; exp++; } + p->frac_lo &=3D ~round_mask; } - frac_shr(p, frac_shift); =20 if (fmt->arm_althp) { /* ARM Alt HP eschews Inf and NaN for a wider exponent. */ @@ -201,18 +211,21 @@ static void partsN(uncanon_normal)(FloatPartsN *p, fl= oat_status *s, flags =3D float_flag_invalid; exp =3D exp_max; frac_allones(p); + p->frac_lo &=3D ~round_mask; } } else if (unlikely(exp >=3D exp_max)) { flags |=3D float_flag_overflow | float_flag_inexact; if (overflow_norm) { exp =3D exp_max - 1; frac_allones(p); + p->frac_lo &=3D ~round_mask; } else { p->cls =3D float_class_inf; exp =3D exp_max; frac_clear(p); } } + frac_shr(p, frac_shift); } else if (s->flush_to_zero) { flags |=3D float_flag_output_denormal; p->cls =3D float_class_zero; @@ -232,17 +245,28 @@ static void partsN(uncanon_normal)(FloatPartsN *p, fl= oat_status *s, /* Need to recompute round-to-even/round-to-odd. */ switch (s->float_rounding_mode) { case float_round_nearest_even: - inc =3D ((p->frac_lo & roundeven_mask) !=3D frac_lsbm1 - ? frac_lsbm1 : 0); + if (N > 64 && frac_lsb =3D=3D 0) { + inc =3D ((p->frac_hi & 1) || + (p->frac_lo & round_mask) !=3D frac_lsbm1 + ? frac_lsbm1 : 0); + } else { + inc =3D ((p->frac_lo & roundeven_mask) !=3D frac_lsbm1 + ? frac_lsbm1 : 0); + } break; case float_round_to_odd: - inc =3D p->frac_lo & frac_lsb ? 0 : round_mask; + if (N > 64 && frac_lsb =3D=3D 0) { + inc =3D p->frac_hi & 1 ? 0 : round_mask; + } else { + inc =3D p->frac_lo & frac_lsb ? 0 : round_mask; + } break; default: break; } flags |=3D float_flag_inexact; frac_addi(p, p, inc); + p->frac_lo &=3D ~round_mask; } =20 exp =3D (p->frac_hi & DECOMPOSED_IMPLICIT_BIT) !=3D 0; --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959298; cv=none; d=zohomail.com; s=zohoarc; b=bXEd9STK6yW9oEhOquSYW/7bIibPeTuVe3aYX+CwkTRFkNWaRAnMzvginKLIsqBc92Xj7MnNeyu6xnuMpY1TzqsAjbxGJ/KISxxvv58q6KK1ZqeF5fAQ9tSlz655ZxuUc9ceFYoj5BSSMva4aVwprMJ/B5ITtIcw04CxOI9C7VA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959298; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=v63kiMKs6E/Jl628TTWBVtvYw6v1ob0t2PY/usIP/Gs=; b=HBipmVyfFFFyuRtybeLyQdyAWISfsiGXKu9RaMeEUWjnq4uFRSPNSqPfIKvHykd7S6ljh7qNfRk9oDzENhbukAFyxenlJZLxFyqxlfE4e2tO7nveZmwS3za+Mh1t6J1dVtRLuSVnCgTJVd15FA/Sz1owDIW3hFqKmVP4jxOVXxk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959298516131.7989445651308; Tue, 25 May 2021 09:14:58 -0700 (PDT) Received: from localhost ([::1]:45512 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZhp-0002hp-3j for importer@patchew.org; Tue, 25 May 2021 12:14:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60416) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeS-0001kt-Sr for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:24 -0400 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]:34502) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeK-0006hT-Uy for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:24 -0400 Received: by mail-pf1-x429.google.com with SMTP id q25so5791953pfn.1 for ; Tue, 25 May 2021 08:07:16 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=v63kiMKs6E/Jl628TTWBVtvYw6v1ob0t2PY/usIP/Gs=; b=ZflE1+L1NNcpkfLFYw75f5nGBlGPIqN/rWJsGBF/2F9WoZsPZQ/EWGyaq1udZ8uCQe B4eMUSQu0n1hctcfBsUNt4FA5tHQadUplVsI15M1ejCgD2Tue+Zzj1/U95IsbQavWFGo Ut/xyi+vCGPshD8aQ1Rpl6D6eOobX1fYIiJ8JXEfK03L/S/DotD5goiuIgAiTNriIIal rmF4Pak2Vf/Ee+ajPsVKFEA03UBsQeJxd0ZO965whYA9HOCaQS3VIB11GY9p3OUQ3goN c/f1klnAjaVA9LoKUFpnftCL8etqfDaUkMNamBggUmZesVDOiDMCS8l0V6iPt4elYxz8 Z4dg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=v63kiMKs6E/Jl628TTWBVtvYw6v1ob0t2PY/usIP/Gs=; b=pRm3IkIvX7wu1FheAJf/7Drg8IFBIkbIJ28loR9EDiL7JTQO5SYHbV62bBk7adE26Z 6c/iQW9ZYKLv5YZXOn435ityuWtJx9nEC8CS2/NQ1gHQncGtanh2e8UGI8Vex43PLVzT CHJBwBd1hHxol2RwynTMjLNd/UYmbRBCnefjS2SbANV95y73Q+M7mTUWjD40vKMYw5bg 38iI9ibxlNC7U/35KBJtsOaJ9HuhLyjrJrtHhrDAEmtFNgewr1o3gsNCX0gErHDvQids jgmqlko8CMbgi410gPZyOo78hdJT1Y+bnlqgdTLye98UN/fQoMysX6xzNcbcBEZ/d5HJ wV+w== X-Gm-Message-State: AOAM5303lXx/ztjIiKlE+0OQ32RehfDp+kksyXuutmbx5VAz7+8i7hMT 4v96MO6M4NpQ65czZy/uH8dWZgJoc+Fsjw== X-Google-Smtp-Source: ABdhPJyMJBvblkEShkdpkmW9GYNR+4pyeo7h+4dfBsJ08+ZgM6T08huUPdfO+zxifc9mo8dYIg4qzg== X-Received: by 2002:a05:6a00:1c43:b029:2e4:d188:fe38 with SMTP id s3-20020a056a001c43b02902e4d188fe38mr23056270pfw.20.1621955235337; Tue, 25 May 2021 08:07:15 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 12/28] tests/fp/fp-test: Reverse order of floatx80 precision tests Date: Tue, 25 May 2021 08:06:50 -0700 Message-Id: <20210525150706.294968-13-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::429; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x429.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Many qemu softfloat will check floatx80_rounding_precision even when berkeley testfloat will not. So begin with floatx80_precision_x, so that's the one we use when !FUNC_EFF_ROUNDINGPRECISION. Reviewed-by: Alex Benn=C3=A9e Signed-off-by: Richard Henderson --- tests/fp/fp-test.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c index 1be3a9788a..352dd71c44 100644 --- a/tests/fp/fp-test.c +++ b/tests/fp/fp-test.c @@ -963,16 +963,16 @@ static void QEMU_NORETURN run_test(void) verCases_usesExact =3D !!(attrs & FUNC_ARG_EXACT); =20 for (k =3D 0; k < 3; k++) { - FloatX80RoundPrec qsf_prec80 =3D floatx80_precision_s; - int prec80 =3D 32; + FloatX80RoundPrec qsf_prec80 =3D floatx80_precision_x; + int prec80 =3D 80; int l; =20 if (k =3D=3D 1) { prec80 =3D 64; qsf_prec80 =3D floatx80_precision_d; } else if (k =3D=3D 2) { - prec80 =3D 80; - qsf_prec80 =3D floatx80_precision_x; + prec80 =3D 32; + qsf_prec80 =3D floatx80_precision_s; } =20 verCases_roundingPrecision =3D 0; --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959468; cv=none; d=zohomail.com; s=zohoarc; b=PvGQqxDklbqNrNnl8i8LLZtgl5HRr1SfQPMjgdTPIWZ2UG1SdkPcQIFsLkK/3K4zyQsKSCVPg75vvC3w7sPxEFcvSNVou7Bd6345xEsSZFbO3I4AenXo8ShR5KvapToTaiYoe3LSa/lUSjaX2X0TNjJqMdzM/8CL5eD149ZEjyk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959468; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=rm4zByqo3GfUyLZhPuxawqIm/WAD7fG88RsiMrmqesc=; b=IbmyXwHngimNYofGcnvLqzi+1Wkz/wxvzL0dngvVdML/c85vgzWSCA8Picx2JVlQSlX0+FYlgRKDihUVNwnzWmIodpk6cCIiIrGc6kopWp2kVIvOhdzbBLv+lYYpp59FMU03JlbuSpuU5Oqj7PkrnxgYd/16TSfEfv/4g8G56+Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959468914120.93195948729044; Tue, 25 May 2021 09:17:48 -0700 (PDT) Received: from localhost ([::1]:54640 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZka-0000nC-2k for importer@patchew.org; Tue, 25 May 2021 12:17:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60456) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeU-0001qd-Mz for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:26 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]:51049) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeM-0006hg-2R for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:26 -0400 Received: by mail-pj1-x102e.google.com with SMTP id t11so17030062pjm.0 for ; Tue, 25 May 2021 08:07:16 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rm4zByqo3GfUyLZhPuxawqIm/WAD7fG88RsiMrmqesc=; b=f98KlvBarWe4dX2K3N/EPfKeRzGtYR9/RIOVlcySco35XEplYDJ3Dg5syIoozbWmf3 UBe9uVpKDkz3IkYs0cd3uJnHvSfw3+ZYY3u+JcZDoP+zV98c2N0TROdmKFsbKZUM8shd rEHD5ZQt+zxJ4KY1pSPh7osf3ctur/qz/EERUI/bNk230XK5GAhZv4R7CLzBGy0QVWFA 7s7h6PRvoLn2Lzs9xlNSKAPXHgottrGIrJz0XXyuaW0MQ5wyIIabN13I0vKlpgV/s767 nquRghC31KAqOZQin+qqPX3R0b/KUG0vkELButv3lspWyrIuO5Pq4bQhBP91c7RGtOb5 cFTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rm4zByqo3GfUyLZhPuxawqIm/WAD7fG88RsiMrmqesc=; b=jrHomvQntdfXMl9uXQqQ4CwwOjLpjxG2ly5c5/SoO+bcuI24kjSojzh12lJ44WwN8N nn0X3y9xNMuMONlYRgUrSRK/GXCx9mUKi6UEzLF7rDoAeBTWLb0hawAn/o4sZWycXhpT rNIiokbFsCZEX6SZ7vH1foHchTQCHB7QmxpCz9V8bEuvulyVTCwKbfWW3+svQggjsOCB HBExtS4QJzHlZq0DeMVypNUE1/tzplBp5nMOhQk6ZrYr9FxitsTzjCNtpdXqRWo50baj UwKnyS8u6KDTFNMWtQ3adLhQyS7UUOhz8iaSLcX9Mr1g3Pmyc7XvHHWJ9KT3uTaXV6xh hnHw== X-Gm-Message-State: AOAM5322XBsNoFq+kO8KTd4gOlYHGlwr9q03YhGqC1GX73BFDFYceEZe ai5gFLEaMLeHdFk7DwFu/VDw232ewVl75w== X-Google-Smtp-Source: ABdhPJwQ4Rhl9vlqvRJEXguFGEWW37geHRxM90f6dkFzTNgD/tNNdfKuerYaAdLEtmuUku+sna4BbA== X-Received: by 2002:a17:90b:14cc:: with SMTP id jz12mr31527281pjb.210.1621955236036; Tue, 25 May 2021 08:07:16 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 13/28] softfloat: Convert floatx80_add/sub to FloatParts Date: Tue, 25 May 2021 08:06:51 -0700 Message-Id: <20210525150706.294968-14-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102e; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102e.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Since this is the first such, this includes all of the packing and unpacking routines as well. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 339 +++++++++++++++++++----------------------------- 1 file changed, 136 insertions(+), 203 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index d7477212be..073b0440eb 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -578,14 +578,14 @@ typedef struct { } FloatFmt; =20 /* Expand fields based on the size of exponent and fraction */ -#define FLOAT_PARAMS_(E, F) \ +#define FLOAT_PARAMS_(E) \ .exp_size =3D E, \ .exp_bias =3D ((1 << E) - 1) >> 1, \ - .exp_max =3D (1 << E) - 1, \ - .frac_size =3D F + .exp_max =3D (1 << E) - 1 =20 #define FLOAT_PARAMS(E, F) \ - FLOAT_PARAMS_(E, F), \ + FLOAT_PARAMS_(E), \ + .frac_size =3D F, \ .frac_shift =3D (-F - 1) & 63, \ .round_mask =3D (1ull << ((-F - 1) & 63)) - 1 =20 @@ -614,6 +614,18 @@ static const FloatFmt float128_params =3D { FLOAT_PARAMS(15, 112) }; =20 +#define FLOATX80_PARAMS(R) \ + FLOAT_PARAMS_(15), \ + .frac_size =3D R =3D=3D 64 ? 63 : R, \ + .frac_shift =3D 0, \ + .round_mask =3D R =3D=3D 64 ? -1 : (1ull << ((-R - 1) & 63)) - 1 + +static const FloatFmt floatx80_params[3] =3D { + [floatx80_precision_s] =3D { FLOATX80_PARAMS(23) }, + [floatx80_precision_d] =3D { FLOATX80_PARAMS(52) }, + [floatx80_precision_x] =3D { FLOATX80_PARAMS(64) }, +}; + /* Unpack a float to parts, but do not canonicalize. */ static void unpack_raw64(FloatParts64 *r, const FloatFmt *fmt, uint64_t ra= w) { @@ -648,6 +660,16 @@ static inline void float64_unpack_raw(FloatParts64 *p,= float64 f) unpack_raw64(p, &float64_params, f); } =20 +static void floatx80_unpack_raw(FloatParts128 *p, floatx80 f) +{ + *p =3D (FloatParts128) { + .cls =3D float_class_unclassified, + .sign =3D extract32(f.high, 15, 1), + .exp =3D extract32(f.high, 0, 15), + .frac_hi =3D f.low + }; +} + static void float128_unpack_raw(FloatParts128 *p, float128 f) { const int f_size =3D float128_params.frac_size - 64; @@ -1536,6 +1558,92 @@ static float128 float128_round_pack_canonical(FloatP= arts128 *p, return float128_pack_raw(p); } =20 +/* Returns false if the encoding is invalid. */ +static bool floatx80_unpack_canonical(FloatParts128 *p, floatx80 f, + float_status *s) +{ + /* Ensure rounding precision is set before beginning. */ + switch (s->floatx80_rounding_precision) { + case floatx80_precision_x: + case floatx80_precision_d: + case floatx80_precision_s: + break; + default: + g_assert_not_reached(); + } + + if (unlikely(floatx80_invalid_encoding(f))) { + float_raise(float_flag_invalid, s); + return false; + } + + floatx80_unpack_raw(p, f); + + if (likely(p->exp !=3D floatx80_params[floatx80_precision_x].exp_max))= { + parts_canonicalize(p, s, &floatx80_params[floatx80_precision_x]); + } else { + /* The explicit integer bit is ignored, after invalid checks. */ + p->frac_hi &=3D MAKE_64BIT_MASK(0, 63); + p->cls =3D (p->frac_hi =3D=3D 0 ? float_class_inf + : parts_is_snan_frac(p->frac_hi, s) + ? float_class_snan : float_class_qnan); + } + return true; +} + +static floatx80 floatx80_round_pack_canonical(FloatParts128 *p, + float_status *s) +{ + const FloatFmt *fmt =3D &floatx80_params[s->floatx80_rounding_precisio= n]; + uint64_t frac; + int exp; + + switch (p->cls) { + case float_class_normal: + if (s->floatx80_rounding_precision =3D=3D floatx80_precision_x) { + parts_uncanon_normal(p, s, fmt); + frac =3D p->frac_hi; + exp =3D p->exp; + } else { + FloatParts64 p64; + + p64.sign =3D p->sign; + p64.exp =3D p->exp; + frac_truncjam(&p64, p); + parts_uncanon_normal(&p64, s, fmt); + frac =3D p64.frac; + exp =3D p64.exp; + } + if (exp !=3D fmt->exp_max) { + break; + } + /* rounded to inf -- fall through to set frac correctly */ + + case float_class_inf: + /* x86 and m68k differ in the setting of the integer bit. */ + frac =3D floatx80_infinity_low; + exp =3D fmt->exp_max; + break; + + case float_class_zero: + frac =3D 0; + exp =3D 0; + break; + + case float_class_snan: + case float_class_qnan: + /* NaNs have the integer bit set. */ + frac =3D p->frac_hi | (1ull << 63); + exp =3D fmt->exp_max; + break; + + default: + g_assert_not_reached(); + } + + return packFloatx80(p->sign, exp, frac); +} + /* * Addition and subtraction */ @@ -1725,6 +1833,30 @@ float128 float128_sub(float128 a, float128 b, float_= status *status) return float128_addsub(a, b, status, true); } =20 +static floatx80 QEMU_FLATTEN +floatx80_addsub(floatx80 a, floatx80 b, float_status *status, bool subtrac= t) +{ + FloatParts128 pa, pb, *pr; + + if (!floatx80_unpack_canonical(&pa, a, status) || + !floatx80_unpack_canonical(&pb, b, status)) { + return floatx80_default_nan(status); + } + + pr =3D parts_addsub(&pa, &pb, status, subtract); + return floatx80_round_pack_canonical(pr, status); +} + +floatx80 floatx80_add(floatx80 a, floatx80 b, float_status *status) +{ + return floatx80_addsub(a, b, status, false); +} + +floatx80 floatx80_sub(floatx80 a, floatx80 b, float_status *status) +{ + return floatx80_addsub(a, b, status, true); +} + /* * Multiplication */ @@ -5734,205 +5866,6 @@ floatx80 floatx80_round_to_int(floatx80 a, float_st= atus *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of adding the absolute values of the extended double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is -| negated before being returned. `zSign' is ignored if the result is a Na= N. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, bool zSign, - float_status *status) -{ - int32_t aExp, bExp, zExp; - uint64_t aSig, bSig, zSig0, zSig1; - int32_t expDiff; - - aSig =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - bSig =3D extractFloatx80Frac( b ); - bExp =3D extractFloatx80Exp( b ); - expDiff =3D aExp - bExp; - if ( 0 < expDiff ) { - if ( aExp =3D=3D 0x7FFF ) { - if ((uint64_t)(aSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) --expDiff; - shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); - zExp =3D aExp; - } - else if ( expDiff < 0 ) { - if ( bExp =3D=3D 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return packFloatx80(zSign, - floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp =3D=3D 0 ) ++expDiff; - shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); - zExp =3D bExp; - } - else { - if ( aExp =3D=3D 0x7FFF ) { - if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) { - return propagateFloatx80NaN(a, b, status); - } - return a; - } - zSig1 =3D 0; - zSig0 =3D aSig + bSig; - if ( aExp =3D=3D 0 ) { - if ((aSig | bSig) & UINT64_C(0x8000000000000000) && zSig0 < aS= ig) { - /* At least one of the values is a pseudo-denormal, - * and there is a carry out of the result. */ - zExp =3D 1; - goto shiftRight1; - } - if (zSig0 =3D=3D 0) { - return packFloatx80(zSign, 0, 0); - } - normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 ); - goto roundAndPack; - } - zExp =3D aExp; - goto shiftRight1; - } - zSig0 =3D aSig + bSig; - if ( (int64_t) zSig0 < 0 ) goto roundAndPack; - shiftRight1: - shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); - zSig0 |=3D UINT64_C(0x8000000000000000); - ++zExp; - roundAndPack: - return roundAndPackFloatx80(status->floatx80_rounding_precision, - zSign, zExp, zSig0, zSig1, status); -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of subtracting the absolute values of the extended -| double-precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, bool zSign, - float_status *status) -{ - int32_t aExp, bExp, zExp; - uint64_t aSig, bSig, zSig0, zSig1; - int32_t expDiff; - - aSig =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - bSig =3D extractFloatx80Frac( b ); - bExp =3D extractFloatx80Exp( b ); - expDiff =3D aExp - bExp; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp =3D=3D 0x7FFF ) { - if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) { - return propagateFloatx80NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - if ( aExp =3D=3D 0 ) { - aExp =3D 1; - bExp =3D 1; - } - zSig1 =3D 0; - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloatx80(status->float_rounding_mode =3D=3D float_round_dow= n, 0, 0); - bExpBigger: - if ( bExp =3D=3D 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return packFloatx80(zSign ^ 1, floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp =3D=3D 0 ) ++expDiff; - shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); - bBigger: - sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 ); - zExp =3D bExp; - zSign ^=3D 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp =3D=3D 0x7FFF ) { - if ((uint64_t)(aSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) --expDiff; - shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); - aBigger: - sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 ); - zExp =3D aExp; - normalizeRoundAndPack: - return normalizeRoundAndPackFloatx80(status->floatx80_rounding_precisi= on, - zSign, zExp, zSig0, zSig1, status= ); -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of adding the extended double-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 floatx80_add(floatx80 a, floatx80 b, float_status *status) -{ - bool aSign, bSign; - - if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) { - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - aSign =3D extractFloatx80Sign( a ); - bSign =3D extractFloatx80Sign( b ); - if ( aSign =3D=3D bSign ) { - return addFloatx80Sigs(a, b, aSign, status); - } - else { - return subFloatx80Sigs(a, b, aSign, status); - } - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of subtracting the extended double-precision floating- -| point values `a' and `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 floatx80_sub(floatx80 a, floatx80 b, float_status *status) -{ - bool aSign, bSign; - - if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) { - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - aSign =3D extractFloatx80Sign( a ); - bSign =3D extractFloatx80Sign( b ); - if ( aSign =3D=3D bSign ) { - return subFloatx80Sigs(a, b, aSign, status); - } - else { - return addFloatx80Sigs(a, b, aSign, status); - } - -} - /*------------------------------------------------------------------------= ---- | Returns the result of multiplying the extended double-precision floating- | point values `a' and `b'. The operation is performed according to the --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621960628; cv=none; d=zohomail.com; s=zohoarc; b=P4duWc7ZLV8W8xIuImEonCzNPJAcKohX8lvsqvJboSjehIh56yCC2ytQmWA6CWFWlkpYmWPTO9DqkgFBw9EKKVIZSc4Tuy9MabyzrXYTR2pq80NUEOTwOqw+0NjJNGc2Q5t50x85f+0v9fOc8NZ6vH520QPpIW+TuFUghfR5RDk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621960628; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=2BYof1ybjsIxHUNZfvumVsH9xGhAIK1VpElG81z2ZqA=; b=htW4QWwjD/Wsq6BoxdzUuL+mKJN/SdF5SBUjgApWmvAnM7yOf5CvxDZagFa/nHU0/M2ANMpgVH/bXFeeOkbHfsxrCuKXj8bsrMRSAhcQC/l0t1534SjTalk2mdzUih4GSFPqGE7MgC3hV2YFPxN+hKwjACs/dqHfNr/Xxx6qf90= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 162196062815394.22462308987815; Tue, 25 May 2021 09:37:08 -0700 (PDT) Received: from localhost ([::1]:54082 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla3H-0005k6-43 for importer@patchew.org; Tue, 25 May 2021 12:37:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60524) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYed-0001y8-Cp for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:37 -0400 Received: from mail-pf1-x42c.google.com ([2607:f8b0:4864:20::42c]:34505) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeN-0006iK-DE for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:33 -0400 Received: by mail-pf1-x42c.google.com with SMTP id q25so5792020pfn.1 for ; Tue, 25 May 2021 08:07:17 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2BYof1ybjsIxHUNZfvumVsH9xGhAIK1VpElG81z2ZqA=; b=mfKKUqZv3XHLRQVOUm9AhbVg/jlijc0xkOEXg5xQfsHfXtTqIZ3sY/uydRS0jvtjiD T2b0pdzwrSiY1av82z2pAI+bqRvPEC+if+DuUIrjLWSZhyAhnsUGM6XqpM9lXJa3dQTW vYksNrPyzqrKGK+rJA6lUjwAOMj9yiPDWjayPADvBrq1xnUEGNrNvF1XcIyRukWFM0Yq eJzNtLjm+BPuhkEpx3JnuJdMHPECCdOuujTR5+LRvjigVKDs2yfx3FqomfUBQ6HdX9OQ WagZWz8P3LJOrCFzrxA61n+Fs94GgvXTsNL5FcBJyZ7ig0nGZS19mAGfuOd5VwhuqvbQ J7XQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2BYof1ybjsIxHUNZfvumVsH9xGhAIK1VpElG81z2ZqA=; b=VcdZ9Fp+VWpQ/sdu0CHkG6O2h1hyGfbV1G3ckXtLr/srzQjk7GGYc749f9ZYhlmLPq swWlWh6uxWxjTcWTJmULk5PRQXobb9YZuaLGkXDUr4ZoEwAUQlS+e81+FzagPnNblt72 cIuKEEVQPseqvpUfG7axREvkjNr67TIzOc7amdQqSfm2ugYemge44WQRhC2ovsZVRvZG UkdxDhq+qAunfuemNCbOpXPtuql4wwuM7DN9w6omYspEujouSKwTZbH5tH0zwq0xAJSk GRjLkllq0HHLEF621yxH7b+yHfClwMjwYoounEJt61qOf2qsW2+5UpC3Ih5mNF3az150 uu4Q== X-Gm-Message-State: AOAM531XJRtLLo70sv6lRfAS+WWCgoHFUcUIoWZO0Gxc/MUWUXnsm3n3 9keXwdxme4wT/KGRqWZLZ09u8GtyRtCRzw== X-Google-Smtp-Source: ABdhPJwYJE9qfU1gyDwuN2usBv8rt4Hj0DWtMSuEg9epZs0hbjsaT0w6EJ4oSavJl4Trc2LCh11Lxg== X-Received: by 2002:a62:148e:0:b029:2e4:e5a5:7e33 with SMTP id 136-20020a62148e0000b02902e4e5a57e33mr22350849pfu.9.1621955236880; Tue, 25 May 2021 08:07:16 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 14/28] softfloat: Convert floatx80_mul to FloatParts Date: Tue, 25 May 2021 08:06:52 -0700 Message-Id: <20210525150706.294968-15-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::42c; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42c.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 76 +++++++++---------------------------------------- 1 file changed, 14 insertions(+), 62 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 073b0440eb..2f2d1e50f7 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1944,6 +1944,20 @@ float128_mul(float128 a, float128 b, float_status *s= tatus) return float128_round_pack_canonical(pr, status); } =20 +floatx80 QEMU_FLATTEN +floatx80_mul(floatx80 a, floatx80 b, float_status *status) +{ + FloatParts128 pa, pb, *pr; + + if (!floatx80_unpack_canonical(&pa, a, status) || + !floatx80_unpack_canonical(&pb, b, status)) { + return floatx80_default_nan(status); + } + + pr =3D parts_mul(&pa, &pb, status); + return floatx80_round_pack_canonical(pr, status); +} + /* * Fused multiply-add */ @@ -5866,68 +5880,6 @@ floatx80 floatx80_round_to_int(floatx80 a, float_sta= tus *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of multiplying the extended double-precision floating- -| point values `a' and `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status) -{ - bool aSign, bSign, zSign; - int32_t aExp, bExp, zExp; - uint64_t aSig, bSig, zSig0, zSig1; - - if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) { - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - aSig =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - aSign =3D extractFloatx80Sign( a ); - bSig =3D extractFloatx80Frac( b ); - bExp =3D extractFloatx80Exp( b ); - bSign =3D extractFloatx80Sign( b ); - zSign =3D aSign ^ bSign; - if ( aExp =3D=3D 0x7FFF ) { - if ( (uint64_t) ( aSig<<1 ) - || ( ( bExp =3D=3D 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) { - return propagateFloatx80NaN(a, b, status); - } - if ( ( bExp | bSig ) =3D=3D 0 ) goto invalid; - return packFloatx80(zSign, floatx80_infinity_high, - floatx80_infinity_low); - } - if ( bExp =3D=3D 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - if ( ( aExp | aSig ) =3D=3D 0 ) { - invalid: - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - return packFloatx80(zSign, floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - zExp =3D aExp + bExp - 0x3FFE; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - if ( 0 < (int64_t) zSig0 ) { - shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 ); - --zExp; - } - return roundAndPackFloatx80(status->floatx80_rounding_precision, - zSign, zExp, zSig0, zSig1, status); -} - /*------------------------------------------------------------------------= ---- | Returns the result of dividing the extended double-precision floating-po= int | value `a' by the corresponding value `b'. The operation is performed --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621960337; cv=none; d=zohomail.com; s=zohoarc; b=jIk59YWYvaZitmuKIj6wTTOAaDe/wdfP7KzBCGMj5WmQr3ZAY9qXVNgUA/V2py8WqrbAv2oZtpU5/SOAcx94Hh5vIhmW/23GTDiSEVHp4Swrff31mESrbsVsPoKmRqi0g6A++xZPJFI3StmWkMbdCM1ZhhF+p1Nc2AQv+x7klwA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621960337; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=17lWOhgcl+ZVqAbMQv1xvpusA/TYAXuediZfiyj2D18=; b=UQne9ewuDYwsHHKmXW9jwQnhRYdbivqghZ3ySFwyt+iKPCK3rw2K0wyZ1XxivM6sYLf75562PaMmAQcQEaxYVDYo6z1CrZoFXqkdvUTNj2kWQjkHwCWjbgKLncaKFqIPzv0hh3js12zku/LEgDNjq5LbGeY2FsUoKz+bavSkX0g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621960337463859.9310148056595; Tue, 25 May 2021 09:32:17 -0700 (PDT) Received: from localhost ([::1]:39276 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZyU-0003rw-PR for importer@patchew.org; Tue, 25 May 2021 12:32:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60424) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeT-0001n6-I0 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:25 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]:51050) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeM-0006iN-SB for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:25 -0400 Received: by mail-pj1-x102f.google.com with SMTP id t11so17030105pjm.0 for ; Tue, 25 May 2021 08:07:18 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=17lWOhgcl+ZVqAbMQv1xvpusA/TYAXuediZfiyj2D18=; b=EVauJhgg+KIZPk17DqgyB874sQrsACp2mMAxtsnfz5bLU++Qg26t+GfSdue4aGaSnH RL5D0gZITXCrHzgOdFljXnxE356OTXqXL/UFtEQpyQtL+656P7zVh+/J9bMlY4rGXiou UyFGiN1Sn6CyPFpgVrl2oBpuIFfxk+WazG/aowMpcqQNHKF3KzlkXL659QAUUSMRZ/nM UynMX7J1/K4JkGfSHGGRECIVsBepjd5rSrvLOMQQbxFeI1Iv+kLBB5Of8P0Ji6q3vYmc y+WoUkCuvYKSzSux1LZlfI8MjWmSYJ+mdDL0ypmgsaXVS9rOsAsRXxh6T1KISGnyRA/8 JXIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=17lWOhgcl+ZVqAbMQv1xvpusA/TYAXuediZfiyj2D18=; b=nseNqc5MxH8tocLPmKv7FzEoNL0GY/IFCuzMGcgdMifkhEoqDbxvLPcJ4xYdyOdkmH tMh9pXj0JXFrgDnd9Vx2tP7W8aVA5t2IVbThHOEh2Pd6yCYlC1DWYn5JteXeR9TTStMf 5gHPgaK29NC9tccJaaMi9VSVoYZF9Ue6VftsL0kJv1UrAW4G+SBNr/SSPRoAo3N8gPKZ PpyP094Yfk/1r+4CNNgb5ftq9u351Jzw1ApdO737mE4YQJJoBk8SHEPamRmjeJxh3K2V 1XBAIfxHLGOtUc+/JQVjq1UFuwWRyEGLczqjt+hplLC5ppVWT4fKVU3B/SN5vkzpFFfI wRpw== X-Gm-Message-State: AOAM533+fplAfM1si9k1wbWEGS2Q8zbXvobl6+8F+JMCiC3K/ZAj7p9c DpBeQpnchnyI3YfibBcK6QxpsQaROPW+jw== X-Google-Smtp-Source: ABdhPJxBiC/XyDhmPLZwYvEnMpCY0JxthaaB70oW/1LvRznezMpUm778RjmjDxXNwAmbOZuhvmB9bw== X-Received: by 2002:a17:90b:100f:: with SMTP id gm15mr31364738pjb.197.1621955237454; Tue, 25 May 2021 08:07:17 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 15/28] softfloat: Convert floatx80_div to FloatParts Date: Tue, 25 May 2021 08:06:53 -0700 Message-Id: <20210525150706.294968-16-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102f.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 100 +++++++----------------------------------------- 1 file changed, 13 insertions(+), 87 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 2f2d1e50f7..7b9ae29285 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2294,6 +2294,19 @@ float128_div(float128 a, float128 b, float_status *s= tatus) return float128_round_pack_canonical(pr, status); } =20 +floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status) +{ + FloatParts128 pa, pb, *pr; + + if (!floatx80_unpack_canonical(&pa, a, status) || + !floatx80_unpack_canonical(&pb, b, status)) { + return floatx80_default_nan(status); + } + + pr =3D parts_div(&pa, &pb, status); + return floatx80_round_pack_canonical(pr, status); +} + /* * Float to Float conversions * @@ -5880,93 +5893,6 @@ floatx80 floatx80_round_to_int(floatx80 a, float_sta= tus *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of dividing the extended double-precision floating-po= int -| value `a' by the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status) -{ - bool aSign, bSign, zSign; - int32_t aExp, bExp, zExp; - uint64_t aSig, bSig, zSig0, zSig1; - uint64_t rem0, rem1, rem2, term0, term1, term2; - - if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) { - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - aSig =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - aSign =3D extractFloatx80Sign( a ); - bSig =3D extractFloatx80Frac( b ); - bExp =3D extractFloatx80Exp( b ); - bSign =3D extractFloatx80Sign( b ); - zSign =3D aSign ^ bSign; - if ( aExp =3D=3D 0x7FFF ) { - if ((uint64_t)(aSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - if ( bExp =3D=3D 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - goto invalid; - } - return packFloatx80(zSign, floatx80_infinity_high, - floatx80_infinity_low); - } - if ( bExp =3D=3D 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return packFloatx80( zSign, 0, 0 ); - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) { - if ( ( aExp | aSig ) =3D=3D 0 ) { - invalid: - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - float_raise(float_flag_divbyzero, status); - return packFloatx80(zSign, floatx80_infinity_high, - floatx80_infinity_low); - } - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); - } - zExp =3D aExp - bExp + 0x3FFE; - rem1 =3D 0; - if ( bSig <=3D aSig ) { - shift128Right( aSig, 0, 1, &aSig, &rem1 ); - ++zExp; - } - zSig0 =3D estimateDiv128To64( aSig, rem1, bSig ); - mul64To128( bSig, zSig0, &term0, &term1 ); - sub128( aSig, rem1, term0, term1, &rem0, &rem1 ); - while ( (int64_t) rem0 < 0 ) { - --zSig0; - add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); - } - zSig1 =3D estimateDiv128To64( rem1, 0, bSig ); - if ( (uint64_t) ( zSig1<<1 ) <=3D 8 ) { - mul64To128( bSig, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - while ( (int64_t) rem1 < 0 ) { - --zSig1; - add128( rem1, rem2, 0, bSig, &rem1, &rem2 ); - } - zSig1 |=3D ( ( rem1 | rem2 ) !=3D 0 ); - } - return roundAndPackFloatx80(status->floatx80_rounding_precision, - zSign, zExp, zSig0, zSig1, status); -} - /*------------------------------------------------------------------------= ---- | Returns the remainder of the extended double-precision floating-point va= lue | `a' with respect to the corresponding value `b'. The operation is perfo= rmed --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959640; cv=none; d=zohomail.com; s=zohoarc; b=QwZZRwfOJD42/JCbpWrY53bLO6tJXfcbs1dWuuAoZvWSWJphNiHS32WCFByqbmzFCjdvgq2QuJcd0Tidir262NJ+QxrP/ov3LOF+Z8MjoVbjd/yOUUxRkHVvJX9rI/xJuI2YZhQL1U0VJC8slmnf4FyWhebPbDfJrG5Bbj7aDlU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959640; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=ADKnkvRZV41OR8FpRzBFVdThnPU71bizMrztN5c22yI=; b=gB7BWAMuRz8aw2kuxtiXvDFgNxW5Z6GWCc5rHo4TL7WDyG6JdAT0naiJDVpfFcznJv0oe4SWXOJJJvPSR9hsx5OzMszi9kxDL0CowKaRnwlB4ItBIeqn7YCn2/CGHUJOJsqnejZdnd7S4lyNrrOdFNoRsDhOFhTAVNm4pzF9qUw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959640782339.6987962492942; Tue, 25 May 2021 09:20:40 -0700 (PDT) Received: from localhost ([::1]:35122 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZnM-0006y3-2Y for importer@patchew.org; Tue, 25 May 2021 12:20:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60574) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYei-00023t-8z for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:40 -0400 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]:46819) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeP-0006iX-Vp for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:40 -0400 Received: by mail-pf1-x435.google.com with SMTP id y15so12439736pfn.13 for ; Tue, 25 May 2021 08:07:20 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ADKnkvRZV41OR8FpRzBFVdThnPU71bizMrztN5c22yI=; b=fh0nR8T6S04JkovZwdwvwnxn9n/ZTpNHD1LAfhfHxT2YVdKMeC1AFEFUlm0MNxVBtb X/qSuv2Cq9u5sFgJwJmV+dqTYyuPN5Wbfg6pN3+vh5uoG+p8vRLpWdFGTTZcGv6kA8VL V8HkgOv63mNZU1EfJSJV6lpMCrJQHvIAkxgRoB/xz9aA5mJeRCcdls8s38llmH98d/Cu zh1/r3nNSUsSsGekC6Ki23PUTST/M81oZWLercPgtBgA69KlMf8dKQ7gDVZJg7mrGzkl e+q4pVcmEHCdXuhFoFSsQUjPOfAFDkkfH3ECokPJEGlX6KsQATn9npdCkA+mck1w8QYY TA9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ADKnkvRZV41OR8FpRzBFVdThnPU71bizMrztN5c22yI=; b=h72tgeO7yYN72aeHSq+XA7fhWUEQ0jnJLG3D0YbwwjJLyW6pdzrqdEMKR2kJqIwrlV W59r42BatFpXuGIC4q0AOnnTuwXhICIi2c7HtztcJW9kax/9dRJQlouXsrN5TDpm51Zm zKCK0V5UO5CJglm83phv0/3CkeLy40JUsDvOL30fOMmGDPimlBZkjsQy568aIh+NkVot tnC6l5PQUADEn0ocJ/juJOo9K4TdcXJX4+lwxxRrQ9TkrotMbcxYskvbdVpXZrT5NQCr pvSuUtgvoKfobuAiNr1whSyNyOhNsxMV7j/dSgKRZWjPMQvL/0cJ9r1EpTDThSuCCSLf sRkQ== X-Gm-Message-State: AOAM533jlX580VA9/0HUu94hpJkIvvtnEsnMlr/xUQSYFP5b81y7nsJU dUcME/W+IGXAlBwpp/avNHJunAKeOa5oJg== X-Google-Smtp-Source: ABdhPJzRx0x8UsxwEC6+yMgLcnrJM1mSpTaDpoJOP4dFQ9LLNb+LtGGpkcHNooDQK9hGFOKQXwABKw== X-Received: by 2002:a63:9316:: with SMTP id b22mr19865846pge.70.1621955237991; Tue, 25 May 2021 08:07:17 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 16/28] softfloat: Convert floatx80_sqrt to FloatParts Date: Tue, 25 May 2021 08:06:54 -0700 Message-Id: <20210525150706.294968-17-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::435; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x435.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 82 +++++++------------------------------------------ 1 file changed, 11 insertions(+), 71 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 7b9ae29285..d7beb27982 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3884,6 +3884,17 @@ float128 QEMU_FLATTEN float128_sqrt(float128 a, floa= t_status *status) return float128_round_pack_canonical(&p, status); } =20 +floatx80 floatx80_sqrt(floatx80 a, float_status *s) +{ + FloatParts128 p; + + if (!floatx80_unpack_canonical(&p, a, s)) { + return floatx80_default_nan(s); + } + parts_sqrt(&p, s, &floatx80_params[s->floatx80_rounding_precision]); + return floatx80_round_pack_canonical(&p, s); +} + /*------------------------------------------------------------------------= ---- | The pattern for a default generated NaN. *-------------------------------------------------------------------------= ---*/ @@ -6047,77 +6058,6 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_= status *status) return floatx80_modrem(a, b, true, "ient, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the square root of the extended double-precision floating-point -| value `a'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 floatx80_sqrt(floatx80 a, float_status *status) -{ - bool aSign; - int32_t aExp, zExp; - uint64_t aSig0, aSig1, zSig0, zSig1, doubleZSig0; - uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3; - - if (floatx80_invalid_encoding(a)) { - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - aSig0 =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - aSign =3D extractFloatx80Sign( a ); - if ( aExp =3D=3D 0x7FFF ) { - if ((uint64_t)(aSig0 << 1)) { - return propagateFloatx80NaN(a, a, status); - } - if ( ! aSign ) return a; - goto invalid; - } - if ( aSign ) { - if ( ( aExp | aSig0 ) =3D=3D 0 ) return a; - invalid: - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - if ( aExp =3D=3D 0 ) { - if ( aSig0 =3D=3D 0 ) return packFloatx80( 0, 0, 0 ); - normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); - } - zExp =3D ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; - zSig0 =3D estimateSqrt32( aExp, aSig0>>32 ); - shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 ); - zSig0 =3D estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 = ); - doubleZSig0 =3D zSig0<<1; - mul64To128( zSig0, zSig0, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (int64_t) rem0 < 0 ) { - --zSig0; - doubleZSig0 -=3D 2; - add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); - } - zSig1 =3D estimateDiv128To64( rem1, 0, doubleZSig0 ); - if ( ( zSig1 & UINT64_C(0x3FFFFFFFFFFFFFFF) ) <=3D 5 ) { - if ( zSig1 =3D=3D 0 ) zSig1 =3D 1; - mul64To128( doubleZSig0, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - mul64To128( zSig1, zSig1, &term2, &term3 ); - sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); - while ( (int64_t) rem1 < 0 ) { - --zSig1; - shortShift128Left( 0, zSig1, 1, &term2, &term3 ); - term3 |=3D 1; - term2 |=3D doubleZSig0; - add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3= ); - } - zSig1 |=3D ( ( rem1 | rem2 | rem3 ) !=3D 0 ); - } - shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 ); - zSig0 |=3D doubleZSig0; - return roundAndPackFloatx80(status->floatx80_rounding_precision, - 0, zExp, zSig0, zSig1, status); -} - /*------------------------------------------------------------------------= ---- | Returns the result of converting the quadruple-precision floating-point | value `a' to the extended double-precision floating-point format. The --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959273; cv=none; d=zohomail.com; s=zohoarc; b=Ai82tAUXZbi5RKNIAkH13hr3zOuFCrOrYTV5sKHxB2kEGD/hmiOLJSAa3K3tPXbb48zYYdQ4ujEhr2MKrEzaCSlMuLfkwGby3yEAspmdeWJ+pcczhcC7s4hQvg65jDYLhUUlvz6aYG9bqb424AHcScA6H6BocQP7JS/HR8A3uNQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959273; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=eShFDpUU2i7h7h2qJCMIyadlLFYSgvTlWNlSA4tKpjQ=; b=C7lsyaNlScHHA7LW2wBiqqnxK6tNfTFpularPUmYh93rOrbxkUUBelmTvY9BN34HihadtQ4n6KP/b2/9hcLu48uuVrFtF4PsGljaM03Moj2eDvbFH3PW3RxDyXMNhhsVwETIPNppRFqihyPYltZnvKFFecto/jao51TkqrIHLo0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959273486627.5155960907069; Tue, 25 May 2021 09:14:33 -0700 (PDT) Received: from localhost ([::1]:44634 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZhQ-00022k-0A for importer@patchew.org; Tue, 25 May 2021 12:14:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60492) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeb-0001vf-0h for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:33 -0400 Received: from mail-pf1-x42d.google.com ([2607:f8b0:4864:20::42d]:40496) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeP-0006iw-M1 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:32 -0400 Received: by mail-pf1-x42d.google.com with SMTP id x188so23833633pfd.7 for ; Tue, 25 May 2021 08:07:19 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eShFDpUU2i7h7h2qJCMIyadlLFYSgvTlWNlSA4tKpjQ=; b=JD4frM17eA0L6XmHj72nPg82VKQiJe8SOtDPh8Ai3hy+3d+99PiAu2FnbCIOqdEoks 4hZOhBpKeW81ZjYVStZ0MoZAy9ibhF4+AoCxqmP0V4Ao0+ZJ52C+xP27U1x0SmbhTMiV n4GqiUMaCI4tNrsm57NwL1puj8qJ0KXlRu0f4wDPLKVBhBmBRtkBWuH2ibPxvhgANyEL aq5qtkCHDpFH0yZXA+/mJORs/Gs4LizbQkbz7VOER7jYGsCyfnV1M+DauQu0Sp2utQOp f3+yxvUWvU0dLnVYCGhzxcrIX8ZRy2qvnLhqmC2fS/iVbFY8bOV78QLf8tiuUkScyFSl +YUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eShFDpUU2i7h7h2qJCMIyadlLFYSgvTlWNlSA4tKpjQ=; b=H8udtCFSTIUAHX7C9OeSj1lhJUu9iDr3Tb2vJpKU+sMPjYxFgY2b0CjkdWvuIT9gxC JEbCL3iIhEj87QDC65IPNiXy/dnZoiez9QYu0SUJ8KgFxKSZBK7cfvvTI1oxZkZ6ZoB2 FcKgf+A4EAnLe3mAZLyvwi/3goi7SE9b2X5i1w+spPWplg1FJ5bNy92RhfACmEdjIIwm 2DPSP9LxcYVwOJOYZoD59ZGg57H3uGkaR5dSS5VyhOXuIhcM4E/ZZb4sfR2kWJxLjT78 DKTh7mg8rGm9u8UgUvkv2XjlyfI/klk8W+I2oebeBpkaqyNmAd/0dhNj+xbo+TOROEUe 7qxA== X-Gm-Message-State: AOAM532lfd2CHTosFidld6PtlLmLFrR0oWpDkJqMmUV/f5zy1HVs/93G 20P1c3b9vm2aZgYEHUh369jqC6vxf1q7YA== X-Google-Smtp-Source: ABdhPJwtuF4aPsILG0UhMxuAdIfjp4DoDPmRJ2rrGENAbH5bj+g7/lXkGXvr6vYtPx/0FX6FZ0+hgg== X-Received: by 2002:a63:1559:: with SMTP id 25mr16141721pgv.384.1621955238532; Tue, 25 May 2021 08:07:18 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 17/28] softfloat: Convert floatx80_round to FloatParts Date: Tue, 25 May 2021 08:06:55 -0700 Message-Id: <20210525150706.294968-18-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::42d; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42d.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index d7beb27982..1f7260caec 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -5795,10 +5795,12 @@ float128 floatx80_to_float128(floatx80 a, float_sta= tus *status) =20 floatx80 floatx80_round(floatx80 a, float_status *status) { - return roundAndPackFloatx80(status->floatx80_rounding_precision, - extractFloatx80Sign(a), - extractFloatx80Exp(a), - extractFloatx80Frac(a), 0, status); + FloatParts128 p; + + if (!floatx80_unpack_canonical(&p, a, status)) { + return floatx80_default_nan(status); + } + return floatx80_round_pack_canonical(&p, status); } =20 /*------------------------------------------------------------------------= ---- --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621960479; cv=none; d=zohomail.com; s=zohoarc; b=him5Sjdf2W9YrZafDPfUQM4BsMrgoosmtD40HbXv1AHTED+f5EZM9xaF/pPl6mH7EMcUR7ci1omus6jec/gnE7QqHteBLJQ9W7gcXltt6AU7DRNuyHXdJn9q0TpwHNBAMrXAnWmI7YDxsaQfBse8Ea7HPK/gJT0fPXNy9pFN+9Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621960479; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=jRtuMx867iiF9LnMJh9kaoCKipyhalwdeBb7t+R/rbM=; b=QI0WB8Qhdf75/QhZC+DzGcPr5SJFCEonFqM6Yu17k2g05nObAmL6LsPuFuv+858+DpSnDp1/qsID7iPS+o+VXR+vrA/87f+GVtBpNjg3lOr5PPO2UIqinYNyPRD7NeqMGzABtzwllQyjl0oxTL7cssZKZTTL74VYFksKqo9M22I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621960479831529.8099248090188; Tue, 25 May 2021 09:34:39 -0700 (PDT) Received: from localhost ([::1]:45730 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla0s-0008JP-QR for importer@patchew.org; Tue, 25 May 2021 12:34:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60530) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYee-0001y9-1V for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:37 -0400 Received: from mail-pg1-x531.google.com ([2607:f8b0:4864:20::531]:43812) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0006jM-0P for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:35 -0400 Received: by mail-pg1-x531.google.com with SMTP id e22so7229707pgv.10 for ; Tue, 25 May 2021 08:07:20 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jRtuMx867iiF9LnMJh9kaoCKipyhalwdeBb7t+R/rbM=; b=Kmy2FyQhJXUlQH1RDfhnjYgU/XNv8JAVpeMeD+l3H+4s647y2BhRIUFXXOZbRS4Evb L0iEGhsI3oBYbLXn2PSECdNqmuyhyDrQR5t4mhYAr9kopa3wp3+jqkMmxP4jQ3nYV2SE dc/Vij28uGnFlaggkyBm2c+JbUE3L5aq3i2mzqc12JemOCOJwIVjn1N9r0gPcuvlVGf+ xow1KadOkSAjBm68P7MNGlJdelbFdtQnqHFhfFiECJUXP3o8qwZw9JqQhMXKcVIQFRHZ e1C9EBf7WCJmv81IXzLygejxCD1gkbiH7dG1L6FCCfDWCpwI9cSatTUQu/MwwKbr1VrK Yucw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jRtuMx867iiF9LnMJh9kaoCKipyhalwdeBb7t+R/rbM=; b=ZjjDBG4fBeTk3jBg28CRbENJYaRW8QvokaKa0V+oVy+4hILbysyox3Ct9qEKb/Lqvq ZbYcZ4D4jcQF5nVZFzmvybF9mEzfMB/EtHaXb9hJ9bkN7wVkKCl85x0rT5jNheFIk1tZ hNARNhDMBejbZSL7MsUCglG832xCK5uFnZ8E1MOlDDn20gXJxTaJyeY1fDER7Ky85js9 Df+bRnC3Dg3D50IwAF6uhNkysTSXFboy11zh69EYo28l6PHtMP7ew0q3d2P666Bux4YT 8jYs/8ZuRck7MBZFyzU3UVWyxnYIYfHoe7E+QNuBCqrYKt3w6kwF21vccoKe+Uy8pLG+ dJVA== X-Gm-Message-State: AOAM532N6nQ0mUZN+5f+zDyXof7ggYS5fiRKYx3URc4+BBl5VhBnEk5n OtjtTtnFQQObyDzZNL8NHw3S9Yn6FUdq+g== X-Google-Smtp-Source: ABdhPJzLlP/0H4/HqV8L1Y88/S5eOoLMHPcBv36b+TQc39yP76VzVfzJWpZOAz44qDhwKVDrjAElBQ== X-Received: by 2002:a63:5052:: with SMTP id q18mr19338140pgl.349.1621955239085; Tue, 25 May 2021 08:07:19 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 18/28] softfloat: Convert floatx80_round_to_int to FloatParts Date: Tue, 25 May 2021 08:06:56 -0700 Message-Id: <20210525150706.294968-19-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::531; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x531.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 116 ++++++------------------------------------------ 1 file changed, 13 insertions(+), 103 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 1f7260caec..5c4a32bcfc 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2610,6 +2610,19 @@ float128 float128_round_to_int(float128 a, float_sta= tus *s) return float128_round_pack_canonical(&p, s); } =20 +floatx80 floatx80_round_to_int(floatx80 a, float_status *status) +{ + FloatParts128 p; + + if (!floatx80_unpack_canonical(&p, a, status)) { + return floatx80_default_nan(status); + } + + parts_round_to_int(&p, status->float_rounding_mode, 0, status, + &floatx80_params[status->floatx80_rounding_precisio= n]); + return floatx80_round_pack_canonical(&p, status); +} + /* * Floating-point to signed integer conversions */ @@ -5803,109 +5816,6 @@ floatx80 floatx80_round(floatx80 a, float_status *s= tatus) return floatx80_round_pack_canonical(&p, status); } =20 -/*------------------------------------------------------------------------= ---- -| Rounds the extended double-precision floating-point value `a' to an inte= ger, -| and returns the result as an extended quadruple-precision floating-point -| value. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 floatx80_round_to_int(floatx80 a, float_status *status) -{ - bool aSign; - int32_t aExp; - uint64_t lastBitMask, roundBitsMask; - floatx80 z; - - if (floatx80_invalid_encoding(a)) { - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - aExp =3D extractFloatx80Exp( a ); - if ( 0x403E <=3D aExp ) { - if ( ( aExp =3D=3D 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a= )<<1 ) ) { - return propagateFloatx80NaN(a, a, status); - } - return a; - } - if ( aExp < 0x3FFF ) { - if ( ( aExp =3D=3D 0 ) - && ( (uint64_t) ( extractFloatx80Frac( a ) ) =3D=3D 0 ) ) { - return a; - } - float_raise(float_flag_inexact, status); - aSign =3D extractFloatx80Sign( a ); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - if ( ( aExp =3D=3D 0x3FFE ) && (uint64_t) ( extractFloatx80Fra= c( a )<<1 ) - ) { - return - packFloatx80( aSign, 0x3FFF, UINT64_C(0x80000000000000= 00)); - } - break; - case float_round_ties_away: - if (aExp =3D=3D 0x3FFE) { - return packFloatx80(aSign, 0x3FFF, UINT64_C(0x800000000000= 0000)); - } - break; - case float_round_down: - return - aSign ? - packFloatx80( 1, 0x3FFF, UINT64_C(0x8000000000000000= )) - : packFloatx80( 0, 0, 0 ); - case float_round_up: - return - aSign ? packFloatx80( 1, 0, 0 ) - : packFloatx80( 0, 0x3FFF, UINT64_C(0x8000000000000000)); - - case float_round_to_zero: - break; - default: - g_assert_not_reached(); - } - return packFloatx80( aSign, 0, 0 ); - } - lastBitMask =3D 1; - lastBitMask <<=3D 0x403E - aExp; - roundBitsMask =3D lastBitMask - 1; - z =3D a; - switch (status->float_rounding_mode) { - case float_round_nearest_even: - z.low +=3D lastBitMask>>1; - if ((z.low & roundBitsMask) =3D=3D 0) { - z.low &=3D ~lastBitMask; - } - break; - case float_round_ties_away: - z.low +=3D lastBitMask >> 1; - break; - case float_round_to_zero: - break; - case float_round_up: - if (!extractFloatx80Sign(z)) { - z.low +=3D roundBitsMask; - } - break; - case float_round_down: - if (extractFloatx80Sign(z)) { - z.low +=3D roundBitsMask; - } - break; - default: - abort(); - } - z.low &=3D ~ roundBitsMask; - if ( z.low =3D=3D 0 ) { - ++z.high; - z.low =3D UINT64_C(0x8000000000000000); - } - if (z.low !=3D a.low) { - float_raise(float_flag_inexact, status); - } - return z; - -} - /*------------------------------------------------------------------------= ---- | Returns the remainder of the extended double-precision floating-point va= lue | `a' with respect to the corresponding value `b'. The operation is perfo= rmed --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959630; cv=none; d=zohomail.com; s=zohoarc; b=CSoTx7UyqhTACX3BHbOVTKRBIXr0YkiCfNX8zreyIUV5cSjFXiboPExkEtQlvFrkQ10rZNB7tWzSEka50vDX65GL3CFI3KI7B9W3xMCN4TcDWcP/sqqAtnEq8hRq4GDmqPCafNdqXszUDxYeN/zRdStnB9MIHKdtb+YLCl/X33s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959630; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=8jY2SfyYuHl84ybtoNE2cXZQw+chD95nctKoUYm9stI=; b=CjoMU0os3/gFrOS1JRk0s5gxzb7Y3So269WswN6Q0K6DkEIWQanSOXYgtUH8dRAIeHkAGw01b0GhRZ/0h6+ZeNUyLOgLcd8yTa5L4nApix3dr+QjOztdhlWbjR+NIG/AKkkm8BTb2/+dqu+DB6KyX1ipPA1flUZtSDiQKajZoI4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959630181639.9669442915523; Tue, 25 May 2021 09:20:30 -0700 (PDT) Received: from localhost ([::1]:34116 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZnB-0006Ha-B9 for importer@patchew.org; Tue, 25 May 2021 12:20:29 -0400 Received: from [2001:470:142:3::10] (port=60600 helo=eggs.gnu.org) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYem-0002Bw-Mm for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:45 -0400 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]:52803) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0006jx-3u for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:40 -0400 Received: by mail-pj1-x102b.google.com with SMTP id q6so17013777pjj.2 for ; Tue, 25 May 2021 08:07:21 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8jY2SfyYuHl84ybtoNE2cXZQw+chD95nctKoUYm9stI=; b=bQUqS0vOqDw3/LR9evNJ6tnnltvDc3sAkbLafYw8eF1qKCOi15miBhJ+oOj60fUyG2 MM8oiwniIG0jW7PtRMXJ10dsxaepCMyR1XpPYa2JLoD//UJToOrBpMdBdrChGefcE5cw nAIImZXlWbOUKBe42SAOIF9TPQG6o693NFZQjoAUIco/+/czYXTjbKJfYEpjqbAw+Ju+ uUQij3hCQH6UvKemxKTyU4vwfDnulXC/EK6SIPwB6tpLhNTXO3zyrJ2vbRjlOj4tV4Ew uOC2ES+1/XrDrYUDY951Xc7zDz51sqM7MLj+02lfxOS96Z8f9K8fBKETsyt1cedyUHaE rDrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8jY2SfyYuHl84ybtoNE2cXZQw+chD95nctKoUYm9stI=; b=umI2AhSkzloaueW9Ju7f1ASCO2XhsJBtiSxYCSRZnGD606tCISDMAIpqv0cQTwNT09 QHEFC8cmH9HyMCPzYZFFVjyPvxH2sGx5cQffe1fK6nfVsh1hAl3Ble5zLjlmuNpKTsu4 hEf+p1bIF2f3NA1IWK1bd6GchL/2yd+Zh6JpHDU4VMOxIPGAlcaP3LLJ3cl7imaiAMGJ tzYIjeWi3VCtZaKVJ+jWsThXuz4dPzvRJRLuQqLtZUzHBBiSEX8DB2cAaDvDbJxDvRKF MxutN2Osd6d1f+Ka+bY5Wwb7Bdg0DtVIPtyZ3BmLCz7oGlZ945YH6WHQmg36gRLaQg8E xT4g== X-Gm-Message-State: AOAM532zXIeEGWaNAi/2iqLJ4tMewE3EaNUJsApuwf+4lwGIP5Ots6Bh IZSWvB287kSarOALt81g5Yr4KniYDhZUUw== X-Google-Smtp-Source: ABdhPJxhiXCOjbIigPtQd6RczVu/RZIOY8BBUoEHWa9rRcT6hz+hW8ntMkGX/B27yX5OpfY+e3IGpw== X-Received: by 2002:a17:90b:194b:: with SMTP id nk11mr30006284pjb.42.1621955239684; Tue, 25 May 2021 08:07:19 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 19/28] softfloat: Convert integer to floatx80 to FloatParts Date: Tue, 25 May 2021 08:06:57 -0700 Message-Id: <20210525150706.294968-20-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102b; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102b.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 58 +++++++++++-------------------------------------- 1 file changed, 13 insertions(+), 45 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 5c4a32bcfc..1cccc40db5 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3345,6 +3345,19 @@ float128 int32_to_float128(int32_t a, float_status *= status) return int64_to_float128(a, status); } =20 +floatx80 int64_to_floatx80(int64_t a, float_status *status) +{ + FloatParts128 p; + + parts_sint_to_float(&p, a, 0, status); + return floatx80_round_pack_canonical(&p, status); +} + +floatx80 int32_to_floatx80(int32_t a, float_status *status) +{ + return int64_to_floatx80(a, status); +} + /* * Unsigned Integer to floating-point conversions */ @@ -5036,51 +5049,6 @@ static float128 normalizeRoundAndPackFloat128(bool z= Sign, int32_t zExp, =20 } =20 - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the extended double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 int32_to_floatx80(int32_t a, float_status *status) -{ - bool zSign; - uint32_t absA; - int8_t shiftCount; - uint64_t zSig; - - if ( a =3D=3D 0 ) return packFloatx80( 0, 0, 0 ); - zSign =3D ( a < 0 ); - absA =3D zSign ? - a : a; - shiftCount =3D clz32(absA) + 32; - zSig =3D absA; - return packFloatx80( zSign, 0x403E - shiftCount, zSig< (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621960746645900.2713602366784; Tue, 25 May 2021 09:39:06 -0700 (PDT) Received: from localhost ([::1]:59372 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla5B-00014N-Ci for importer@patchew.org; Tue, 25 May 2021 12:39:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60564) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeh-00022P-Tz for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:39 -0400 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]:45877) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0006kP-EB for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:39 -0400 Received: by mail-pf1-x429.google.com with SMTP id d16so23817125pfn.12 for ; Tue, 25 May 2021 08:07:21 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yypiJKlNYeqtvvcjyGW3K32R1pv456DwhxaXAo9XzRI=; b=AtBXvt5DPAnpkqN4NqH48qf61nydZtbEJEGt6CKlT/0Ee1sgF8khEQyDRe9GIQkHVk YinKvandR2K7JG8RHZBloUaTarXI8jNumYT5PKkNujVaLfC/2bU/lBBGkFg80ih5H+32 s2UJO0PZpSIHLxZRSiDYTSnYlmFJ5G5GYMhwPYGshZ2OrPjsE4aPldAkl3WoofGJ2NFi BSkwd5LwP8LlS9TDAPB+9wcpAKDjwmBgJpTxVJYhQLnkEd7RYZOTcrFiWPDYW0OabD1e TGbsv4X+UJEi7Pm7lE+OtGhgf8BrowNIQv5u0YP7WguROJlcCX8JOFkaNg/qifUStPwC h29A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yypiJKlNYeqtvvcjyGW3K32R1pv456DwhxaXAo9XzRI=; b=l3v9mkycos3JF1SNw8/3YgZEjvfeLAE7ByMnwPfkiV2wC+hEg3R3rWrRx/XvRRl6Ui EFx/ZEvveQhn/Cz4uPFybmBlzq99AEQ6AkuyzxMeEN5lUklnQ8cHD0g5QNK7XbpaBCAz A7yt8adBX1oiClM4o7djsWqNpvhZTbRx8sIKeJDDSAWkBwCe93HXpWpRHDtVz7Dv3Ubr WMaahiKPBf1fNvPdEfPmt8WeRakLmLs6mpjJfLa9/cpl4YjYK2mWcEjZDsiFxL+gHpPG qcAEJadLHVK//w32a/VW2h/ldal6h5eqCNonTDHBntBgN2nnMFyXG1ARcU/LrQFOHTPx jATQ== X-Gm-Message-State: AOAM533x/54VMtYNNGYz+TDn8O23XVu1Kb49LpuV927I+qqoFzm9GxHZ dw48UHOcWs4z0mXvakgZXcu5NN6wjUCecA== X-Google-Smtp-Source: ABdhPJx0uEp3l3Wn6JRcO/FXxqivMiJgxjI4auQak4liUm/olAS47eSu97dqnnVgj6mu2dAWuALNFQ== X-Received: by 2002:a63:ff25:: with SMTP id k37mr19298321pgi.360.1621955240368; Tue, 25 May 2021 08:07:20 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 20/28] softfloat: Convert floatx80 float conversions to FloatParts Date: Tue, 25 May 2021 08:06:58 -0700 Message-Id: <20210525150706.294968-21-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::429; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x429.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" This is the last use of commonNaNT and all of the routines that use it, so remove all of them for Werror. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 276 ++++++++------------------------- fpu/softfloat-specialize.c.inc | 175 --------------------- 2 files changed, 67 insertions(+), 384 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 1cccc40db5..435be2a0bf 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2561,6 +2561,73 @@ float128 float64_to_float128(float64 a, float_status= *s) return float128_round_pack_canonical(&p128, s); } =20 +float32 floatx80_to_float32(floatx80 a, float_status *s) +{ + FloatParts64 p64; + FloatParts128 p128; + + if (floatx80_unpack_canonical(&p128, a, s)) { + parts_float_to_float_narrow(&p64, &p128, s); + } else { + parts_default_nan(&p64, s); + } + return float32_round_pack_canonical(&p64, s); +} + +float64 floatx80_to_float64(floatx80 a, float_status *s) +{ + FloatParts64 p64; + FloatParts128 p128; + + if (floatx80_unpack_canonical(&p128, a, s)) { + parts_float_to_float_narrow(&p64, &p128, s); + } else { + parts_default_nan(&p64, s); + } + return float64_round_pack_canonical(&p64, s); +} + +float128 floatx80_to_float128(floatx80 a, float_status *s) +{ + FloatParts128 p; + + if (floatx80_unpack_canonical(&p, a, s)) { + parts_float_to_float(&p, s); + } else { + parts_default_nan(&p, s); + } + return float128_round_pack_canonical(&p, s); +} + +floatx80 float32_to_floatx80(float32 a, float_status *s) +{ + FloatParts64 p64; + FloatParts128 p128; + + float32_unpack_canonical(&p64, a, s); + parts_float_to_float_widen(&p128, &p64, s); + return floatx80_round_pack_canonical(&p128, s); +} + +floatx80 float64_to_floatx80(float64 a, float_status *s) +{ + FloatParts64 p64; + FloatParts128 p128; + + float64_unpack_canonical(&p64, a, s); + parts_float_to_float_widen(&p128, &p64, s); + return floatx80_round_pack_canonical(&p128, s); +} + +floatx80 float128_to_floatx80(float128 a, float_status *s) +{ + FloatParts128 p; + + float128_unpack_canonical(&p, a, s); + parts_float_to_float(&p, s); + return floatx80_round_pack_canonical(&p, s); +} + /* * Round to integral value */ @@ -5049,42 +5116,6 @@ static float128 normalizeRoundAndPackFloat128(bool z= Sign, int32_t zExp, =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the extended double-precision floating-point format. The convers= ion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 float32_to_floatx80(float32 a, float_status *status) -{ - bool aSign; - int aExp; - uint32_t aSig; - - a =3D float32_squash_input_denormal(a, status); - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - if ( aExp =3D=3D 0xFF ) { - if (aSig) { - floatx80 res =3D commonNaNToFloatx80(float32ToCommonNaN(a, sta= tus), - status); - return floatx80_silence_nan(res, status); - } - return packFloatx80(aSign, - floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - aSig |=3D 0x00800000; - return packFloatx80( aSign, aExp + 0x3F80, ( (uint64_t) aSig )<<40 ); - -} - /*------------------------------------------------------------------------= ---- | Returns the remainder of the single-precision floating-point value `a' | with respect to the corresponding value `b'. The operation is performed @@ -5321,43 +5352,6 @@ float32 float32_log2(float32 a, float_status *status) return normalizeRoundAndPackFloat32(zSign, 0x85, zSig, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the extended double-precision floating-point format. The convers= ion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 float64_to_floatx80(float64 a, float_status *status) -{ - bool aSign; - int aExp; - uint64_t aSig; - - a =3D float64_squash_input_denormal(a, status); - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( aExp =3D=3D 0x7FF ) { - if (aSig) { - floatx80 res =3D commonNaNToFloatx80(float64ToCommonNaN(a, sta= tus), - status); - return floatx80_silence_nan(res, status); - } - return packFloatx80(aSign, - floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - return - packFloatx80( - aSign, aExp + 0x3C00, (aSig | UINT64_C(0x0010000000000000)) <<= 11); - -} - /*------------------------------------------------------------------------= ---- | Returns the remainder of the double-precision floating-point value `a' | with respect to the corresponding value `b'. The operation is performed @@ -5668,104 +5662,6 @@ int64_t floatx80_to_int64_round_to_zero(floatx80 a,= float_status *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the single-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 floatx80_to_float32(floatx80 a, float_status *status) -{ - bool aSign; - int32_t aExp; - uint64_t aSig; - - if (floatx80_invalid_encoding(a)) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - aSig =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - aSign =3D extractFloatx80Sign( a ); - if ( aExp =3D=3D 0x7FFF ) { - if ( (uint64_t) ( aSig<<1 ) ) { - float32 res =3D commonNaNToFloat32(floatx80ToCommonNaN(a, stat= us), - status); - return float32_silence_nan(res, status); - } - return packFloat32( aSign, 0xFF, 0 ); - } - shift64RightJamming( aSig, 33, &aSig ); - if ( aExp || aSig ) aExp -=3D 0x3F81; - return roundAndPackFloat32(aSign, aExp, aSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 floatx80_to_float64(floatx80 a, float_status *status) -{ - bool aSign; - int32_t aExp; - uint64_t aSig, zSig; - - if (floatx80_invalid_encoding(a)) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - aSig =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - aSign =3D extractFloatx80Sign( a ); - if ( aExp =3D=3D 0x7FFF ) { - if ( (uint64_t) ( aSig<<1 ) ) { - float64 res =3D commonNaNToFloat64(floatx80ToCommonNaN(a, stat= us), - status); - return float64_silence_nan(res, status); - } - return packFloat64( aSign, 0x7FF, 0 ); - } - shift64RightJamming( aSig, 1, &zSig ); - if ( aExp || aSig ) aExp -=3D 0x3C01; - return roundAndPackFloat64(aSign, aExp, zSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the quadruple-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float128 floatx80_to_float128(floatx80 a, float_status *status) -{ - bool aSign; - int aExp; - uint64_t aSig, zSig0, zSig1; - - if (floatx80_invalid_encoding(a)) { - float_raise(float_flag_invalid, status); - return float128_default_nan(status); - } - aSig =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - aSign =3D extractFloatx80Sign( a ); - if ( ( aExp =3D=3D 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) { - float128 res =3D commonNaNToFloat128(floatx80ToCommonNaN(a, status= ), - status); - return float128_silence_nan(res, status); - } - shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 ); - return packFloat128( aSign, aExp, zSig0, zSig1 ); - -} - /*------------------------------------------------------------------------= ---- | Rounds the extended double-precision floating-point value `a' | to the precision provided by floatx80_rounding_precision and returns the @@ -5938,44 +5834,6 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_= status *status) return floatx80_modrem(a, b, true, "ient, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the extended double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 float128_to_floatx80(float128 a, float_status *status) -{ - bool aSign; - int32_t aExp; - uint64_t aSig0, aSig1; - - aSig1 =3D extractFloat128Frac1( a ); - aSig0 =3D extractFloat128Frac0( a ); - aExp =3D extractFloat128Exp( a ); - aSign =3D extractFloat128Sign( a ); - if ( aExp =3D=3D 0x7FFF ) { - if ( aSig0 | aSig1 ) { - floatx80 res =3D commonNaNToFloatx80(float128ToCommonNaN(a, st= atus), - status); - return floatx80_silence_nan(res, status); - } - return packFloatx80(aSign, floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp =3D=3D 0 ) { - if ( ( aSig0 | aSig1 ) =3D=3D 0 ) return packFloatx80( aSign, 0, 0= ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - else { - aSig0 |=3D UINT64_C(0x0001000000000000); - } - shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 ); - return roundAndPackFloatx80(80, aSign, aExp, aSig0, aSig1, status); - -} - /*------------------------------------------------------------------------= ---- | Returns the remainder of the quadruple-precision floating-point value `a' | with respect to the corresponding value `b'. The operation is performed diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc index c895733e79..95e5325f67 100644 --- a/fpu/softfloat-specialize.c.inc +++ b/fpu/softfloat-specialize.c.inc @@ -256,14 +256,6 @@ floatx80 floatx80_default_nan(float_status *status) const floatx80 floatx80_infinity =3D make_floatx80_init(floatx80_infinity_high, floatx80_infinity_low); =20 -/*------------------------------------------------------------------------= ---- -| Internal canonical NaN format. -*-------------------------------------------------------------------------= ---*/ -typedef struct { - bool sign; - uint64_t high, low; -} commonNaNT; - /*------------------------------------------------------------------------= ---- | Returns 1 if the half-precision floating-point value `a' is a quiet | NaN; otherwise returns 0. @@ -379,46 +371,6 @@ bool float32_is_signaling_nan(float32 a_, float_status= *status) } } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*-------------------------------------------------------------------------= ---*/ - -static commonNaNT float32ToCommonNaN(float32 a, float_status *status) -{ - commonNaNT z; - - if (float32_is_signaling_nan(a, status)) { - float_raise(float_flag_invalid, status); - } - z.sign =3D float32_val(a) >> 31; - z.low =3D 0; - z.high =3D ((uint64_t)float32_val(a)) << 41; - return z; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the canonical NaN `a' to the single- -| precision floating-point format. -*-------------------------------------------------------------------------= ---*/ - -static float32 commonNaNToFloat32(commonNaNT a, float_status *status) -{ - uint32_t mantissa =3D a.high >> 41; - - if (status->default_nan_mode) { - return float32_default_nan(status); - } - - if (mantissa) { - return make_float32( - (((uint32_t)a.sign) << 31) | 0x7F800000 | (a.high >> 41)); - } else { - return float32_default_nan(status); - } -} - /*------------------------------------------------------------------------= ---- | Select which NaN to propagate for a two-input operation. | IEEE754 doesn't specify all the details of this, so the @@ -785,48 +737,6 @@ bool float64_is_signaling_nan(float64 a_, float_status= *status) } } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*-------------------------------------------------------------------------= ---*/ - -static commonNaNT float64ToCommonNaN(float64 a, float_status *status) -{ - commonNaNT z; - - if (float64_is_signaling_nan(a, status)) { - float_raise(float_flag_invalid, status); - } - z.sign =3D float64_val(a) >> 63; - z.low =3D 0; - z.high =3D float64_val(a) << 12; - return z; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the canonical NaN `a' to the double- -| precision floating-point format. -*-------------------------------------------------------------------------= ---*/ - -static float64 commonNaNToFloat64(commonNaNT a, float_status *status) -{ - uint64_t mantissa =3D a.high >> 12; - - if (status->default_nan_mode) { - return float64_default_nan(status); - } - - if (mantissa) { - return make_float64( - (((uint64_t) a.sign) << 63) - | UINT64_C(0x7FF0000000000000) - | (a.high >> 12)); - } else { - return float64_default_nan(status); - } -} - /*------------------------------------------------------------------------= ---- | Takes two double-precision floating-point values `a' and `b', one of whi= ch | is a NaN, and returns the appropriate NaN result. If either `a' or `b' = is a @@ -946,55 +856,6 @@ floatx80 floatx80_silence_nan(floatx80 a, float_status= *status) return a; } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the extended double-precision floating- -| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, t= he -| invalid exception is raised. -*-------------------------------------------------------------------------= ---*/ - -static commonNaNT floatx80ToCommonNaN(floatx80 a, float_status *status) -{ - floatx80 dflt; - commonNaNT z; - - if (floatx80_is_signaling_nan(a, status)) { - float_raise(float_flag_invalid, status); - } - if (a.low >> 63) { - z.sign =3D a.high >> 15; - z.low =3D 0; - z.high =3D a.low << 1; - } else { - dflt =3D floatx80_default_nan(status); - z.sign =3D dflt.high >> 15; - z.low =3D 0; - z.high =3D dflt.low << 1; - } - return z; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the canonical NaN `a' to the extended -| double-precision floating-point format. -*-------------------------------------------------------------------------= ---*/ - -static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status) -{ - floatx80 z; - - if (status->default_nan_mode) { - return floatx80_default_nan(status); - } - - if (a.high >> 1) { - z.low =3D UINT64_C(0x8000000000000000) | a.high >> 1; - z.high =3D (((uint16_t)a.sign) << 15) | 0x7FFF; - } else { - z =3D floatx80_default_nan(status); - } - return z; -} - /*------------------------------------------------------------------------= ---- | Takes two extended double-precision floating-point values `a' and `b', o= ne | of which is a NaN, and returns the appropriate NaN result. If either `a= ' or @@ -1087,42 +948,6 @@ bool float128_is_signaling_nan(float128 a, float_stat= us *status) } } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the quadruple-precision floating-point = NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*-------------------------------------------------------------------------= ---*/ - -static commonNaNT float128ToCommonNaN(float128 a, float_status *status) -{ - commonNaNT z; - - if (float128_is_signaling_nan(a, status)) { - float_raise(float_flag_invalid, status); - } - z.sign =3D a.high >> 63; - shortShift128Left(a.high, a.low, 16, &z.high, &z.low); - return z; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the canonical NaN `a' to the quadruple- -| precision floating-point format. -*-------------------------------------------------------------------------= ---*/ - -static float128 commonNaNToFloat128(commonNaNT a, float_status *status) -{ - float128 z; - - if (status->default_nan_mode) { - return float128_default_nan(status); - } - - shift128Right(a.high, a.low, 16, &z.high, &z.low); - z.high |=3D (((uint64_t)a.sign) << 63) | UINT64_C(0x7FFF000000000000); - return z; -} - /*------------------------------------------------------------------------= ---- | Takes two quadruple-precision floating-point values `a' and `b', one of | which is a NaN, and returns the appropriate NaN result. If either `a' or --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621960596; cv=none; d=zohomail.com; s=zohoarc; b=OeaPU+YtVmuHoJPIeNyLyyj5Xj0aHdLc8Q4pyiOgcXfB0HS/1xkrVy7SjirMHdcYcegRfKT8VQDKloJ5YCXZZ1mF+HJhCh12jpDiqWixHPTGAAMqjQcoLSxXJ7zxC6nfBCBFv4MePMIYM1837rUSLcoWimQw46kjUu1NtzhZtYQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621960596; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=CI/R/53O81mXWi9nTuhnEYZUkbwrVqzqCqbujiTaNEg=; b=RIfBLKBWvF+U/AkyMwnBZJyDSyS4wEQbJQZ+0zWMkQDhg1XnSt3MdpbbDB+n+rJlUmJlAYV9ef4yWI6HyM8aaro5ihLQg7cTtWUEbMElOgWfmdCFeW2rQhSFXmpcKHTYxAHJKQFgBmxeFdexLgr0ibGrtn7GPOYkriFr85D4axA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621960596002598.7666883377083; Tue, 25 May 2021 09:36:36 -0700 (PDT) Received: from localhost ([::1]:50884 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla2k-0003Yd-LT for importer@patchew.org; Tue, 25 May 2021 12:36:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60550) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeh-00020W-FE for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:39 -0400 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]:37875) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0006km-K1 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:39 -0400 Received: by mail-pl1-x62a.google.com with SMTP id u7so7928776plq.4 for ; Tue, 25 May 2021 08:07:22 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CI/R/53O81mXWi9nTuhnEYZUkbwrVqzqCqbujiTaNEg=; b=wnQiYUJ8E86Ndlp0TOSzjXXk/6Ril2ez3ITu9iluONdOOe/Z0EXK+QHNd19tBovTQ9 I1dWSumbnLfQ5rswhRa0POpmG3NYE5sg9/NB/BxzcPzcieyUV/ooPIUBmNqUBrGcuNv5 EC6/Zh9PpFnsq/DAXObPSHHNBOdeGwP6OnGg2eyGMgNnYCa9Y8zAt7qMjkvX7X2UK4QG tWFe0G20yavm+rrNJ2ihDPy3QOsGN8sdTxEUmJgXUu0w3/nmFggMaou5yhMSLb8AR3RQ R4w06ECQ5K1VZhvXZoN5ZCuEJZQQ75qLEZHyq/pknWxtZE6MGJxFy4f8nblNBUGgvG0o bmjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CI/R/53O81mXWi9nTuhnEYZUkbwrVqzqCqbujiTaNEg=; b=FXqf3F587FT4t7Ope52ri4wmkzhbXioeM3tIMU1U3S3wSNSTEDl3VGy3h54L5gZZHe NP69u4/xYudRE4aCJaDwyzk/XHPmWoX/hmZjgisTwVpXz3SoSX/Ac8AG9xCRGrdJiRkN bJ27NooNk7EsUt2nl9SdQHSR2CULFiXMNaElrCP47ujCusYIECr0YqLusIvSWLOZCSH9 Poj0lRVSRwoTJuhDWT7FlJtopXvLmsjU2995bjIV0OY2HkbHyBhtFgR0NelQL895yurt TgODQ8NHMQ0akBZ1jG6YJ86IfY1+lrdC7g9udr8Sn88FQ4dr7IiQV5spHJXqpSBs6vm6 VqIA== X-Gm-Message-State: AOAM532nftglzpHQWy8tJ4EtQHCuj8D4CNAfFaeebQjx5tEzAUcjNo8M rL7XZhSnrmcFNtpMMUyzf2Tvy070Qt9w4g== X-Google-Smtp-Source: ABdhPJzraaLODrAKECNtwyIWK7qjABStI7WeMR1o3GfvOyuMhGrpIKz1xD/M0aHRpInajPauTS9p4Q== X-Received: by 2002:a17:90a:e2c7:: with SMTP id fr7mr31156346pjb.145.1621955240964; Tue, 25 May 2021 08:07:20 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 21/28] softfloat: Convert floatx80 to integer to FloatParts Date: Tue, 25 May 2021 08:06:59 -0700 Message-Id: <20210525150706.294968-22-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62a.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 336 ++++++------------------------------------------ 1 file changed, 42 insertions(+), 294 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 435be2a0bf..52a9aa1837 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2829,6 +2829,28 @@ static int64_t float128_to_int64_scalbn(float128 a, = FloatRoundMode rmode, return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s); } =20 +static int32_t floatx80_to_int32_scalbn(floatx80 a, FloatRoundMode rmode, + int scale, float_status *s) +{ + FloatParts128 p; + + if (!floatx80_unpack_canonical(&p, a, s)) { + parts_default_nan(&p, s); + } + return parts_float_to_sint(&p, rmode, scale, INT32_MIN, INT32_MAX, s); +} + +static int64_t floatx80_to_int64_scalbn(floatx80 a, FloatRoundMode rmode, + int scale, float_status *s) +{ + FloatParts128 p; + + if (!floatx80_unpack_canonical(&p, a, s)) { + parts_default_nan(&p, s); + } + return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s); +} + int8_t float16_to_int8(float16 a, float_status *s) { return float16_to_int8_scalbn(a, s->float_rounding_mode, 0, s); @@ -2889,6 +2911,16 @@ int64_t float128_to_int64(float128 a, float_status *= s) return float128_to_int64_scalbn(a, s->float_rounding_mode, 0, s); } =20 +int32_t floatx80_to_int32(floatx80 a, float_status *s) +{ + return floatx80_to_int32_scalbn(a, s->float_rounding_mode, 0, s); +} + +int64_t floatx80_to_int64(floatx80 a, float_status *s) +{ + return floatx80_to_int64_scalbn(a, s->float_rounding_mode, 0, s); +} + int16_t float16_to_int16_round_to_zero(float16 a, float_status *s) { return float16_to_int16_scalbn(a, float_round_to_zero, 0, s); @@ -2944,6 +2976,16 @@ int64_t float128_to_int64_round_to_zero(float128 a, = float_status *s) return float128_to_int64_scalbn(a, float_round_to_zero, 0, s); } =20 +int32_t floatx80_to_int32_round_to_zero(floatx80 a, float_status *s) +{ + return floatx80_to_int32_scalbn(a, float_round_to_zero, 0, s); +} + +int64_t floatx80_to_int64_round_to_zero(floatx80 a, float_status *s) +{ + return floatx80_to_int64_scalbn(a, float_round_to_zero, 0, s); +} + int16_t bfloat16_to_int16(bfloat16 a, float_status *s) { return bfloat16_to_int16_scalbn(a, s->float_rounding_mode, 0, s); @@ -4163,127 +4205,6 @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a,= float_status *status) return a; } =20 -/*------------------------------------------------------------------------= ---- -| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 -| and 7, and returns the properly rounded 32-bit integer corresponding to = the -| input. If `zSign' is 1, the input is negated before being converted to = an -| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point in= put -| is simply rounded to an integer, with the inexact exception raised if the -| input cannot be represented exactly as an integer. However, if the fixe= d- -| point input is too large, the invalid exception is raised and the largest -| positive or negative integer is returned. -*-------------------------------------------------------------------------= ---*/ - -static int32_t roundAndPackInt32(bool zSign, uint64_t absZ, - float_status *status) -{ - int8_t roundingMode; - bool roundNearestEven; - int8_t roundIncrement, roundBits; - int32_t z; - - roundingMode =3D status->float_rounding_mode; - roundNearestEven =3D ( roundingMode =3D=3D float_round_nearest_even ); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - roundIncrement =3D 0x40; - break; - case float_round_to_zero: - roundIncrement =3D 0; - break; - case float_round_up: - roundIncrement =3D zSign ? 0 : 0x7f; - break; - case float_round_down: - roundIncrement =3D zSign ? 0x7f : 0; - break; - case float_round_to_odd: - roundIncrement =3D absZ & 0x80 ? 0 : 0x7f; - break; - default: - abort(); - } - roundBits =3D absZ & 0x7F; - absZ =3D ( absZ + roundIncrement )>>7; - if (!(roundBits ^ 0x40) && roundNearestEven) { - absZ &=3D ~1; - } - z =3D absZ; - if ( zSign ) z =3D - z; - if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { - float_raise(float_flag_invalid, status); - return zSign ? INT32_MIN : INT32_MAX; - } - if (roundBits) { - float_raise(float_flag_inexact, status); - } - return z; - -} - -/*------------------------------------------------------------------------= ---- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input wor= ds), -| and returns the properly rounded 64-bit integer corresponding to the inp= ut. -| If `zSign' is 1, the input is negated before being converted to an integ= er. -| Ordinarily, the fixed-point input is simply rounded to an integer, with -| the inexact exception raised if the input cannot be represented exactly = as -| an integer. However, if the fixed-point input is too large, the invalid -| exception is raised and the largest positive or negative integer is -| returned. -*-------------------------------------------------------------------------= ---*/ - -static int64_t roundAndPackInt64(bool zSign, uint64_t absZ0, uint64_t absZ= 1, - float_status *status) -{ - int8_t roundingMode; - bool roundNearestEven, increment; - int64_t z; - - roundingMode =3D status->float_rounding_mode; - roundNearestEven =3D ( roundingMode =3D=3D float_round_nearest_even ); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - increment =3D ((int64_t) absZ1 < 0); - break; - case float_round_to_zero: - increment =3D 0; - break; - case float_round_up: - increment =3D !zSign && absZ1; - break; - case float_round_down: - increment =3D zSign && absZ1; - break; - case float_round_to_odd: - increment =3D !(absZ0 & 1) && absZ1; - break; - default: - abort(); - } - if ( increment ) { - ++absZ0; - if ( absZ0 =3D=3D 0 ) goto overflow; - if (!(absZ1 << 1) && roundNearestEven) { - absZ0 &=3D ~1; - } - } - z =3D absZ0; - if ( zSign ) z =3D - z; - if ( z && ( ( z < 0 ) ^ zSign ) ) { - overflow: - float_raise(float_flag_invalid, status); - return zSign ? INT64_MIN : INT64_MAX; - } - if (absZ1) { - float_raise(float_flag_inexact, status); - } - return z; - -} - /*------------------------------------------------------------------------= ---- | Normalizes the subnormal single-precision floating-point value represent= ed | by the denormalized significand `aSig'. The normalized exponent and @@ -5489,179 +5410,6 @@ float64 float64_log2(float64 a, float_status *statu= s) return normalizeRoundAndPackFloat64(zSign, 0x408, zSig, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 32-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic---which means in particular that the conversion -| is rounded according to the current rounding mode. If `a' is a NaN, the -| largest positive integer is returned. Otherwise, if the conversion -| overflows, the largest integer with the same sign as `a' is returned. -*-------------------------------------------------------------------------= ---*/ - -int32_t floatx80_to_int32(floatx80 a, float_status *status) -{ - bool aSign; - int32_t aExp, shiftCount; - uint64_t aSig; - - if (floatx80_invalid_encoding(a)) { - float_raise(float_flag_invalid, status); - return 1 << 31; - } - aSig =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - aSign =3D extractFloatx80Sign( a ); - if ( ( aExp =3D=3D 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign =3D 0; - shiftCount =3D 0x4037 - aExp; - if ( shiftCount <=3D 0 ) shiftCount =3D 1; - shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32(aSign, aSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 32-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic, except that the conversion is always rounded -| toward zero. If `a' is a NaN, the largest positive integer is returned. -| Otherwise, if the conversion overflows, the largest integer with the same -| sign as `a' is returned. -*-------------------------------------------------------------------------= ---*/ - -int32_t floatx80_to_int32_round_to_zero(floatx80 a, float_status *status) -{ - bool aSign; - int32_t aExp, shiftCount; - uint64_t aSig, savedASig; - int32_t z; - - if (floatx80_invalid_encoding(a)) { - float_raise(float_flag_invalid, status); - return 1 << 31; - } - aSig =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - aSign =3D extractFloatx80Sign( a ); - if ( 0x401E < aExp ) { - if ( ( aExp =3D=3D 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign =3D = 0; - goto invalid; - } - else if ( aExp < 0x3FFF ) { - if (aExp || aSig) { - float_raise(float_flag_inexact, status); - } - return 0; - } - shiftCount =3D 0x403E - aExp; - savedASig =3D aSig; - aSig >>=3D shiftCount; - z =3D aSig; - if ( aSign ) z =3D - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise(float_flag_invalid, status); - return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<>( - shiftCount ); - if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) { - float_raise(float_flag_inexact, status); - } - if ( aSign ) z =3D - z; - return z; - -} - /*------------------------------------------------------------------------= ---- | Rounds the extended double-precision floating-point value `a' | to the precision provided by floatx80_rounding_precision and returns the --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621960811; cv=none; d=zohomail.com; s=zohoarc; b=RP0hS/13W8WBUy5k7JiYbK1yDGl9T7JPaOmdvCGU5/e01t3dNrESsa529+VKwsVjhBj8oSNyz8bqr7O2xV167E3UVCkuRS9XW1EXkIm4hibAaDRMd0e6oj66UQJse58i1HhHVSO/AI7PuVH1xp3Qp1k4rlFP3WzKygjrRDfNtns= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621960811; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=2avWxXahubZ/o5oT70KgFRqpsBXSFNH/Xke7KM6cuMA=; b=SWqQamPyc6tq96lwekqh5YsBj4ehzX6Z78RZP1Q8FQLSUpXVTaqdIv6QuhZYMKuyIhXAZq333hezYSOqBuJsxfy3wQIaJXv9yAhxv+r7roNBzxj+uvVuC8e5O9Rs/3b6JP57iRH7iVWcMms9TP79fsywHp9IMW+/gbriCYmEdeU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621960811743687.9309348300563; Tue, 25 May 2021 09:40:11 -0700 (PDT) Received: from localhost ([::1]:34234 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla6E-0003Gs-MG for importer@patchew.org; Tue, 25 May 2021 12:40:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60546) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeh-0001zs-9q for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:39 -0400 Received: from mail-pg1-x52b.google.com ([2607:f8b0:4864:20::52b]:36532) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0006kx-WC for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:38 -0400 Received: by mail-pg1-x52b.google.com with SMTP id 27so21669979pgy.3 for ; Tue, 25 May 2021 08:07:22 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2avWxXahubZ/o5oT70KgFRqpsBXSFNH/Xke7KM6cuMA=; b=Em9r4PRlDFRSDkqXeXPAwGjl2ne5ZDxYhGOCvwdesdsoZLz40VrS4/qpMTaTR7D28T zvb5x/UmhiUdxmJW/tD6Lmy4to6NLI7FJz2e6aYagZTj5zvWESzG/om2aR2BxWFMwr7A VLZMIue2VNiVGFklFwkTr3+TLW9SbEMBGRsGtJnGS4qLR2gDKkQZ4VZHYag01rJM5mJh UxOsx9ql05D+PIMbQH5BDVvG0O9uSIjycSqWrjjojfS/o5nVFVVwyyHmGeaWlBXlkcPa yKztmPls4bApMkNmNu5uhVDQvSZTIhL6TDsWaSDkRrVd3K76uwcSaxXL4ufEDILpg7Y8 j0IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2avWxXahubZ/o5oT70KgFRqpsBXSFNH/Xke7KM6cuMA=; b=KiFF3KTqGepo1nhr7YkrHvCaJaXfnvO4RR6krMJS9EgyhMA1zrXcbTinnCtx2nIG67 s5VKkpqGu49XGTWszStU9/yFjEGzdwmESd7GPvt7YEYmBOuMTLAYA3J112Vt/aLsTtUI UDwL2t2heCdrP47izOOEYir/4Zo25NhLU6VSe4F9s2ot1X4qNElMyHrtjoC4Enea68NX NrCwt9P40apccDFsz7OgILQqH89MhMedokf993bDvBR3rE7mKKs/7O/5f7DjZHPFEo3p OGROTnbbw/V6wugL+L1Ai5rYoQ1uxa4n+obdgf/fa4kXKTqIli0ZeLdGn44d8LJyEbIQ pysQ== X-Gm-Message-State: AOAM532ebBJ8Z1uqZdPTo9US9OG3F1fGm9vVYrw4YgkE9O23J5Fqba6m 9x8G8GS5HkIHqzCwlkTN6D4OeO/tLKSQWQ== X-Google-Smtp-Source: ABdhPJy6cDtWCdcIjYLiaV0WwekLMiP5sU8q004PI1LiOzJ0Mzdv5Z0RxYw6ZJxOLpN+c1zqi6n4sA== X-Received: by 2002:a63:1953:: with SMTP id 19mr19377649pgz.273.1621955241568; Tue, 25 May 2021 08:07:21 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 22/28] softfloat: Convert floatx80_scalbn to FloatParts Date: Tue, 25 May 2021 08:07:00 -0700 Message-Id: <20210525150706.294968-23-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::52b; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52b.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 50 +++++++++++-------------------------------------- 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 52a9aa1837..0d1d9df70d 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3914,6 +3914,17 @@ float128 float128_scalbn(float128 a, int n, float_st= atus *status) return float128_round_pack_canonical(&p, status); } =20 +floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) +{ + FloatParts128 p; + + if (!floatx80_unpack_canonical(&p, a, status)) { + return floatx80_default_nan(status); + } + parts_scalbn(&p, n, status); + return floatx80_round_pack_canonical(&p, status); +} + /* * Square Root */ @@ -5748,45 +5759,6 @@ FloatRelation floatx80_compare_quiet(floatx80 a, flo= atx80 b, return floatx80_compare_internal(a, b, 1, status); } =20 -floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) -{ - bool aSign; - int32_t aExp; - uint64_t aSig; - - if (floatx80_invalid_encoding(a)) { - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - aSig =3D extractFloatx80Frac( a ); - aExp =3D extractFloatx80Exp( a ); - aSign =3D extractFloatx80Sign( a ); - - if ( aExp =3D=3D 0x7FFF ) { - if ( aSig<<1 ) { - return propagateFloatx80NaN(a, a, status); - } - return a; - } - - if (aExp =3D=3D 0) { - if (aSig =3D=3D 0) { - return a; - } - aExp++; - } - - if (n > 0x10000) { - n =3D 0x10000; - } else if (n < -0x10000) { - n =3D -0x10000; - } - - aExp +=3D n; - return normalizeRoundAndPackFloatx80(status->floatx80_rounding_precisi= on, - aSign, aExp, aSig, 0, status); -} - static void __attribute__((constructor)) softfloat_init(void) { union_float64 ua, ub, uc, ur; --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621960922; cv=none; d=zohomail.com; s=zohoarc; b=P+8V0nxEovrFBQzEzCtuVCI002D7Vb1eU1TANIaXKytpvmCNFJ2KDSV/C/5NfrTr/6hev7zE0HoYL+g6s4roK2HQqDXK8q3SfQ8f7MsWpG1fQqLvyP6dgSGdUCk0NpPDpsIkpYBGkBPrFnjpQIPCdCyu1ZBqr1Citp0BhM9xLd4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621960922; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=ytofR8WbQtEyPToJLhefg0tEo9cYPt2fZe6o8phMK5E=; b=efYBWbpseNxq2oFGYfbVMki0CjQYOEBOYIDLVTp/EnpyxG448758DX+aVRQ3874dUrViGKGuCtsCYNJjKEIlntLkVW/o/rd1HALzwTQTs04lwHor7gjD7W5sSLFKmBQNNaEhnNbMU0qp/GDDL+avogm8+v7zra7sYWUXMKgWmV0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621960922596997.3750143764469; Tue, 25 May 2021 09:42:02 -0700 (PDT) Received: from localhost ([::1]:39864 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla81-0007F3-GB for importer@patchew.org; Tue, 25 May 2021 12:42:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60620) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYen-0002Gl-RN for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:45 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]:44867) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeR-0006lB-DC for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:45 -0400 Received: by mail-pl1-x62c.google.com with SMTP id h12so4336579plf.11 for ; Tue, 25 May 2021 08:07:22 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ytofR8WbQtEyPToJLhefg0tEo9cYPt2fZe6o8phMK5E=; b=ep7y7vEPA+LFrDFCm6qfcE2P8K4IkD4DbYegf7nsOgXgKJum0OHHFMaUU5E4EEe7Bh 3gEJL160OWg3I7kcX/X40N4CCUS5/RGaFR6nMVV6367dwa9LZKwyyc3aG6EDhLV1VKWR bqCOq2ZxFiP5e8aXY0b5BgcjrwsCKxGCNspTr3SixNSEfgysvR/T9hX1UKOCPZDjOTEl 85SOmKtYlsaFHczf+HLsQxIgC89lCS6uSYzLeqjlHVt/dR2B0+9xvwa4D/FwRWZjoM1v LIB2oSYE+hQK1Yvhhjei2A1xzMg0OThi752GSbzfkEimdZ8248qS+yu0GpHXWq1chexo XJSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ytofR8WbQtEyPToJLhefg0tEo9cYPt2fZe6o8phMK5E=; b=qH/9Ke0Qkj/MPK+Anzouar8jCxN5F7aQ9AfYN91khIH1L0ZwR/Rbu+7vLNGL0YsqJw 6xS0LLGvOOmOONpoVn9A1nk5Cdz3PcEw/D4H2M2kIcfppAnbQbIgyLwzS7JZR8Eim2IO WuI5c6hPmnZH7RAHvBxYeFRd5A14iDCUtox9voqtG4mMWdrOQyphBi6R4i2Fc+pMsUXY Bx5u75jWo1djxW0wvEPP2qKLIs1Qmg0YWy7c53cGWIyDam3o79ZJ07SEKJqev+dSkmVY UFA/6Oj78bB4aMLZ1nSi6APJ1iRccs2FHoT/w+jIk/XCuCTHvyPNNT2ATfCMRzlbsFUe 74zw== X-Gm-Message-State: AOAM532wvOI/sf9bJZ4ehhcH4gZCk07QektbrnCTRP8YzoiSIHzD9Tu4 b0y7rn5LWu18kPCmkYIkc6CLWT087P+AGA== X-Google-Smtp-Source: ABdhPJxMh3tI9ze2K+TlN/RdFhV9pT0bdfyWvpfFE5UQ1bq6TQCzBRAsz4FGKl4F6LJZD/0cwVdP6A== X-Received: by 2002:a17:90b:201:: with SMTP id fy1mr5198437pjb.119.1621955242132; Tue, 25 May 2021 08:07:22 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 23/28] softfloat: Convert floatx80 compare to FloatParts Date: Tue, 25 May 2021 08:07:01 -0700 Message-Id: <20210525150706.294968-24-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62c.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 82 +++++++++++++------------------------------------ 1 file changed, 22 insertions(+), 60 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 0d1d9df70d..b86441d0c9 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3865,6 +3865,28 @@ FloatRelation float128_compare_quiet(float128 a, flo= at128 b, float_status *s) return float128_do_compare(a, b, s, true); } =20 +static FloatRelation QEMU_FLATTEN +floatx80_do_compare(floatx80 a, floatx80 b, float_status *s, bool is_quiet) +{ + FloatParts128 pa, pb; + + if (!floatx80_unpack_canonical(&pa, a, s) || + !floatx80_unpack_canonical(&pb, b, s)) { + return float_relation_unordered; + } + return parts_compare(&pa, &pb, s, is_quiet); +} + +FloatRelation floatx80_compare(floatx80 a, floatx80 b, float_status *s) +{ + return floatx80_do_compare(a, b, s, false); +} + +FloatRelation floatx80_compare_quiet(floatx80 a, floatx80 b, float_status = *s) +{ + return floatx80_do_compare(a, b, s, true); +} + /* * Scale by 2**N */ @@ -5699,66 +5721,6 @@ float128 float128_rem(float128 a, float128 b, float_= status *status) return normalizeRoundAndPackFloat128(aSign ^ zSign, bExp - 4, aSig0, a= Sig1, status); } - -static inline FloatRelation -floatx80_compare_internal(floatx80 a, floatx80 b, bool is_quiet, - float_status *status) -{ - bool aSign, bSign; - - if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) { - float_raise(float_flag_invalid, status); - return float_relation_unordered; - } - if (( ( extractFloatx80Exp( a ) =3D=3D 0x7fff ) && - ( extractFloatx80Frac( a )<<1 ) ) || - ( ( extractFloatx80Exp( b ) =3D=3D 0x7fff ) && - ( extractFloatx80Frac( b )<<1 ) )) { - if (!is_quiet || - floatx80_is_signaling_nan(a, status) || - floatx80_is_signaling_nan(b, status)) { - float_raise(float_flag_invalid, status); - } - return float_relation_unordered; - } - aSign =3D extractFloatx80Sign( a ); - bSign =3D extractFloatx80Sign( b ); - if ( aSign !=3D bSign ) { - - if ( ( ( (uint16_t) ( ( a.high | b.high ) << 1 ) ) =3D=3D 0) && - ( ( a.low | b.low ) =3D=3D 0 ) ) { - /* zero case */ - return float_relation_equal; - } else { - return 1 - (2 * aSign); - } - } else { - /* Normalize pseudo-denormals before comparison. */ - if ((a.high & 0x7fff) =3D=3D 0 && a.low & UINT64_C(0x8000000000000= 000)) { - ++a.high; - } - if ((b.high & 0x7fff) =3D=3D 0 && b.low & UINT64_C(0x8000000000000= 000)) { - ++b.high; - } - if (a.low =3D=3D b.low && a.high =3D=3D b.high) { - return float_relation_equal; - } else { - return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low = ) )); - } - } -} - -FloatRelation floatx80_compare(floatx80 a, floatx80 b, float_status *statu= s) -{ - return floatx80_compare_internal(a, b, 0, status); -} - -FloatRelation floatx80_compare_quiet(floatx80 a, floatx80 b, - float_status *status) -{ - return floatx80_compare_internal(a, b, 1, status); -} - static void __attribute__((constructor)) softfloat_init(void) { union_float64 ua, ub, uc, ur; --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959783; cv=none; d=zohomail.com; s=zohoarc; b=SV9BihZ33cEGnLiseVGZSMKGRA0iQyYB7e+CN4rDRsW0jA3Qb2BX/bYCu+7JoAW4dRuoYB7tY/DF0HACXy/GIyXHnCH5BAPSf/BW5YDoNeESQOW1VHiQCXzOU6QIx2Dv7LtqkWujVuo7voKFRlrMiVYUMooYn18nN05ncFnWrd8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959783; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=oFUF30PagAXhKM0dixbmpt9CMC+0KnqcFmUJiQifWoM=; b=U/YahV19W9LODbNa30DbH3ntd5/JicX5WaSkUahgqZ84gOTQX7pKWhiE2BHVrFtA0dBuxzMM+3jimc7iU48U4SuUIRViV3d1CEIYX2UaS/fWMgD5L9jKJ8U5fM33Qc9EG0qLk/F/OhKW+2xiXpYvQupB2TalhbpkadpbjWgV6XM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959783268347.840567156454; Tue, 25 May 2021 09:23:03 -0700 (PDT) Received: from localhost ([::1]:43626 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZpe-0004EZ-EK for importer@patchew.org; Tue, 25 May 2021 12:23:02 -0400 Received: from [2001:470:142:3::10] (port=60606 helo=eggs.gnu.org) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYem-0002Ag-Gf for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:44 -0400 Received: from mail-pf1-x436.google.com ([2607:f8b0:4864:20::436]:42643) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeS-0006lb-Ez for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:43 -0400 Received: by mail-pf1-x436.google.com with SMTP id x18so19535009pfi.9 for ; Tue, 25 May 2021 08:07:24 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=oFUF30PagAXhKM0dixbmpt9CMC+0KnqcFmUJiQifWoM=; b=PMLlTlkvPOWxRykFfR0i0BtrNbCKbeO3YwHzCKjfpPtcrz7amfVClToEdEsSuvFlyE xfUBybHPo3OVYeZuq0MIn4BAV+MQArljh6BbHyeKctJu0gPOE3+GHU5BZZ85Ooobw6ds CrOjlyFAdYDepHE06qhooXCaqXmP3RL6Xn4nBiPSoou/+ZyrD8YxljfkJzqs7y/KOsBX 1edgB5l8wpRRbVjbANoplrJ2Fs8Cy00wZcYiTCV4v8F417BZt0fzsynui+zFj81o0bYi dQ3g0XKawb5s6u5ZtL+IYByy1IxV2G2viLmRjCIL0ewpi0Wm8BQG7JIgnQbGZE1LQha2 GNZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oFUF30PagAXhKM0dixbmpt9CMC+0KnqcFmUJiQifWoM=; b=SEDggpXtDlhA+hLPy2RThcrvmGAnOt1bVPo8YqMM+YiySU5EcDDsYGVioOislrY75N Lh1UDJM4IVmqif3E2g4G28B47U4hJ4iz2e1X+PKukKqDysHKs/D8PiqlNi0d6Kutv3wl Eqzyp93JALjeOxhtgPFJ+IV0idJ8kTR5ratcYr3DcLxB0gxmv4SsQ/BMkWYm6A37mNoI G0c0odVsiTfPKqxfNro0kscFQEAJOa5O5E2VE4/2eUJYxD5UuXUgDpxhXMes6GcWuZhA MzQjy7nOQGUE2GTuIxV3pHDnvCmmHhgSyhFhMFrACbdCSLl90Ico4Ezgf9x48IWjN57O +CAQ== X-Gm-Message-State: AOAM531FLtUp1Mf0i0X/CliEkiVVKDzs+QtN2kzCG54iwG6uanBIGbXH tvtHmqrYRAQN2gh4ixkN9r/2mHrWO+kYKA== X-Google-Smtp-Source: ABdhPJxk8vPoUZk/1Ysv0JvFTqiMulCHdBsBCVF7lsM8hWMPi9H9BVOZWpqub1bU8SDSvA0eYGGiPg== X-Received: by 2002:a62:d447:0:b029:291:19f7:ddcd with SMTP id u7-20020a62d4470000b029029119f7ddcdmr30705548pfl.54.1621955242990; Tue, 25 May 2021 08:07:22 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 24/28] softfloat: Convert float32_exp2 to FloatParts Date: Tue, 25 May 2021 08:07:02 -0700 Message-Id: <20210525150706.294968-25-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::436; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x436.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Keep the intermediate results in FloatParts instead of converting back and forth between float64. Use muladd instead of separate mul+add. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 53 +++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index b86441d0c9..c778b96c37 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -5213,47 +5213,40 @@ static const float64 float32_exp2_coefficients[15] = =3D =20 float32 float32_exp2(float32 a, float_status *status) { - bool aSign; - int aExp; - uint32_t aSig; - float64 r, x, xn; + FloatParts64 xp, xnp, tp, rp; int i; - a =3D float32_squash_input_denormal(a, status); =20 - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - - if ( aExp =3D=3D 0xFF) { - if (aSig) { - return propagateFloat32NaN(a, float32_zero, status); + float32_unpack_canonical(&xp, a, status); + if (unlikely(xp.cls !=3D float_class_normal)) { + switch (xp.cls) { + case float_class_snan: + case float_class_qnan: + parts_return_nan(&xp, status); + return float32_round_pack_canonical(&xp, status); + case float_class_inf: + return xp.sign ? float32_zero : a; + case float_class_zero: + return float32_one; + default: + break; } - return (aSign) ? float32_zero : a; - } - if (aExp =3D=3D 0) { - if (aSig =3D=3D 0) return float32_one; + g_assert_not_reached(); } =20 float_raise(float_flag_inexact, status); =20 - /* ******************************* */ - /* using float64 for approximation */ - /* ******************************* */ - x =3D float32_to_float64(a, status); - x =3D float64_mul(x, float64_ln2, status); + float64_unpack_canonical(&xnp, float64_ln2, status); + xp =3D *parts_mul(&xp, &tp, status); + xnp =3D xp; =20 - xn =3D x; - r =3D float64_one; + float64_unpack_canonical(&rp, float64_one, status); for (i =3D 0 ; i < 15 ; i++) { - float64 f; - - f =3D float64_mul(xn, float32_exp2_coefficients[i], status); - r =3D float64_add(r, f, status); - - xn =3D float64_mul(xn, x, status); + float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status= ); + rp =3D *parts_muladd(&tp, &xp, &rp, 0, status); + xnp =3D *parts_mul(&xnp, &xp, status); } =20 - return float64_to_float32(r, status); + return float32_round_pack_canonical(&rp, status); } =20 /*------------------------------------------------------------------------= ---- --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959771; cv=none; d=zohomail.com; s=zohoarc; b=dm3UIqIlvkAeXkfJL6hTw9Td0TMX9AZLEn0LM3KQRyXcPjxtF52NA3AEhaCDUFA1HwWYQJojMxstRdFzNrtOtNa+mXhfPNSKOU1iWpo/v1NCzZbLXfKEUrWhsUL7jy2RzkKrmpTLbN2oICUIoYaLnz20Dsa2OCFW/BkzyYYQtL0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959771; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=jQpxV55+RReSCj98NiG+0x+49ehVUqcsxXmjl0897cY=; b=KHMAHE61Kmav0aB9K29q5VFOp7WGfzQrYBWnaQDo22ysO7+Izm/RbG0KzY8Y7Pj58MQF7/vZG+45tZqkY8tgRUjpcBG3GtGvHxmdUGf0vSnaFSoGLyHssWOH3B3q/dx4b15OJRDqk3Zy6NcNgV0RrQ1X5yiqHrYnzsI9twLiW88= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 16219597716809.560976431147424; Tue, 25 May 2021 09:22:51 -0700 (PDT) Received: from localhost ([::1]:42840 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZpS-0003h2-Pz for importer@patchew.org; Tue, 25 May 2021 12:22:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60608) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeo-0002IZ-8a for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:46 -0400 Received: from mail-pg1-x532.google.com ([2607:f8b0:4864:20::532]:40716) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeT-0006mX-H3 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:44 -0400 Received: by mail-pg1-x532.google.com with SMTP id j12so22967800pgh.7 for ; Tue, 25 May 2021 08:07:24 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jQpxV55+RReSCj98NiG+0x+49ehVUqcsxXmjl0897cY=; b=z1ujuaUzcze3t2NvVDYvdKf9DTHfi25W2Zw3krekGLHTyzncoWbH0bNS1gPaA3IUJA AhIc+nzeYFa6FQjX6BqnL8Kj6SQzl7oK+s8We0lGCtAJN9UNoIE+RhRslSdKbQigm6uX N7t2WdQ4UVgRTNbtypVb/8VRs/ADh4IpQuFsNLw3cka7yLnmPxaofq7PI50GGqmVlmuY tjT6qPTXFh4k3QUu2xzfMf2mGfNNUP7IMhJptppsy2E6CP3+M2zmTvb37m7fxUi/S4X4 7ZCopupJ7EYc4vtqrP1iEPpzRYMig1Vd9/LohrfBCLDiDcXn57fcYtqXJ7tNOicgYMfn /+Lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jQpxV55+RReSCj98NiG+0x+49ehVUqcsxXmjl0897cY=; b=Co1az95RmtfR4f/S3wgB0ItDXa9Ns6bQt25O6BTkDWv4SguSekvTVIkH5fUFReUygB qnfIgMl/+NDzrvWyV1N9Pf1UIo8aYs0UyOm/6tUYPr9hYfAVJ6kJktCJJ3/GxEJ3x6oX PXqgbh+FpRg4Bk7YNf5/BslSYFO7IfjownvnBIsrD6cE5N+suyPSaX97SxBfzsUJICO3 1/dKWoFvX1FseGBRCUHEW7sHldWOhG5JS0HMAHWLZZT0uzTlWbZa1RDJ4CP5m00fxmyK 89LLgIyJlAB7dVVObJMNBa7e0GIWodnoyQ5KNXJR6yd1w3mm2u2mKWeO5euZd6NCqs+q V+zg== X-Gm-Message-State: AOAM532fSvEtndCRnpEEIb9x9E64LIT01Xg9h1nHs/I5Q4tMeojm0txX 4VYZ9IEm2YTBJJIwIapgC/eoDOhNanvV0Q== X-Google-Smtp-Source: ABdhPJwb2ifM0Dde2/JRyhhJ6A3NtMDOFHLYKkf1sCbwPOY2etjYmWVhYpbYUVdVGHVImidZXR1IQQ== X-Received: by 2002:aa7:8a18:0:b029:2dd:42f3:d42f with SMTP id m24-20020aa78a180000b02902dd42f3d42fmr30494585pfa.70.1621955243828; Tue, 25 May 2021 08:07:23 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 25/28] softfloat: Move floatN_log2 to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:07:03 -0700 Message-Id: <20210525150706.294968-26-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::532; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x532.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Rename to parts$N_log2. Though this is partly a ruse, since I do not believe the code will succeed for float128 without work. Which is ok for now, because we do not need this for more than float32 and float64. Since berkeley-testfloat-3 doesn't support log2, compare float64_log2 vs the system log2. Fix the errors for inputs near 1.0: test: 3ff00000000000b0 +0x1.00000000000b0p+0 sf: 3d2fa00000000000 +0x1.fa00000000000p-45 libm: 3d2fbd422b1bd36f +0x1.fbd422b1bd36fp-45 Error in fraction: 32170028290927 ulp test: 3feec24f6770b100 +0x1.ec24f6770b100p-1 sf: bfad3740d13c9ec0 -0x1.d3740d13c9ec0p-5 libm: bfad3740d13c9e98 -0x1.d3740d13c9e98p-5 Error in fraction: 40 ulp Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 126 ++++++++------------------------------ tests/fp/fp-test-log2.c | 118 +++++++++++++++++++++++++++++++++++ fpu/softfloat-parts.c.inc | 125 +++++++++++++++++++++++++++++++++++++ tests/fp/meson.build | 11 ++++ 4 files changed, 281 insertions(+), 99 deletions(-) create mode 100644 tests/fp/fp-test-log2.c diff --git a/fpu/softfloat.c b/fpu/softfloat.c index c778b96c37..6d2f606b39 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -927,6 +927,12 @@ static void parts128_scalbn(FloatParts128 *a, int n, f= loat_status *s); #define parts_scalbn(A, N, S) \ PARTS_GENERIC_64_128(scalbn, A)(A, N, S) =20 +static void parts64_log2(FloatParts64 *a, float_status *s, const FloatFmt = *f); +static void parts128_log2(FloatParts128 *a, float_status *s, const FloatFm= t *f); + +#define parts_log2(A, S, F) \ + PARTS_GENERIC_64_128(log2, A)(A, S, F) + /* * Helper functions for softfloat-parts.c.inc, per-size operations. */ @@ -4063,6 +4069,27 @@ floatx80 floatx80_sqrt(floatx80 a, float_status *s) return floatx80_round_pack_canonical(&p, s); } =20 +/* + * log2 + */ +float32 float32_log2(float32 a, float_status *status) +{ + FloatParts64 p; + + float32_unpack_canonical(&p, a, status); + parts_log2(&p, status, &float32_params); + return float32_round_pack_canonical(&p, status); +} + +float64 float64_log2(float64 a, float_status *status) +{ + FloatParts64 p; + + float64_unpack_canonical(&p, a, status); + parts_log2(&p, status, &float64_params); + return float64_round_pack_canonical(&p, status); +} + /*------------------------------------------------------------------------= ---- | The pattern for a default generated NaN. *-------------------------------------------------------------------------= ---*/ @@ -5249,56 +5276,6 @@ float32 float32_exp2(float32 a, float_status *status) return float32_round_pack_canonical(&rp, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the binary log of the single-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ -float32 float32_log2(float32 a, float_status *status) -{ - bool aSign, zSign; - int aExp; - uint32_t aSig, zSig, i; - - a =3D float32_squash_input_denormal(a, status); - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloat32( 1, 0xFF, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - if ( aSign ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - if ( aExp =3D=3D 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, float32_zero, status); - } - return a; - } - - aExp -=3D 0x7F; - aSig |=3D 0x00800000; - zSign =3D aExp < 0; - zSig =3D aExp << 23; - - for (i =3D 1 << 22; i > 0; i >>=3D 1) { - aSig =3D ( (uint64_t)aSig * aSig ) >> 23; - if ( aSig & 0x01000000 ) { - aSig >>=3D 1; - zSig |=3D i; - } - } - - if ( zSign ) - zSig =3D -zSig; - - return normalizeRoundAndPackFloat32(zSign, 0x85, zSig, status); -} - /*------------------------------------------------------------------------= ---- | Returns the remainder of the double-precision floating-point value `a' | with respect to the corresponding value `b'. The operation is performed @@ -5387,55 +5364,6 @@ float64 float64_rem(float64 a, float64 b, float_stat= us *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the binary log of the double-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ -float64 float64_log2(float64 a, float_status *status) -{ - bool aSign, zSign; - int aExp; - uint64_t aSig, aSig0, aSig1, zSig, i; - a =3D float64_squash_input_denormal(a, status); - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloat64( 1, 0x7FF, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - if ( aSign ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - if ( aExp =3D=3D 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, float64_zero, status); - } - return a; - } - - aExp -=3D 0x3FF; - aSig |=3D UINT64_C(0x0010000000000000); - zSign =3D aExp < 0; - zSig =3D (uint64_t)aExp << 52; - for (i =3D 1LL << 51; i > 0; i >>=3D 1) { - mul64To128( aSig, aSig, &aSig0, &aSig1 ); - aSig =3D ( aSig0 << 12 ) | ( aSig1 >> 52 ); - if ( aSig & UINT64_C(0x0020000000000000) ) { - aSig >>=3D 1; - zSig |=3D i; - } - } - - if ( zSign ) - zSig =3D -zSig; - return normalizeRoundAndPackFloat64(zSign, 0x408, zSig, status); -} - /*------------------------------------------------------------------------= ---- | Rounds the extended double-precision floating-point value `a' | to the precision provided by floatx80_rounding_precision and returns the diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c new file mode 100644 index 0000000000..8ad856509b --- /dev/null +++ b/tests/fp/fp-test-log2.c @@ -0,0 +1,118 @@ +/* + * fp-test-log2.c - test QEMU's softfloat log2 + * + * Copyright (C) 2020, Linaro, Ltd. + * + * License: GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#ifndef HW_POISON_H +#error Must define HW_POISON_H to work around TARGET_* poisoning +#endif + +#include "qemu/osdep.h" +#include "qemu/cutils.h" +#include +#include "fpu/softfloat.h" + +typedef union { + double d; + float64 i; +} ufloat64; + +static int errors; + +static void compare(ufloat64 test, ufloat64 real, ufloat64 soft, bool exac= t) +{ + int msb; + uint64_t ulp =3D UINT64_MAX; + + if (real.i =3D=3D soft.i) { + return; + } + msb =3D 63 - __builtin_clzll(real.i ^ soft.i); + + if (msb < 52) { + if (real.i > soft.i) { + ulp =3D real.i - soft.i; + } else { + ulp =3D soft.i - real.i; + } + } + + /* glibc allows 3 ulp error in its libm-test-ulps; allow 4 here */ + if (!exact && ulp <=3D 4) { + return; + } + =20 + printf("test: %016" PRIx64 " %+.13a\n" + " sf: %016" PRIx64 " %+.13a\n" + "libm: %016" PRIx64 " %+.13a\n", + test.i, test.d, soft.i, soft.d, real.i, real.d); + + if (msb =3D=3D 63) { + printf("Error in sign!\n\n"); + } else if (msb >=3D 52) { + printf("Error in exponent: %d\n\n", + (int)(soft.i >> 52) - (int)(real.i >> 52)); + } else { + printf("Error in fraction: %" PRIu64 " ulp\n\n", ulp); + } + + if (++errors =3D=3D 20) { + exit(1); + } +} + +int main(int ac, char **av) +{ + ufloat64 test, real, soft; + float_status qsf =3D {0}; + int i; + + set_float_rounding_mode(float_round_nearest_even, &qsf); + + test.d =3D 0.0; + real.d =3D -__builtin_inf(); + soft.i =3D float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d =3D 1.0; + real.d =3D 0.0; + soft.i =3D float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d =3D 2.0; + real.d =3D 1.0; + soft.i =3D float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d =3D 4.0; + real.d =3D 2.0; + soft.i =3D float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d =3D 0x1p64; + real.d =3D 64.0; + soft.i =3D float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d =3D __builtin_inf(); + real.d =3D __builtin_inf(); + soft.i =3D float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + for (i =3D 0; i < 10000; ++i) { + test.d =3D drand48() + 1.0; /* [1.0, 2.0) */ + real.d =3D log2(test.d); + soft.i =3D float64_log2(test.i, &qsf); + compare(test, real, soft, false); + + test.d =3D drand48() * 100; /* [0.0, 100) */ + real.d =3D log2(test.d); + soft.i =3D float64_log2(test.i, &qsf); + compare(test, real, soft, false); + } + + return 0; +} diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index 8a7f22d6b5..3fd6d97fa4 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1331,3 +1331,128 @@ static void partsN(scalbn)(FloatPartsN *a, int n, f= loat_status *s) g_assert_not_reached(); } } + +/* + * Return log2(A) + */ +static void partsN(log2)(FloatPartsN *a, float_status *s, const FloatFmt *= fmt) +{ + uint64_t a0, a1, r, t, ign; + FloatPartsN f; + int i, n, a_exp, f_exp; + + if (unlikely(a->cls !=3D float_class_normal)) { + switch (a->cls) { + case float_class_snan: + case float_class_qnan: + parts_return_nan(a, s); + return; + case float_class_zero: + /* log2(0) =3D -inf */ + a->cls =3D float_class_inf; + a->sign =3D 1; + return; + case float_class_inf: + if (unlikely(a->sign)) { + goto d_nan; + } + return; + default: + break; + } + g_assert_not_reached(); + } + if (unlikely(a->sign)) { + goto d_nan; + } + + /* TODO: This algorithm looses bits too quickly for float128. */ + g_assert(N =3D=3D 64); + + a_exp =3D a->exp; + f_exp =3D -1; + + r =3D 0; + t =3D DECOMPOSED_IMPLICIT_BIT; + a0 =3D a->frac_hi; + a1 =3D 0; + + n =3D fmt->frac_size + 2; + if (unlikely(a_exp =3D=3D -1)) { + /* + * When a_exp =3D=3D -1, we're computing the log2 of a value [0.5,= 1.0). + * When the value is very close to 1.0, there are lots of 1's in + * the msb parts of the fraction. At the end, when we subtract + * this value from -1.0, we can see a catastrophic loss of precisi= on, + * as 0x800..000 - 0x7ff..ffx becomes 0x000..00y, leaving only the + * bits of y in the final result. To minimize this, compute as ma= ny + * digits as we can. + * ??? This case needs another algorithm to avoid this. + */ + n =3D fmt->frac_size * 2 + 2; + /* Don't compute a value overlapping the sticky bit */ + n =3D MIN(n, 62); + } + + for (i =3D 0; i < n; i++) { + if (a1) { + mul128To256(a0, a1, a0, a1, &a0, &a1, &ign, &ign); + } else if (a0 & 0xffffffffull) { + mul64To128(a0, a0, &a0, &a1); + } else if (a0 & ~DECOMPOSED_IMPLICIT_BIT) { + a0 >>=3D 32; + a0 *=3D a0; + } else { + goto exact; + } + + if (a0 & DECOMPOSED_IMPLICIT_BIT) { + if (unlikely(a_exp =3D=3D 0 && r =3D=3D 0)) { + /* + * When a_exp =3D=3D 0, we're computing the log2 of a value + * [1.0,2.0). When the value is very close to 1.0, there + * are lots of 0's in the msb parts of the fraction. + * We need to compute more digits to produce a correct + * result -- restart at the top of the fraction. + * ??? This is likely to lose precision quickly, as for + * float128; we may need another method. + */ + f_exp -=3D i; + t =3D r =3D DECOMPOSED_IMPLICIT_BIT; + i =3D 0; + } else { + r |=3D t; + } + } else { + add128(a0, a1, a0, a1, &a0, &a1); + } + t >>=3D 1; + } + + /* Set sticky for inexact. */ + r |=3D (a1 || a0 & ~DECOMPOSED_IMPLICIT_BIT); + + exact: + parts_sint_to_float(a, a_exp, 0, s); + if (r =3D=3D 0) { + return; + } + + memset(&f, 0, sizeof(f)); + f.cls =3D float_class_normal; + f.frac_hi =3D r; + f.exp =3D f_exp - frac_normalize(&f); + + if (a_exp < 0) { + parts_sub_normal(a, &f); + } else if (a_exp > 0) { + parts_add_normal(a, &f); + } else { + *a =3D f; + } + return; + + d_nan: + float_raise(float_flag_invalid, s); + parts_default_nan(a, s); +} diff --git a/tests/fp/meson.build b/tests/fp/meson.build index 1c3eee9955..9218bfd3b0 100644 --- a/tests/fp/meson.build +++ b/tests/fp/meson.build @@ -634,3 +634,14 @@ fpbench =3D executable( include_directories: [sfinc, include_directories(tfdir)], c_args: fpcflags, ) + +fptestlog2 =3D executable( + 'fp-test-log2', + ['fp-test-log2.c', '../../fpu/softfloat.c'], + link_with: [libsoftfloat], + dependencies: [qemuutil], + include_directories: [sfinc], + c_args: fpcflags, +) +test('fp-test-log2', fptestlog2, + suite: ['softfloat', 'softfloat-ops']) --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621961339; cv=none; d=zohomail.com; s=zohoarc; b=ESphnV4zSjZfVyZpBpNSmMxN2nB6XUIg7Da0PP2gVBUpivKcCvFmMLwFHARJPHbd7DnUd/XoFRSYaMli+lKU/n8RZRFfsB1BWXJz7DFduQQQwH0j3emjnqNAoCSbP7EeW75Un3UOryUo04isxNg8ks6jv2SssySkEYzl+ALTwQU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621961339; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=WhF1IZko0dh1L7wch1lEVaycxOtRYGGaXM4qmB4c8Jw=; b=Ci70BF9XVYVihrAKr7tRpPrgmZCISs9L4zpLzaWUC2ftBHR+pF6Lm3nB/swYSK0dQ/sXRKIi3ASziYhlMeG9NsbB3/ECUq/AfvuMF8F+58Qg8zDsn1BDKTqgpP1slX6ugLEeId5VOy7gH3xBGCbkHoJIzHOWYjFBEs+DjfhgV9k= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621961339114916.096833524171; Tue, 25 May 2021 09:48:59 -0700 (PDT) Received: from localhost ([::1]:57408 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llaEj-0002S3-KO for importer@patchew.org; Tue, 25 May 2021 12:48:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60722) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYer-0002YX-Sm for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:49 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]:55252) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeW-0006nS-Gs for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:49 -0400 Received: by mail-pj1-x102f.google.com with SMTP id g24so16993140pji.4 for ; Tue, 25 May 2021 08:07:26 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WhF1IZko0dh1L7wch1lEVaycxOtRYGGaXM4qmB4c8Jw=; b=WvkHqyx0Eqt1NaB9sWKfCrch/4EkNz+X7RN5XqKP76+Su+lXe7/2PlAlLK6CwVlL5b XkfUhWhVk0hqosWchK86TxynMjQwezNBa+ZpxuC8iJVT6Q6kvLZJ0ex0G/YNZe+85uDQ HFl/8hTXHTZ5bfszgssCSIfbK1iX6nQQ1KrnFGvgTvNNunjARjZXy3GLkAyyVC6bLEZU OIPLmOK9LVSDWiUEP4gqyLrhA97BqFCUQJBnpZS7yXTqsIvQiZGyxl/y901F5N/jix0z hr3w69VnUkGgouZggNp5SI4Nr5bOERfiDW1kBrRvtShkiX5iJlZGsPBffobxpapAnnCU kOKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WhF1IZko0dh1L7wch1lEVaycxOtRYGGaXM4qmB4c8Jw=; b=SGptxK3v910aIVeYqkqr4zp4/s4qqk3t8CT8Vd+N+/y2UJucYQYQ/o4KKZeAnbikrb K1BQMmfTqcPeOCs9McWF965Z2v9Tid2JzBiLnjxElssChBJLJ+SVKarLFuIWmiTRENMC ykJYc/fSKvnRi1csMTapr7Vq0IVpPxs2bK8xUWPk/t6Aj9dZ6DcDACPWIGmzmizjbsB2 JebWoybchxzXdjnB/4WUZgnpb9bfGPnXEdlKlKHOKe3+grH/qXOR7/QrHMQymq8VJL/R bvBV1Hp5rTJ73ose62cgTmfoIZaJvYeK9L6/QAIZB1C2O1pdHq85u4lT529U1raP8NVt nC2g== X-Gm-Message-State: AOAM530YsQcbK54g41RCypAE9C6O0CfYDZk8zscJ/Q9VB2Ur7cbmSpWT 8JkbtlmjWbDvs9llSD7OZTc3CCvpOn4PnA== X-Google-Smtp-Source: ABdhPJyFGokjfczeXIzi4CdcMUzskOi4GAhToNe3cYcRBLmS4buXJ8HyAzbTHRsQVhB8mEx+qfO7Mg== X-Received: by 2002:a17:902:c784:b029:ef:b14e:2b0b with SMTP id w4-20020a170902c784b02900efb14e2b0bmr31381059pla.64.1621955244743; Tue, 25 May 2021 08:07:24 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 26/28] softfloat: Convert modrem operations to FloatParts Date: Tue, 25 May 2021 08:07:04 -0700 Message-Id: <20210525150706.294968-27-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102f.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Rename to parts$N_modrem. This was the last use of a lot of the legacy infrastructure, so remove it as required. Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- include/fpu/softfloat-macros.h | 34 + fpu/softfloat.c | 1339 +++++++------------------------- fpu/softfloat-parts.c.inc | 34 + fpu/softfloat-specialize.c.inc | 165 ---- 4 files changed, 329 insertions(+), 1243 deletions(-) diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index ec4e27a595..81c3fe8256 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -745,4 +745,38 @@ static inline bool ne128(uint64_t a0, uint64_t a1, uin= t64_t b0, uint64_t b1) return a0 !=3D b0 || a1 !=3D b1; } =20 +/* + * Similarly, comparisons of 192-bit values. + */ + +static inline bool eq192(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t b0, uint64_t b1, uint64_t b2) +{ + return ((a0 ^ b0) | (a1 ^ b1) | (a2 ^ b2)) =3D=3D 0; +} + +static inline bool le192(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t b0, uint64_t b1, uint64_t b2) +{ + if (a0 !=3D b0) { + return a0 < b0; + } + if (a1 !=3D b1) { + return a1 < b1; + } + return a2 <=3D b2; +} + +static inline bool lt192(uint64_t a0, uint64_t a1, uint64_t a2, + uint64_t b0, uint64_t b1, uint64_t b2) +{ + if (a0 !=3D b0) { + return a0 < b0; + } + if (a1 !=3D b1) { + return a1 < b1; + } + return a2 < b2; +} + #endif diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6d2f606b39..b0df5b6dc5 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -401,60 +401,6 @@ float64_gen2(float64 xa, float64 xb, float_status *s, return soft(ua.s, ub.s, s); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the fraction bits of the single-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline uint32_t extractFloat32Frac(float32 a) -{ - return float32_val(a) & 0x007FFFFF; -} - -/*------------------------------------------------------------------------= ---- -| Returns the exponent bits of the single-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline int extractFloat32Exp(float32 a) -{ - return (float32_val(a) >> 23) & 0xFF; -} - -/*------------------------------------------------------------------------= ---- -| Returns the sign bit of the single-precision floating-point value `a'. -*-------------------------------------------------------------------------= ---*/ - -static inline bool extractFloat32Sign(float32 a) -{ - return float32_val(a) >> 31; -} - -/*------------------------------------------------------------------------= ---- -| Returns the fraction bits of the double-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline uint64_t extractFloat64Frac(float64 a) -{ - return float64_val(a) & UINT64_C(0x000FFFFFFFFFFFFF); -} - -/*------------------------------------------------------------------------= ---- -| Returns the exponent bits of the double-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline int extractFloat64Exp(float64 a) -{ - return (float64_val(a) >> 52) & 0x7FF; -} - -/*------------------------------------------------------------------------= ---- -| Returns the sign bit of the double-precision floating-point value `a'. -*-------------------------------------------------------------------------= ---*/ - -static inline bool extractFloat64Sign(float64 a) -{ - return float64_val(a) >> 63; -} - /* * Classify a floating point number. Everything above float_class_qnan * is a NaN so cls >=3D float_class_qnan is any NaN. @@ -845,6 +791,14 @@ static FloatParts128 *parts128_div(FloatParts128 *a, F= loatParts128 *b, #define parts_div(A, B, S) \ PARTS_GENERIC_64_128(div, A)(A, B, S) =20 +static FloatParts64 *parts64_modrem(FloatParts64 *a, FloatParts64 *b, + uint64_t *mod_quot, float_status *s); +static FloatParts128 *parts128_modrem(FloatParts128 *a, FloatParts128 *b, + uint64_t *mod_quot, float_status *s); + +#define parts_modrem(A, B, Q, S) \ + PARTS_GENERIC_64_128(modrem, A)(A, B, Q, S) + static void parts64_sqrt(FloatParts64 *a, float_status *s, const FloatFmt = *f); static void parts128_sqrt(FloatParts128 *a, float_status *s, const FloatFm= t *f); =20 @@ -1229,6 +1183,186 @@ static int frac256_normalize(FloatParts256 *a) =20 #define frac_normalize(A) FRAC_GENERIC_64_128_256(normalize, A)(A) =20 +static void frac64_modrem(FloatParts64 *a, FloatParts64 *b, uint64_t *mod_= quot) +{ + uint64_t a0, a1, b0, t0, t1, q, quot; + int exp_diff =3D a->exp - b->exp; + int shift; + + a0 =3D a->frac; + a1 =3D 0; + + if (exp_diff < -1) { + if (mod_quot) { + *mod_quot =3D 0; + } + return; + } + if (exp_diff =3D=3D -1) { + a0 >>=3D 1; + exp_diff =3D 0; + } + + b0 =3D b->frac; + quot =3D q =3D b0 <=3D a0; + if (q) { + a0 -=3D b0; + } + + exp_diff -=3D 64; + while (exp_diff > 0) { + q =3D estimateDiv128To64(a0, a1, b0); + q =3D q > 2 ? q - 2 : 0; + mul64To128(b0, q, &t0, &t1); + sub128(a0, a1, t0, t1, &a0, &a1); + shortShift128Left(a0, a1, 62, &a0, &a1); + exp_diff -=3D 62; + quot =3D (quot << 62) + q; + } + + exp_diff +=3D 64; + if (exp_diff > 0) { + q =3D estimateDiv128To64(a0, a1, b0); + q =3D q > 2 ? (q - 2) >> (64 - exp_diff) : 0; + mul64To128(b0, q << (64 - exp_diff), &t0, &t1); + sub128(a0, a1, t0, t1, &a0, &a1); + shortShift128Left(0, b0, 64 - exp_diff, &t0, &t1); + while (le128(t0, t1, a0, a1)) { + ++q; + sub128(a0, a1, t0, t1, &a0, &a1); + } + quot =3D (exp_diff < 64 ? quot << exp_diff : 0) + q; + } else { + t0 =3D b0; + t1 =3D 0; + } + + if (mod_quot) { + *mod_quot =3D quot; + } else { + sub128(t0, t1, a0, a1, &t0, &t1); + if (lt128(t0, t1, a0, a1) || + (eq128(t0, t1, a0, a1) && (q & 1))) { + a0 =3D t0; + a1 =3D t1; + a->sign =3D !a->sign; + } + } + + if (likely(a0)) { + shift =3D clz64(a0); + shortShift128Left(a0, a1, shift, &a0, &a1); + } else if (likely(a1)) { + shift =3D clz64(a1); + a0 =3D a1 << shift; + a1 =3D 0; + shift +=3D 64; + } else { + a->cls =3D float_class_zero; + return; + } + + a->exp =3D b->exp + exp_diff - shift; + a->frac =3D a0 | (a1 !=3D 0); +} + +static void frac128_modrem(FloatParts128 *a, FloatParts128 *b, + uint64_t *mod_quot) +{ + uint64_t a0, a1, a2, b0, b1, t0, t1, t2, q, quot; + int exp_diff =3D a->exp - b->exp; + int shift; + + a0 =3D a->frac_hi; + a1 =3D a->frac_lo; + a2 =3D 0; + + if (exp_diff < -1) { + if (mod_quot) { + *mod_quot =3D 0; + } + return; + } + if (exp_diff =3D=3D -1) { + shift128Right(a0, a1, 1, &a0, &a1); + exp_diff =3D 0; + } + + b0 =3D b->frac_hi; + b1 =3D b->frac_lo; + + quot =3D q =3D le128(b0, b1, a0, a1); + if (q) { + sub128(a0, a1, b0, b1, &a0, &a1); + } + + exp_diff -=3D 64; + while (exp_diff > 0) { + q =3D estimateDiv128To64(a0, a1, b0); + q =3D q > 4 ? q - 4 : 0; + mul128By64To192(b0, b1, q, &t0, &t1, &t2); + sub192(a0, a1, a2, t0, t1, t2, &a0, &a1, &a2); + shortShift192Left(a0, a1, a2, 61, &a0, &a1, &a2); + exp_diff -=3D 61; + quot =3D (quot << 61) + q; + } + + exp_diff +=3D 64; + if (exp_diff > 0) { + q =3D estimateDiv128To64(a0, a1, b0); + q =3D q > 4 ? (q - 4) >> (64 - exp_diff) : 0; + mul128By64To192(b0, b1, q << (64 - exp_diff), &t0, &t1, &t2); + sub192(a0, a1, a2, t0, t1, t2, &a0, &a1, &a2); + shortShift192Left(0, b0, b1, 64 - exp_diff, &t0, &t1, &t2); + while (le192(t0, t1, t2, a0, a1, a2)) { + ++q; + sub192(a0, a1, a2, t0, t1, t2, &a0, &a1, &a2); + } + quot =3D (exp_diff < 64 ? quot << exp_diff : 0) + q; + } else { + t0 =3D b0; + t1 =3D b1; + t2 =3D 0; + } + + if (mod_quot) { + *mod_quot =3D quot; + } else { + sub192(t0, t1, t2, a0, a1, a2, &t0, &t1, &t2); + if (lt192(t0, t1, t2, a0, a1, a2) || + (eq192(t0, t1, t2, a0, a1, a2) && (q & 1))) { + a0 =3D t0; + a1 =3D t1; + a2 =3D t2; + a->sign =3D !a->sign; + } + } + + if (likely(a0)) { + shift =3D clz64(a0); + shortShift192Left(a0, a1, a2, shift, &a0, &a1, &a2); + } else if (likely(a1)) { + shift =3D clz64(a1); + shortShift128Left(a1, a2, shift, &a0, &a1); + a2 =3D 0; + shift +=3D 64; + } else if (likely(a2)) { + shift =3D clz64(a2); + a0 =3D a2 << shift; + a1 =3D a2 =3D 0; + shift +=3D 128; + } else { + a->cls =3D float_class_zero; + return; + } + + a->exp =3D b->exp + exp_diff - shift; + a->frac_hi =3D a0; + a->frac_lo =3D a1 | (a2 !=3D 0); +} + +#define frac_modrem(A, B, Q) FRAC_GENERIC_64_128(modrem, A)(A, B, Q) + static void frac64_shl(FloatParts64 *a, int c) { a->frac <<=3D c; @@ -2313,6 +2447,79 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_= status *status) return floatx80_round_pack_canonical(pr, status); } =20 +/* + * Remainder + */ + +float32 float32_rem(float32 a, float32 b, float_status *status) +{ + FloatParts64 pa, pb, *pr; + + float32_unpack_canonical(&pa, a, status); + float32_unpack_canonical(&pb, b, status); + pr =3D parts_modrem(&pa, &pb, NULL, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_rem(float64 a, float64 b, float_status *status) +{ + FloatParts64 pa, pb, *pr; + + float64_unpack_canonical(&pa, a, status); + float64_unpack_canonical(&pb, b, status); + pr =3D parts_modrem(&pa, &pb, NULL, status); + + return float64_round_pack_canonical(pr, status); +} + +float128 float128_rem(float128 a, float128 b, float_status *status) +{ + FloatParts128 pa, pb, *pr; + + float128_unpack_canonical(&pa, a, status); + float128_unpack_canonical(&pb, b, status); + pr =3D parts_modrem(&pa, &pb, NULL, status); + + return float128_round_pack_canonical(pr, status); +} + +/* + * Returns the remainder of the extended double-precision floating-point v= alue + * `a' with respect to the corresponding value `b'. + * If 'mod' is false, the operation is performed according to the IEC/IEEE + * Standard for Binary Floating-Point Arithmetic. If 'mod' is true, return + * the remainder based on truncating the quotient toward zero instead and + * *quotient is set to the low 64 bits of the absolute value of the integer + * quotient. + */ +floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod, + uint64_t *quotient, float_status *status) +{ + FloatParts128 pa, pb, *pr; + + *quotient =3D 0; + if (!floatx80_unpack_canonical(&pa, a, status) || + !floatx80_unpack_canonical(&pb, b, status)) { + return floatx80_default_nan(status); + } + pr =3D parts_modrem(&pa, &pb, mod ? quotient : NULL, status); + + return floatx80_round_pack_canonical(pr, status); +} + +floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status) +{ + uint64_t quotient; + return floatx80_modrem(a, b, false, "ient, status); +} + +floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status) +{ + uint64_t quotient; + return floatx80_modrem(a, b, true, "ient, status); +} + /* * Float to Float conversions * @@ -4265,300 +4472,6 @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a,= float_status *status) return a; } =20 -/*------------------------------------------------------------------------= ---- -| Normalizes the subnormal single-precision floating-point value represent= ed -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*-------------------------------------------------------------------------= ---*/ - -static void - normalizeFloat32Subnormal(uint32_t aSig, int *zExpPtr, uint32_t *zSigPtr) -{ - int8_t shiftCount; - - shiftCount =3D clz32(aSig) - 8; - *zSigPtr =3D aSig<float_rounding_mode; - roundNearestEven =3D ( roundingMode =3D=3D float_round_nearest_even ); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - roundIncrement =3D 0x40; - break; - case float_round_to_zero: - roundIncrement =3D 0; - break; - case float_round_up: - roundIncrement =3D zSign ? 0 : 0x7f; - break; - case float_round_down: - roundIncrement =3D zSign ? 0x7f : 0; - break; - case float_round_to_odd: - roundIncrement =3D zSig & 0x80 ? 0 : 0x7f; - break; - default: - abort(); - break; - } - roundBits =3D zSig & 0x7F; - if ( 0xFD <=3D (uint16_t) zExp ) { - if ( ( 0xFD < zExp ) - || ( ( zExp =3D=3D 0xFD ) - && ( (int32_t) ( zSig + roundIncrement ) < 0 ) ) - ) { - bool overflow_to_inf =3D roundingMode !=3D float_round_to_odd = && - roundIncrement !=3D 0; - float_raise(float_flag_overflow | float_flag_inexact, status); - return packFloat32(zSign, 0xFF, -!overflow_to_inf); - } - if ( zExp < 0 ) { - if (status->flush_to_zero) { - float_raise(float_flag_output_denormal, status); - return packFloat32(zSign, 0, 0); - } - isTiny =3D status->tininess_before_rounding - || (zExp < -1) - || (zSig + roundIncrement < 0x80000000); - shift32RightJamming( zSig, - zExp, &zSig ); - zExp =3D 0; - roundBits =3D zSig & 0x7F; - if (isTiny && roundBits) { - float_raise(float_flag_underflow, status); - } - if (roundingMode =3D=3D float_round_to_odd) { - /* - * For round-to-odd case, the roundIncrement depends on - * zSig which just changed. - */ - roundIncrement =3D zSig & 0x80 ? 0 : 0x7f; - } - } - } - if (roundBits) { - float_raise(float_flag_inexact, status); - } - zSig =3D ( zSig + roundIncrement )>>7; - if (!(roundBits ^ 0x40) && roundNearestEven) { - zSig &=3D ~1; - } - if ( zSig =3D=3D 0 ) zExp =3D 0; - return packFloat32( zSign, zExp, zSig ); - -} - -/*------------------------------------------------------------------------= ---- -| Takes an abstract floating-point value having sign `zSign', exponent `zE= xp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. This routine is just l= ike -| `roundAndPackFloat32' except that `zSig' does not have to be normalized. -| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true= '' -| floating-point exponent. -*-------------------------------------------------------------------------= ---*/ - -static float32 - normalizeRoundAndPackFloat32(bool zSign, int zExp, uint32_t zSig, - float_status *status) -{ - int8_t shiftCount; - - shiftCount =3D clz32(zSig) - 1; - return roundAndPackFloat32(zSign, zExp - shiftCount, zSig<float_rounding_mode; - roundNearestEven =3D ( roundingMode =3D=3D float_round_nearest_even ); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - roundIncrement =3D 0x200; - break; - case float_round_to_zero: - roundIncrement =3D 0; - break; - case float_round_up: - roundIncrement =3D zSign ? 0 : 0x3ff; - break; - case float_round_down: - roundIncrement =3D zSign ? 0x3ff : 0; - break; - case float_round_to_odd: - roundIncrement =3D (zSig & 0x400) ? 0 : 0x3ff; - break; - default: - abort(); - } - roundBits =3D zSig & 0x3FF; - if ( 0x7FD <=3D (uint16_t) zExp ) { - if ( ( 0x7FD < zExp ) - || ( ( zExp =3D=3D 0x7FD ) - && ( (int64_t) ( zSig + roundIncrement ) < 0 ) ) - ) { - bool overflow_to_inf =3D roundingMode !=3D float_round_to_odd = && - roundIncrement !=3D 0; - float_raise(float_flag_overflow | float_flag_inexact, status); - return packFloat64(zSign, 0x7FF, -(!overflow_to_inf)); - } - if ( zExp < 0 ) { - if (status->flush_to_zero) { - float_raise(float_flag_output_denormal, status); - return packFloat64(zSign, 0, 0); - } - isTiny =3D status->tininess_before_rounding - || (zExp < -1) - || (zSig + roundIncrement < UINT64_C(0x8000000000000000)= ); - shift64RightJamming( zSig, - zExp, &zSig ); - zExp =3D 0; - roundBits =3D zSig & 0x3FF; - if (isTiny && roundBits) { - float_raise(float_flag_underflow, status); - } - if (roundingMode =3D=3D float_round_to_odd) { - /* - * For round-to-odd case, the roundIncrement depends on - * zSig which just changed. - */ - roundIncrement =3D (zSig & 0x400) ? 0 : 0x3ff; - } - } - } - if (roundBits) { - float_raise(float_flag_inexact, status); - } - zSig =3D ( zSig + roundIncrement )>>10; - if (!(roundBits ^ 0x200) && roundNearestEven) { - zSig &=3D ~1; - } - if ( zSig =3D=3D 0 ) zExp =3D 0; - return packFloat64( zSign, zExp, zSig ); - -} - -/*------------------------------------------------------------------------= ---- -| Takes an abstract floating-point value having sign `zSign', exponent `zE= xp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. This routine is just l= ike -| `roundAndPackFloat64' except that `zSig' does not have to be normalized. -| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true= '' -| floating-point exponent. -*-------------------------------------------------------------------------= ---*/ - -static float64 - normalizeRoundAndPackFloat64(bool zSign, int zExp, uint64_t zSig, - float_status *status) -{ - int8_t shiftCount; - - shiftCount =3D clz64(zSig) - 1; - return roundAndPackFloat64(zSign, zExp - shiftCount, zSig<>48 ) & 0x7FFF; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the sign bit of the quadruple-precision floating-point value `a'. -*-------------------------------------------------------------------------= ---*/ - -static inline bool extractFloat128Sign(float128 a) -{ - return a.high >> 63; -} - -/*------------------------------------------------------------------------= ---- -| Normalizes the subnormal quadruple-precision floating-point value -| represented by the denormalized significand formed by the concatenation = of -| `aSig0' and `aSig1'. The normalized exponent is stored at the location -| pointed to by `zExpPtr'. The most significant 49 bits of the normalized -| significand are stored at the location pointed to by `zSig0Ptr', and the -| least significant 64 bits of the normalized significand are stored at the -| location pointed to by `zSig1Ptr'. -*-------------------------------------------------------------------------= ---*/ - -static void - normalizeFloat128Subnormal( - uint64_t aSig0, - uint64_t aSig1, - int32_t *zExpPtr, - uint64_t *zSig0Ptr, - uint64_t *zSig1Ptr - ) -{ - int8_t shiftCount; - - if ( aSig0 =3D=3D 0 ) { - shiftCount =3D clz64(aSig1) - 15; - if ( shiftCount < 0 ) { - *zSig0Ptr =3D aSig1>>( - shiftCount ); - *zSig1Ptr =3D aSig1<<( shiftCount & 63 ); - } - else { - *zSig0Ptr =3D aSig1<float_rounding_mode; - roundNearestEven =3D ( roundingMode =3D=3D float_round_nearest_even ); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - increment =3D ((int64_t)zSig2 < 0); - break; - case float_round_to_zero: - increment =3D 0; - break; - case float_round_up: - increment =3D !zSign && zSig2; - break; - case float_round_down: - increment =3D zSign && zSig2; - break; - case float_round_to_odd: - increment =3D !(zSig1 & 0x1) && zSig2; - break; - default: - abort(); - } - if ( 0x7FFD <=3D (uint32_t) zExp ) { - if ( ( 0x7FFD < zExp ) - || ( ( zExp =3D=3D 0x7FFD ) - && eq128( - UINT64_C(0x0001FFFFFFFFFFFF), - UINT64_C(0xFFFFFFFFFFFFFFFF), - zSig0, - zSig1 - ) - && increment - ) - ) { - float_raise(float_flag_overflow | float_flag_inexact, status); - if ( ( roundingMode =3D=3D float_round_to_zero ) - || ( zSign && ( roundingMode =3D=3D float_round_up ) ) - || ( ! zSign && ( roundingMode =3D=3D float_round_down ) ) - || (roundingMode =3D=3D float_round_to_odd) - ) { - return - packFloat128( - zSign, - 0x7FFE, - UINT64_C(0x0000FFFFFFFFFFFF), - UINT64_C(0xFFFFFFFFFFFFFFFF) - ); - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( zExp < 0 ) { - if (status->flush_to_zero) { - float_raise(float_flag_output_denormal, status); - return packFloat128(zSign, 0, 0, 0); - } - isTiny =3D status->tininess_before_rounding - || (zExp < -1) - || !increment - || lt128(zSig0, zSig1, - UINT64_C(0x0001FFFFFFFFFFFF), - UINT64_C(0xFFFFFFFFFFFFFFFF)); - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 ); - zExp =3D 0; - if (isTiny && zSig2) { - float_raise(float_flag_underflow, status); - } - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - increment =3D ((int64_t)zSig2 < 0); - break; - case float_round_to_zero: - increment =3D 0; - break; - case float_round_up: - increment =3D !zSign && zSig2; - break; - case float_round_down: - increment =3D zSign && zSig2; - break; - case float_round_to_odd: - increment =3D !(zSig1 & 0x1) && zSig2; - break; - default: - abort(); - } - } - } - if (zSig2) { - float_raise(float_flag_inexact, status); - } - if ( increment ) { - add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 ); - if ((zSig2 + zSig2 =3D=3D 0) && roundNearestEven) { - zSig1 &=3D ~1; - } - } - else { - if ( ( zSig0 | zSig1 ) =3D=3D 0 ) zExp =3D 0; - } - return packFloat128( zSign, zExp, zSig0, zSig1 ); - -} - -/*------------------------------------------------------------------------= ---- -| Takes an abstract floating-point value having sign `zSign', exponent `zE= xp', -| and significand formed by the concatenation of `zSig0' and `zSig1', and -| returns the proper quadruple-precision floating-point value corresponding -| to the abstract input. This routine is just like `roundAndPackFloat128' -| except that the input significand has fewer bits and does not have to be -| normalized. In all cases, `zExp' must be 1 less than the ``true'' float= ing- -| point exponent. -*-------------------------------------------------------------------------= ---*/ - -static float128 normalizeRoundAndPackFloat128(bool zSign, int32_t zExp, - uint64_t zSig0, uint64_t zSi= g1, - float_status *status) -{ - int8_t shiftCount; - uint64_t zSig2; - - if ( zSig0 =3D=3D 0 ) { - zSig0 =3D zSig1; - zSig1 =3D 0; - zExp -=3D 64; - } - shiftCount =3D clz64(zSig0) - 15; - if ( 0 <=3D shiftCount ) { - zSig2 =3D 0; - shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); - } - else { - shift128ExtraRightJamming( - zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 ); - } - zExp -=3D shiftCount; - return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the remainder of the single-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_rem(float32 a, float32 b, float_status *status) -{ - bool aSign, zSign; - int aExp, bExp, expDiff; - uint32_t aSig, bSig; - uint32_t q; - uint64_t aSig64, bSig64, q64; - uint32_t alternateASig; - int32_t sigMean; - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - bSig =3D extractFloat32Frac( b ); - bExp =3D extractFloat32Exp( b ); - if ( aExp =3D=3D 0xFF ) { - if ( aSig || ( ( bExp =3D=3D 0xFF ) && bSig ) ) { - return propagateFloat32NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return a; - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - expDiff =3D aExp - bExp; - aSig |=3D 0x00800000; - bSig |=3D 0x00800000; - if ( expDiff < 32 ) { - aSig <<=3D 8; - bSig <<=3D 8; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - aSig >>=3D 1; - } - q =3D ( bSig <=3D aSig ); - if ( q ) aSig -=3D bSig; - if ( 0 < expDiff ) { - q =3D ( ( (uint64_t) aSig )<<32 ) / bSig; - q >>=3D 32 - expDiff; - bSig >>=3D 2; - aSig =3D ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; - } - else { - aSig >>=3D 2; - bSig >>=3D 2; - } - } - else { - if ( bSig <=3D aSig ) aSig -=3D bSig; - aSig64 =3D ( (uint64_t) aSig )<<40; - bSig64 =3D ( (uint64_t) bSig )<<40; - expDiff -=3D 64; - while ( 0 < expDiff ) { - q64 =3D estimateDiv128To64( aSig64, 0, bSig64 ); - q64 =3D ( 2 < q64 ) ? q64 - 2 : 0; - aSig64 =3D - ( ( bSig * q64 )<<38 ); - expDiff -=3D 62; - } - expDiff +=3D 64; - q64 =3D estimateDiv128To64( aSig64, 0, bSig64 ); - q64 =3D ( 2 < q64 ) ? q64 - 2 : 0; - q =3D q64>>( 64 - expDiff ); - bSig <<=3D 6; - aSig =3D ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q; - } - do { - alternateASig =3D aSig; - ++q; - aSig -=3D bSig; - } while ( 0 <=3D (int32_t) aSig ); - sigMean =3D aSig + alternateASig; - if ( ( sigMean < 0 ) || ( ( sigMean =3D=3D 0 ) && ( q & 1 ) ) ) { - aSig =3D alternateASig; - } - zSign =3D ( (int32_t) aSig < 0 ); - if ( zSign ) aSig =3D - aSig; - return normalizeRoundAndPackFloat32(aSign ^ zSign, bExp, aSig, status); -} - - - /*------------------------------------------------------------------------= ---- | Returns the binary exponential of the single-precision floating-point va= lue | `a'. The operation is performed according to the IEC/IEEE Standard for @@ -5276,94 +4807,6 @@ float32 float32_exp2(float32 a, float_status *status) return float32_round_pack_canonical(&rp, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the remainder of the double-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_rem(float64 a, float64 b, float_status *status) -{ - bool aSign, zSign; - int aExp, bExp, expDiff; - uint64_t aSig, bSig; - uint64_t q, alternateASig; - int64_t sigMean; - - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - bSig =3D extractFloat64Frac( b ); - bExp =3D extractFloat64Exp( b ); - if ( aExp =3D=3D 0x7FF ) { - if ( aSig || ( ( bExp =3D=3D 0x7FF ) && bSig ) ) { - return propagateFloat64NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return a; - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - expDiff =3D aExp - bExp; - aSig =3D (aSig | UINT64_C(0x0010000000000000)) << 11; - bSig =3D (bSig | UINT64_C(0x0010000000000000)) << 11; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - aSig >>=3D 1; - } - q =3D ( bSig <=3D aSig ); - if ( q ) aSig -=3D bSig; - expDiff -=3D 64; - while ( 0 < expDiff ) { - q =3D estimateDiv128To64( aSig, 0, bSig ); - q =3D ( 2 < q ) ? q - 2 : 0; - aSig =3D - ( ( bSig>>2 ) * q ); - expDiff -=3D 62; - } - expDiff +=3D 64; - if ( 0 < expDiff ) { - q =3D estimateDiv128To64( aSig, 0, bSig ); - q =3D ( 2 < q ) ? q - 2 : 0; - q >>=3D 64 - expDiff; - bSig >>=3D 2; - aSig =3D ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; - } - else { - aSig >>=3D 2; - bSig >>=3D 2; - } - do { - alternateASig =3D aSig; - ++q; - aSig -=3D bSig; - } while ( 0 <=3D (int64_t) aSig ); - sigMean =3D aSig + alternateASig; - if ( ( sigMean < 0 ) || ( ( sigMean =3D=3D 0 ) && ( q & 1 ) ) ) { - aSig =3D alternateASig; - } - zSign =3D ( (int64_t) aSig < 0 ); - if ( zSign ) aSig =3D - aSig; - return normalizeRoundAndPackFloat64(aSign ^ zSign, bExp, aSig, status); - -} - /*------------------------------------------------------------------------= ---- | Rounds the extended double-precision floating-point value `a' | to the precision provided by floatx80_rounding_precision and returns the @@ -5382,266 +4825,6 @@ floatx80 floatx80_round(floatx80 a, float_status *s= tatus) return floatx80_round_pack_canonical(&p, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the remainder of the extended double-precision floating-point va= lue -| `a' with respect to the corresponding value `b'. The operation is perfo= rmed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic, -| if 'mod' is false; if 'mod' is true, return the remainder based on trunc= ating -| the quotient toward zero instead. '*quotient' is set to the low 64 bits= of -| the absolute value of the integer quotient. -*-------------------------------------------------------------------------= ---*/ - -floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod, uint64_t *quoti= ent, - float_status *status) -{ - bool aSign, zSign; - int32_t aExp, bExp, expDiff, aExpOrig; - uint64_t aSig0, aSig1, bSig; - uint64_t q, term0, term1, alternateASig0, alternateASig1; - - *quotient =3D 0; - if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) { - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - aSig0 =3D extractFloatx80Frac( a ); - aExpOrig =3D aExp =3D extractFloatx80Exp( a ); - aSign =3D extractFloatx80Sign( a ); - bSig =3D extractFloatx80Frac( b ); - bExp =3D extractFloatx80Exp( b ); - if ( aExp =3D=3D 0x7FFF ) { - if ( (uint64_t) ( aSig0<<1 ) - || ( ( bExp =3D=3D 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) { - return propagateFloatx80NaN(a, b, status); - } - goto invalid; - } - if ( bExp =3D=3D 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - if (aExp =3D=3D 0 && aSig0 >> 63) { - /* - * Pseudo-denormal argument must be returned in normalized - * form. - */ - return packFloatx80(aSign, 1, aSig0); - } - return a; - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) { - invalid: - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig0 =3D=3D 0 ) return a; - normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); - } - zSign =3D aSign; - expDiff =3D aExp - bExp; - aSig1 =3D 0; - if ( expDiff < 0 ) { - if ( mod || expDiff < -1 ) { - if (aExp =3D=3D 1 && aExpOrig =3D=3D 0) { - /* - * Pseudo-denormal argument must be returned in - * normalized form. - */ - return packFloatx80(aSign, aExp, aSig0); - } - return a; - } - shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); - expDiff =3D 0; - } - *quotient =3D q =3D ( bSig <=3D aSig0 ); - if ( q ) aSig0 -=3D bSig; - expDiff -=3D 64; - while ( 0 < expDiff ) { - q =3D estimateDiv128To64( aSig0, aSig1, bSig ); - q =3D ( 2 < q ) ? q - 2 : 0; - mul64To128( bSig, q, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 ); - expDiff -=3D 62; - *quotient <<=3D 62; - *quotient +=3D q; - } - expDiff +=3D 64; - if ( 0 < expDiff ) { - q =3D estimateDiv128To64( aSig0, aSig1, bSig ); - q =3D ( 2 < q ) ? q - 2 : 0; - q >>=3D 64 - expDiff; - mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 ); - while ( le128( term0, term1, aSig0, aSig1 ) ) { - ++q; - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - } - if (expDiff < 64) { - *quotient <<=3D expDiff; - } else { - *quotient =3D 0; - } - *quotient +=3D q; - } - else { - term1 =3D 0; - term0 =3D bSig; - } - if (!mod) { - sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASi= g1 ); - if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) - || ( eq128( alternateASig0, alternateASig1, aSig0, aSig= 1 ) - && ( q & 1 ) ) - ) { - aSig0 =3D alternateASig0; - aSig1 =3D alternateASig1; - zSign =3D ! zSign; - ++*quotient; - } - } - return - normalizeRoundAndPackFloatx80( - floatx80_precision_x, zSign, bExp + expDiff, aSig0, aSig1, sta= tus); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the remainder of the extended double-precision floating-point va= lue -| `a' with respect to the corresponding value `b'. The operation is perfo= rmed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status) -{ - uint64_t quotient; - return floatx80_modrem(a, b, false, "ient, status); -} - -/*------------------------------------------------------------------------= ---- -| Returns the remainder of the extended double-precision floating-point va= lue -| `a' with respect to the corresponding value `b', with the quotient trunc= ated -| toward zero. -*-------------------------------------------------------------------------= ---*/ - -floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status) -{ - uint64_t quotient; - return floatx80_modrem(a, b, true, "ient, status); -} - -/*------------------------------------------------------------------------= ---- -| Returns the remainder of the quadruple-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float128 float128_rem(float128 a, float128 b, float_status *status) -{ - bool aSign, zSign; - int32_t aExp, bExp, expDiff; - uint64_t aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; - uint64_t allZero, alternateASig0, alternateASig1, sigMean1; - int64_t sigMean0; - - aSig1 =3D extractFloat128Frac1( a ); - aSig0 =3D extractFloat128Frac0( a ); - aExp =3D extractFloat128Exp( a ); - aSign =3D extractFloat128Sign( a ); - bSig1 =3D extractFloat128Frac1( b ); - bSig0 =3D extractFloat128Frac0( b ); - bExp =3D extractFloat128Exp( b ); - if ( aExp =3D=3D 0x7FFF ) { - if ( ( aSig0 | aSig1 ) - || ( ( bExp =3D=3D 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { - return propagateFloat128NaN(a, b, status); - } - goto invalid; - } - if ( bExp =3D=3D 0x7FFF ) { - if (bSig0 | bSig1) { - return propagateFloat128NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - if ( ( bSig0 | bSig1 ) =3D=3D 0 ) { - invalid: - float_raise(float_flag_invalid, status); - return float128_default_nan(status); - } - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - if ( aExp =3D=3D 0 ) { - if ( ( aSig0 | aSig1 ) =3D=3D 0 ) return a; - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - expDiff =3D aExp - bExp; - if ( expDiff < -1 ) return a; - shortShift128Left( - aSig0 | UINT64_C(0x0001000000000000), - aSig1, - 15 - ( expDiff < 0 ), - &aSig0, - &aSig1 - ); - shortShift128Left( - bSig0 | UINT64_C(0x0001000000000000), bSig1, 15, &bSig0, &bSig1 ); - q =3D le128( bSig0, bSig1, aSig0, aSig1 ); - if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - expDiff -=3D 64; - while ( 0 < expDiff ) { - q =3D estimateDiv128To64( aSig0, aSig1, bSig0 ); - q =3D ( 4 < q ) ? q - 4 : 0; - mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); - shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZe= ro ); - shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero ); - sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 ); - expDiff -=3D 61; - } - if ( -64 < expDiff ) { - q =3D estimateDiv128To64( aSig0, aSig1, bSig0 ); - q =3D ( 4 < q ) ? q - 4 : 0; - q >>=3D - expDiff; - shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); - expDiff +=3D 52; - if ( expDiff < 0 ) { - shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); - } - else { - shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 ); - } - mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); - sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 ); - } - else { - shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 ); - shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); - } - do { - alternateASig0 =3D aSig0; - alternateASig1 =3D aSig1; - ++q; - sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - } while ( 0 <=3D (int64_t) aSig0 ); - add128( - aSig0, aSig1, alternateASig0, alternateASig1, (uint64_t *)&sigMean= 0, &sigMean1 ); - if ( ( sigMean0 < 0 ) - || ( ( ( sigMean0 | sigMean1 ) =3D=3D 0 ) && ( q & 1 ) ) ) { - aSig0 =3D alternateASig0; - aSig1 =3D alternateASig1; - } - zSign =3D ( (int64_t) aSig0 < 0 ); - if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); - return normalizeRoundAndPackFloat128(aSign ^ zSign, bExp - 4, aSig0, a= Sig1, - status); -} static void __attribute__((constructor)) softfloat_init(void) { union_float64 ua, ub, uc, ur; diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index 3fd6d97fa4..801aa86ff9 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -625,6 +625,40 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatP= artsN *b, return a; } =20 +/* + * Floating point remainder, per IEC/IEEE, or modulus. + */ +static FloatPartsN *partsN(modrem)(FloatPartsN *a, FloatPartsN *b, + uint64_t *mod_quot, float_status *s) +{ + int ab_mask =3D float_cmask(a->cls) | float_cmask(b->cls); + + if (likely(ab_mask =3D=3D float_cmask_normal)) { + frac_modrem(a, b, mod_quot); + return a; + } + + if (mod_quot) { + *mod_quot =3D 0; + } + + /* All the NaN cases */ + if (unlikely(ab_mask & float_cmask_anynan)) { + return parts_pick_nan(a, b, s); + } + + /* Inf % N; N % 0 */ + if (a->cls =3D=3D float_class_inf || b->cls =3D=3D float_class_zero) { + float_raise(float_flag_invalid, s); + parts_default_nan(a, s); + return a; + } + + /* N % Inf; 0 % N */ + g_assert(b->cls =3D=3D float_class_inf || a->cls =3D=3D float_class_ze= ro); + return a; +} + /* * Square Root * diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc index 95e5325f67..12467bb9bb 100644 --- a/fpu/softfloat-specialize.c.inc +++ b/fpu/softfloat-specialize.c.inc @@ -641,62 +641,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass = b_cls, FloatClass c_cls, #endif } =20 -/*------------------------------------------------------------------------= ---- -| Takes two single-precision floating-point values `a' and `b', one of whi= ch -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' = is a -| signaling NaN, the invalid exception is raised. -*-------------------------------------------------------------------------= ---*/ - -static float32 propagateFloat32NaN(float32 a, float32 b, float_status *sta= tus) -{ - bool aIsLargerSignificand; - uint32_t av, bv; - FloatClass a_cls, b_cls; - - /* This is not complete, but is good enough for pickNaN. */ - a_cls =3D (!float32_is_any_nan(a) - ? float_class_normal - : float32_is_signaling_nan(a, status) - ? float_class_snan - : float_class_qnan); - b_cls =3D (!float32_is_any_nan(b) - ? float_class_normal - : float32_is_signaling_nan(b, status) - ? float_class_snan - : float_class_qnan); - - av =3D float32_val(a); - bv =3D float32_val(b); - - if (is_snan(a_cls) || is_snan(b_cls)) { - float_raise(float_flag_invalid, status); - } - - if (status->default_nan_mode) { - return float32_default_nan(status); - } - - if ((uint32_t)(av << 1) < (uint32_t)(bv << 1)) { - aIsLargerSignificand =3D 0; - } else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) { - aIsLargerSignificand =3D 1; - } else { - aIsLargerSignificand =3D (av < bv) ? 1 : 0; - } - - if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) { - if (is_snan(b_cls)) { - return float32_silence_nan(b, status); - } - return b; - } else { - if (is_snan(a_cls)) { - return float32_silence_nan(a, status); - } - return a; - } -} - /*------------------------------------------------------------------------= ---- | Returns 1 if the double-precision floating-point value `a' is a quiet | NaN; otherwise returns 0. @@ -737,62 +681,6 @@ bool float64_is_signaling_nan(float64 a_, float_status= *status) } } =20 -/*------------------------------------------------------------------------= ---- -| Takes two double-precision floating-point values `a' and `b', one of whi= ch -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' = is a -| signaling NaN, the invalid exception is raised. -*-------------------------------------------------------------------------= ---*/ - -static float64 propagateFloat64NaN(float64 a, float64 b, float_status *sta= tus) -{ - bool aIsLargerSignificand; - uint64_t av, bv; - FloatClass a_cls, b_cls; - - /* This is not complete, but is good enough for pickNaN. */ - a_cls =3D (!float64_is_any_nan(a) - ? float_class_normal - : float64_is_signaling_nan(a, status) - ? float_class_snan - : float_class_qnan); - b_cls =3D (!float64_is_any_nan(b) - ? float_class_normal - : float64_is_signaling_nan(b, status) - ? float_class_snan - : float_class_qnan); - - av =3D float64_val(a); - bv =3D float64_val(b); - - if (is_snan(a_cls) || is_snan(b_cls)) { - float_raise(float_flag_invalid, status); - } - - if (status->default_nan_mode) { - return float64_default_nan(status); - } - - if ((uint64_t)(av << 1) < (uint64_t)(bv << 1)) { - aIsLargerSignificand =3D 0; - } else if ((uint64_t)(bv << 1) < (uint64_t)(av << 1)) { - aIsLargerSignificand =3D 1; - } else { - aIsLargerSignificand =3D (av < bv) ? 1 : 0; - } - - if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) { - if (is_snan(b_cls)) { - return float64_silence_nan(b, status); - } - return b; - } else { - if (is_snan(a_cls)) { - return float64_silence_nan(a, status); - } - return a; - } -} - /*------------------------------------------------------------------------= ---- | Returns 1 if the extended double-precision floating-point value `a' is a | quiet NaN; otherwise returns 0. This slightly differs from the same @@ -947,56 +835,3 @@ bool float128_is_signaling_nan(float128 a, float_statu= s *status) } } } - -/*------------------------------------------------------------------------= ---- -| Takes two quadruple-precision floating-point values `a' and `b', one of -| which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*-------------------------------------------------------------------------= ---*/ - -static float128 propagateFloat128NaN(float128 a, float128 b, - float_status *status) -{ - bool aIsLargerSignificand; - FloatClass a_cls, b_cls; - - /* This is not complete, but is good enough for pickNaN. */ - a_cls =3D (!float128_is_any_nan(a) - ? float_class_normal - : float128_is_signaling_nan(a, status) - ? float_class_snan - : float_class_qnan); - b_cls =3D (!float128_is_any_nan(b) - ? float_class_normal - : float128_is_signaling_nan(b, status) - ? float_class_snan - : float_class_qnan); - - if (is_snan(a_cls) || is_snan(b_cls)) { - float_raise(float_flag_invalid, status); - } - - if (status->default_nan_mode) { - return float128_default_nan(status); - } - - if (lt128(a.high << 1, a.low, b.high << 1, b.low)) { - aIsLargerSignificand =3D 0; - } else if (lt128(b.high << 1, b.low, a.high << 1, a.low)) { - aIsLargerSignificand =3D 1; - } else { - aIsLargerSignificand =3D (a.high < b.high) ? 1 : 0; - } - - if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) { - if (is_snan(b_cls)) { - return float128_silence_nan(b, status); - } - return b; - } else { - if (is_snan(a_cls)) { - return float128_silence_nan(a, status); - } - return a; - } -} --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959957; cv=none; d=zohomail.com; s=zohoarc; b=fwZKeN7q7MQ4OdCwrP/WKLV9FDjBiyePqYf0AUiXWe/AL1C3baD9++y9l2ZU6qqvfJ4SkAySSscmFReLXXNW70FG6OWLvVtekYL14McSqgV2z/SknntOX/PNSVqIclJtxk2hAxHRi91D57gi6x9jACx0CRbQT+hYcTk4pPWUWZU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959957; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=0sbWGfdi+vZU0+T2mHM/iN4YQ8XRnXrlumJZuqrhiwA=; b=UnG5XcQWtKtSjyHBurDYsfJpSNo9+wsqfnf2AtAPt8fdfvSVuXlCovIUQOE3b6DHUL33on7eR4D/n1E+m4LjgNT6bJFhbfMK2FlLDiRk71UuhBzoEgSFyMO4n1kYe84CyK/N9tJluegpcUET/iJDxKfwA34G15BUyR39/uglFiI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959957225874.8506863195846; Tue, 25 May 2021 09:25:57 -0700 (PDT) Received: from localhost ([::1]:51754 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZsR-0001Aa-61 for importer@patchew.org; Tue, 25 May 2021 12:25:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60650) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeo-0002Lk-TK for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:46 -0400 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]:36707) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeU-0006nD-Nf for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:46 -0400 Received: by mail-pf1-x435.google.com with SMTP id c12so12247783pfl.3 for ; Tue, 25 May 2021 08:07:26 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0sbWGfdi+vZU0+T2mHM/iN4YQ8XRnXrlumJZuqrhiwA=; b=U8vlAa+CqUqKsS5kvTd4vH9kS4wTp9q+Jxb6pGIzpbSgvDSw6fd/MMWunDL+NLsG26 TtVMeR7PxC9+iE0/15EdBl5MnU1lTNQ/MoTkrnL385fNBfNYWFCU1X+LwZxSueT28lAF zpXu18aZTFFuKLjlyUtcuMvLquygWFcP+dnIoOgnGwecLv3CQLDkxvZL6Qw+rj9Z8zS5 JV3PNkLHD/vyz8RtmKCJLquLW4oCbIHJD0mwgmGjAu4ltG22W3tfQSpV8H5rJ/rDxvrE iwFudyL6pLWLbgIQ6NV83E5IeqObcWCJVSkWpWT4Ocm1jnH/ZBVLth0575woq9XTS15i Mdsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0sbWGfdi+vZU0+T2mHM/iN4YQ8XRnXrlumJZuqrhiwA=; b=tNl04iwYZXE8qSL7AmA4WW0pLrTjuejhQCMt7GxIrJEkY1G9zcUL+4EvlqgpuZgoXu 08f4VXe6+RPXqxLdLTQ/9+v6qrZ2QT2FpVtOGazmTKXymz1EbVlZLA91y2k1ED4G8Mzs l6o/b7lPqwg1lF9D6x8oRMlr26kaIXnaYfokiBklSnzCDh1GHzJwOkxi58g2wUVP7ICY auwPG7XKzBJcv769PQD4QNzdV3PrcYbmxd9vu6wPwOMIREu7Jj5Q9qWSRrc8WZRb0E8P 0PnquSvS6IlbulCQfcrhM1Q89Wbml+a4CdJPes/7IVIHDjBIuw2FWcRivQllBsfpk3Lg voVA== X-Gm-Message-State: AOAM5317XtAn6k39Zvf2FeRcN8sFeILmQ5xkXD9JM+vdx87vY97ZTgQD e6jOrxzM3kFlaB4N8m0v4Q1L0FZXqPkJrw== X-Google-Smtp-Source: ABdhPJwGcue5TJ+DsiKWedst7PvNld1ZVc4xnxsRM2I5bGo6pso0LwmKsqWRJ0ckfdDp0vEewrt7Nw== X-Received: by 2002:aa7:982e:0:b029:2e4:eef5:e0c9 with SMTP id q14-20020aa7982e0000b02902e4eef5e0c9mr22082764pfl.3.1621955245403; Tue, 25 May 2021 08:07:25 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 27/28] tests/fp: Enable more tests Date: Tue, 25 May 2021 08:07:05 -0700 Message-Id: <20210525150706.294968-28-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::435; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x435.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) From: Alex Benn=C3=A9e Fix the trivial typo in extF80_lt_quiet, and re-enable all of the floatx80 tests that are now fixed. Signed-off-by: Alex Benn=C3=A9e Message-ID: <87bl9iyahr.fsf@linaro.org> [rth: Squash the fix for lt_quiet, and enable that too.] Signed-off-by: Richard Henderson --- tests/fp/wrap.c.inc | 2 +- tests/fp/meson.build | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/fp/wrap.c.inc b/tests/fp/wrap.c.inc index cb1bb77e4c..9ff884c140 100644 --- a/tests/fp/wrap.c.inc +++ b/tests/fp/wrap.c.inc @@ -643,7 +643,7 @@ WRAP_CMP80(qemu_extF80M_eq, floatx80_eq_quiet) WRAP_CMP80(qemu_extF80M_le, floatx80_le) WRAP_CMP80(qemu_extF80M_lt, floatx80_lt) WRAP_CMP80(qemu_extF80M_le_quiet, floatx80_le_quiet) -WRAP_CMP80(qemu_extF80M_lt_quiet, floatx80_le_quiet) +WRAP_CMP80(qemu_extF80M_lt_quiet, floatx80_lt_quiet) #undef WRAP_CMP80 =20 #define WRAP_CMP128(name, func) \ diff --git a/tests/fp/meson.build b/tests/fp/meson.build index 9218bfd3b0..07e2cdc8d2 100644 --- a/tests/fp/meson.build +++ b/tests/fp/meson.build @@ -556,7 +556,9 @@ softfloat_conv_tests =3D { 'extF80_to_f64 extF80_to_f128 ' + 'f128_to_f16', 'int-to-float': 'i32_to_f16 i64_to_f16 i32_to_f32 i64_to_f32 ' + - 'i32_to_f64 i64_to_f64 i32_to_f128 i64_to_f128', + 'i32_to_f64 i64_to_f64 ' + + 'i32_to_extF80 i64_to_extF80 ' + + 'i32_to_f128 i64_to_f128', 'uint-to-float': 'ui32_to_f16 ui64_to_f16 ui32_to_f32 ui64_to_f32 ' + 'ui32_to_f64 ui64_to_f64 ui64_to_f128 ' + 'ui32_to_extF80 ui64_to_extF80', @@ -581,7 +583,7 @@ softfloat_conv_tests =3D { 'extF80_to_ui64 extF80_to_ui64_r_minMag ' + 'f128_to_ui64 f128_to_ui64_r_minMag', 'round-to-integer': 'f16_roundToInt f32_roundToInt ' + - 'f64_roundToInt f128_roundToInt' + 'f64_roundToInt extF80_roundToInt f128_roundToInt' } softfloat_tests =3D { 'eq_signaling' : 'compare', @@ -602,24 +604,20 @@ fptest_args =3D ['-s', '-l', '1'] fptest_rounding_args =3D ['-r', 'all'] =20 # Conversion Routines: -# FIXME: i32_to_extF80 (broken), i64_to_extF80 (broken) -# extF80_roundToInt (broken) foreach k, v : softfloat_conv_tests test('fp-test-' + k, fptest, args: fptest_args + fptest_rounding_args + v.split(), suite: ['softfloat', 'softfloat-conv']) endforeach =20 -# FIXME: extF80_{lt_quiet, rem} (broken), -# extF80_{mulAdd} (missing) foreach k, v : softfloat_tests - extF80_broken =3D ['lt_quiet', 'rem'].contains(k) test('fp-test-' + k, fptest, args: fptest_args + fptest_rounding_args + - ['f16_' + k, 'f32_' + k, 'f64_' + k, 'f128_' + k] + - (extF80_broken ? [] : ['extF80_' + k]), + ['f16_' + k, 'f32_' + k, 'f64_' + k, 'f128_' + k, 'extF80_' += k], suite: ['softfloat', 'softfloat-' + v]) endforeach + +# FIXME: extF80_{mulAdd} (missing) test('fp-test-mulAdd', fptest, # no fptest_rounding_args args: fptest_args + --=20 2.25.1 From nobody Wed Apr 24 21:31:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1621959449; cv=none; d=zohomail.com; s=zohoarc; b=Aq4joiBYS2XTXtnGZFTP4snl20FVPP+czy2D+FWK4nRDtRj7fq9/ivEO2sauN7rbAr5mRSkYqmWoRppSIs1UZQJuaNSCyDYP3oXgXUdQirdV3Q38FpKqxxMsgkbJl4TnUCoaKj2c3hv+2m6mQ+HfQkA2AF3Oweyvd7RNtNR3orI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621959449; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=jPESxkdne1pl9qKkpnJVzbPwFkDrkEve1zwqkORGLuk=; b=BNPyoqQJcgXAYjGbMocQ89yovk31mAKo1AbsGZAo5r3o9e16WwBtu9Golrnr1+LIIb7FksggBiAdpRpqQbrwhf6aWtXO9vH6MlPmkNTOWHs3Y93TlDBCT7UkeFQz66QOtf8E9MqGumMmE3D5eLEEMMvIDKXIr+MKZOTcnxldFno= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1621959449263101.01717043850942; Tue, 25 May 2021 09:17:29 -0700 (PDT) Received: from localhost ([::1]:53488 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZkG-0008Oe-HW for importer@patchew.org; Tue, 25 May 2021 12:17:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60614) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYen-0002Fc-DI for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:45 -0400 Received: from mail-pf1-x42e.google.com ([2607:f8b0:4864:20::42e]:40498) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeW-0006nR-Gh for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:45 -0400 Received: by mail-pf1-x42e.google.com with SMTP id x188so23833956pfd.7 for ; Tue, 25 May 2021 08:07:26 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jPESxkdne1pl9qKkpnJVzbPwFkDrkEve1zwqkORGLuk=; b=NrGyYqhvhZuyBq9Zo6J0tCtHCQFS5Dic6ht7OBRcJpUL99xtoCLqUw+nf6qYU3/EiA AFP4Yr8iNVTAoEn5J4jEeEArpqakV69lObkYY6tE/hWD+6Vl0Qc+hfA2KEghP4R64r3L uoCze7IGdYVFmpShAO6IAUzCElRAQvJl6V/6xJ+f9fQLRb5fPDj43oHjriUYrkqDnrdS qgAWzLYrAZW/16yd9BWmwVKz95LNiBIU8Bjm4fqMgtBczjk64OGgbMECOSo8q3IjDJqJ ovImFwKwg7Cn4RxzIQ85RTwIkaWRRjOSd+qHPKRnffAt0WPg7AygbbbLCIS0ORe6//HT a88A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jPESxkdne1pl9qKkpnJVzbPwFkDrkEve1zwqkORGLuk=; b=m4HXz0Fg35VCMLIqD8/mfmwe0uXlXZidt+nkCbCnXEEcKlM+xIldIjEje+7WjuJTlm Uq9fF2t7nMvsjGCMZ8kFFZ3rWpRCxNul3sv1kO4+1UluI95fzXza5Jf8ijuUqygvOBk2 yY8nLHjz61IuPGAxUHwJr40E7fWxldGAxCfIk79IT/WZIf1ubyK6CLcZxOe//YXa4Kxc C9Qee6CrFXIq7VkJquRGU12JGDNLKYj0OLxW8SOrvKf33djS1dH4sXbccet45VnVyiXc XLaziyKsSq5/f6DXJ3UaEpCdKpq01RuWP5mmM/fsk16UhcPQjRlJs4nPmczZwHStj6Yu 7s0Q== X-Gm-Message-State: AOAM531ILG13iAa7mMKldsSbav75jBuzoPQGTECYJ0Gi9JZ5rWo2dQfg 0P0Q9pzij0Et1IlBMnDBUwhIVURUYAnnJw== X-Google-Smtp-Source: ABdhPJweyp9UkGj20z6Z7ile+Zoy0L+9BRFNy465G+TwlfgiQAvKKjzXCI8M/98KpbVaEH7pQXw58g== X-Received: by 2002:a63:5c1:: with SMTP id 184mr19617387pgf.75.1621955246013; Tue, 25 May 2021 08:07:26 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 28/28] softfloat: Use hard-float for {u}int64_to_float{32, 64} Date: Tue, 25 May 2021 08:07:06 -0700 Message-Id: <20210525150706.294968-29-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::42e; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42e.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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" For the normal case of no additional scaling, this reduces the profile contribution of int64_to_float64 to the testcase in the linked issue from 0.81% to 0.04%. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/134 Signed-off-by: Richard Henderson Reviewed-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index b0df5b6dc5..79b2205070 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3559,6 +3559,13 @@ float32 int64_to_float32_scalbn(int64_t a, int scale= , float_status *status) { FloatParts64 p; =20 + /* Without scaling, there are no overflow concerns. */ + if (likely(scale =3D=3D 0) && can_use_fpu(status)) { + union_float32 ur; + ur.h =3D a; + return ur.s; + } + parts64_sint_to_float(&p, a, scale, status); return float32_round_pack_canonical(&p, status); } @@ -3592,6 +3599,13 @@ float64 int64_to_float64_scalbn(int64_t a, int scale= , float_status *status) { FloatParts64 p; =20 + /* Without scaling, there are no overflow concerns. */ + if (likely(scale =3D=3D 0) && can_use_fpu(status)) { + union_float64 ur; + ur.h =3D a; + return ur.s; + } + parts_sint_to_float(&p, a, scale, status); return float64_round_pack_canonical(&p, status); } @@ -3726,6 +3740,13 @@ float32 uint64_to_float32_scalbn(uint64_t a, int sca= le, float_status *status) { FloatParts64 p; =20 + /* Without scaling, there are no overflow concerns. */ + if (likely(scale =3D=3D 0) && can_use_fpu(status)) { + union_float32 ur; + ur.h =3D a; + return ur.s; + } + parts_uint_to_float(&p, a, scale, status); return float32_round_pack_canonical(&p, status); } @@ -3759,6 +3780,13 @@ float64 uint64_to_float64_scalbn(uint64_t a, int sca= le, float_status *status) { FloatParts64 p; =20 + /* Without scaling, there are no overflow concerns. */ + if (likely(scale =3D=3D 0) && can_use_fpu(status)) { + union_float64 ur; + ur.h =3D a; + return ur.s; + } + parts_uint_to_float(&p, a, scale, status); return float64_round_pack_canonical(&p, status); } --=20 2.25.1