From patchwork Thu Jun 3 21:41:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453310 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp626726jao; Thu, 3 Jun 2021 14:43:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxb5gebAHGg7eU5S3dM/Y7hLRMYN0ocxyjhWjcUri2j1Vnle0D+mWUWbtiJidcdPoZ23kLn X-Received: by 2002:a54:4690:: with SMTP id k16mr8793410oic.57.1622756596585; Thu, 03 Jun 2021 14:43:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756596; cv=none; d=google.com; s=arc-20160816; b=hsjbYtnZVZ+X8yVnJWSU8p2fJfnDEL1C2FONoj4/z+u+rsXzVbLqg3WsDT6e3QK5/C hzemvY+Sgf321wZ6kRKjO9hblUsc1iK61cHxPd+409Yjz5FZB2ajyPVhXKhHMTcHOh62 YVA+EfweHlWMSJHyjZxoi1OS59Mr58WlAqo6pjm6IZqMD1I1O+44kDsq/htKouYYrwtN Qt8m4VGkeLQatOPlJ+FC8nZokxQdO/dfWkgsdbQi6YgMchWhC65ugv4MQs4SzQ8HOyEl v8An0pQYciWbMtFLjcq1ocT0HTeBhpPQQpasp2VkI4RfYRz/Gtw0PZJG0O1nymv1BhHG u36Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=/8zGSmRtRNib0B0xN2lfOZiuTchPOPYviatx/oRU9nA=; b=ghlDCF0bUZoZDvIwuLirNk0n0+JSafuiNtrMyCAF54diqpzBBTqJa+wZVynzJJ/ELd BHyGNV6wfJBZJAINwK3exOoGI1ElrY0Y4Z8EN/118w7P7MrCDne1IcUIqP1I2jTO9cvG f0NRsMRoXys0d4hw6wE5ok/vX93MdtBeMaQK593aIUR6xMrudlYOEzX+i7M5TZiHokVL F258r/2QQRsiUMDriw3DFn5yJfFsnqrFk6KKANGYMsI86d3DOQyKPrV2PpXnDca4KKpw Dg69YalQS/QGCyqJu8ZTg2kq0aL+Hibs4mM1UPVP70c4GScjVKaKe0DvVVhLigDd+I+y GF9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=yxXjNhZZ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id i17si124786oie.240.2021.06.03.14.43.16 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:43:16 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=yxXjNhZZ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:51158 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lov7T-00065K-Tz for patch@linaro.org; Thu, 03 Jun 2021 17:43:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58180) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov5t-0001xu-Ou for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:37 -0400 Received: from mail-pf1-x42c.google.com ([2607:f8b0:4864:20::42c]:35475) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5r-0000zZ-34 for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:37 -0400 Received: by mail-pf1-x42c.google.com with SMTP id h12so3084100pfe.2 for ; Thu, 03 Jun 2021 14:41:34 -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=/8zGSmRtRNib0B0xN2lfOZiuTchPOPYviatx/oRU9nA=; b=yxXjNhZZtX3x5ymMeDRdM7+QaPl24bagMpqxQ4MX0Fq7Zjk+4vnwo1g06T8wfJx+ZD mFeo3Q/rOhGEa8Z9iwkbJYFGYWujpOWZmr4H0zcGoGdn/cgzyuyZIk7VQSNWEyfEnHB6 YrlyA2hNIA3o8dskwSiuYheWpkAuXT+vmLbW/zUBPx7LsAtwN1vhhHL6IOLnMwRAE/Ig 67fOdmerHU494KvBmvuDD62X6op77cXs4b6iuiWGGSGZl3M7U/NwB7B48ZrbOc0VAoCl 4ctZT9Zt4XrjW41T+2KwA1M4GbFb9zgaObo9sAh9StGKeaNLPUpOIIcVFNVaqTzm96d3 05Gg== 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=/8zGSmRtRNib0B0xN2lfOZiuTchPOPYviatx/oRU9nA=; b=cTdD7d1IYHaA1GECXP+CqnrUOvntqAZum64GjlpwmnbkD944c/0h1KmupfEMvNu25U iiKHsHFz6cm5eamwfx5ANneFwJdq+VqZ2Dw442Vk7/Bf5EoErM65qgoc1LXPZOzrN5iQ 51g0xzdaNA+q3NhQoVMlwRlaiVOc5zw9my47QKP4a18JSMHYswLoxzoThdb+RjrxyjU0 nFd0MU0YOG2bQ+oo8X5rug+v0zdDb3AfN3PS8/lYJcm2dSqzLgFPONxHLpCOVvHdjKpX faETTA0alvjTwl9otmXNn63fnCVjii5xwq8AuznyXfUV0x1Pzs3bvOeEHr8cK4fEOlkG WVOw== X-Gm-Message-State: AOAM530Lgjv3VkTh7ItGQrj2KdA2F1ynWgPW0rssMoV8n4DpZVSQd/gO BlWs+0Ba4di8ENlSWNsoTJNjN7tMjraUqg== X-Received: by 2002:a63:521a:: with SMTP id g26mr1469611pgb.279.1622756493522; Thu, 03 Jun 2021 14:41:33 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:33 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 01/29] softfloat: Move round_to_uint_and_pack to softfloat-parts.c.inc Date: Thu, 3 Jun 2021 14:41:03 -0700 Message-Id: <20210603214131.629841-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Rename to parts$N_float_to_uint. Reimplement float128_to_uint{32,64}{_round_to_zero} with FloatParts128. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 357 +++++++++----------------------------- fpu/softfloat-parts.c.inc | 68 +++++++- 2 files changed, 147 insertions(+), 278 deletions(-) -- 2.25.1 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) +static uint64_t parts64_float_to_uint(FloatParts64 *p, FloatRoundMode rmode, + int scale, uint64_t max, + float_status *s); +static uint64_t parts128_float_to_uint(FloatParts128 *p, FloatRoundMode rmode, + 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) } /* - * 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 */ -static uint64_t round_to_uint_and_pack(FloatParts64 p, FloatRoundMode rmode, - int scale, uint64_t max, - float_status *s) -{ - int flags = 0; - uint64_t r; - - switch (p.cls) { - case float_class_snan: - case float_class_qnan: - flags = float_flag_invalid; - r = max; - break; - - case float_class_inf: - flags = float_flag_invalid; - r = p.sign ? 0 : max; - break; - - case float_class_zero: - return 0; - - case float_class_normal: - /* TODO: 62 = N - 2, frac_size for rounding */ - if (parts_round_to_int_normal(&p, rmode, scale, 62)) { - flags = float_flag_inexact; - if (p.cls == float_class_zero) { - r = 0; - break; - } - } - - if (p.sign) { - flags = float_flag_invalid; - r = 0; - } else if (p.exp > DECOMPOSED_BINARY_POINT) { - flags = float_flag_invalid; - r = max; - } else { - r = p.frac >> (DECOMPOSED_BINARY_POINT - p.exp); - if (r > max) { - flags = float_flag_invalid; - r = 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; 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); } uint16_t float16_to_uint16_scalbn(float16 a, FloatRoundMode rmode, int scale, @@ -2728,7 +2674,7 @@ uint16_t float16_to_uint16_scalbn(float16 a, FloatRoundMode rmode, int scale, FloatParts64 p; 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); } uint32_t float16_to_uint32_scalbn(float16 a, FloatRoundMode rmode, int scale, @@ -2737,7 +2683,7 @@ uint32_t float16_to_uint32_scalbn(float16 a, FloatRoundMode rmode, int scale, FloatParts64 p; 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); } uint64_t float16_to_uint64_scalbn(float16 a, FloatRoundMode rmode, int scale, @@ -2746,7 +2692,7 @@ uint64_t float16_to_uint64_scalbn(float16 a, FloatRoundMode rmode, int scale, FloatParts64 p; 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); } uint16_t float32_to_uint16_scalbn(float32 a, FloatRoundMode rmode, int scale, @@ -2755,7 +2701,7 @@ uint16_t float32_to_uint16_scalbn(float32 a, FloatRoundMode rmode, int scale, FloatParts64 p; 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); } uint32_t float32_to_uint32_scalbn(float32 a, FloatRoundMode rmode, int scale, @@ -2764,7 +2710,7 @@ uint32_t float32_to_uint32_scalbn(float32 a, FloatRoundMode rmode, int scale, FloatParts64 p; 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); } uint64_t float32_to_uint64_scalbn(float32 a, FloatRoundMode rmode, int scale, @@ -2773,7 +2719,7 @@ uint64_t float32_to_uint64_scalbn(float32 a, FloatRoundMode rmode, int scale, FloatParts64 p; 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); } uint16_t float64_to_uint16_scalbn(float64 a, FloatRoundMode rmode, int scale, @@ -2782,7 +2728,7 @@ uint16_t float64_to_uint16_scalbn(float64 a, FloatRoundMode rmode, int scale, FloatParts64 p; 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); } uint32_t float64_to_uint32_scalbn(float64 a, FloatRoundMode rmode, int scale, @@ -2791,7 +2737,7 @@ uint32_t float64_to_uint32_scalbn(float64 a, FloatRoundMode rmode, int scale, FloatParts64 p; 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); } uint64_t float64_to_uint64_scalbn(float64 a, FloatRoundMode rmode, int scale, @@ -2800,7 +2746,52 @@ uint64_t float64_to_uint64_scalbn(float64 a, FloatRoundMode rmode, int scale, FloatParts64 p; 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); } 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); } +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); } -/* - * 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); } -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); } 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, } -/*---------------------------------------------------------------------------- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input words), -| and returns the properly rounded 64-bit unsigned integer corresponding to the -| input. 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 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 = status->float_rounding_mode; - roundNearestEven = (roundingMode == float_round_nearest_even); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - increment = ((int64_t)absZ1 < 0); - break; - case float_round_to_zero: - increment = 0; - break; - case float_round_up: - increment = !zSign && absZ1; - break; - case float_round_down: - increment = zSign && absZ1; - break; - case float_round_to_odd: - increment = !(absZ0 & 1) && absZ1; - break; - default: - abort(); - } - if (increment) { - ++absZ0; - if (absZ0 == 0) { - float_raise(float_flag_invalid, status); - return UINT64_MAX; - } - if (!(absZ1 << 1) && roundNearestEven) { - absZ0 &= ~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 represented | by the denormalized significand `aSig'. The normalized exponent and @@ -6536,122 +6455,6 @@ floatx80 floatx80_sqrt(floatx80 a, float_status *status) 0, zExp, zSig0, zSig1, status); } -/*---------------------------------------------------------------------------- -| 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 = extractFloat128Frac0(a); - aSig1 = extractFloat128Frac1(a); - aExp = extractFloat128Exp(a); - aSign = 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 |= UINT64_C(0x0001000000000000); - } - shiftCount = 0x402F - aExp; - if (shiftCount <= 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 = status->float_rounding_mode; - - set_float_rounding_mode(float_round_to_zero, status); - v = 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 = get_float_exception_flags(status); - - v = float128_to_uint64_round_to_zero(a, status); - if (v > 0xffffffff) { - res = 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 = get_float_exception_flags(status); - - v = float128_to_uint64(a, status); - if (v > 0xffffffff) { - res = 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 7f69da1d8f..483bdc0e21 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -763,7 +763,7 @@ static void partsN(round_to_int)(FloatPartsN *a, FloatRoundMode 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) @@ -817,3 +817,69 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode 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_status *s) +{ + int flags = 0; + uint64_t r; + + switch (p->cls) { + case float_class_snan: + case float_class_qnan: + flags = float_flag_invalid; + r = max; + break; + + case float_class_inf: + flags = float_flag_invalid; + r = 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 = float_flag_inexact; + if (p->cls == float_class_zero) { + r = 0; + break; + } + } + + if (p->sign) { + flags = float_flag_invalid; + r = 0; + } else if (p->exp > DECOMPOSED_BINARY_POINT) { + flags = float_flag_invalid; + r = max; + } else { + r = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp); + if (r > max) { + flags = float_flag_invalid; + r = max; + } + } + break; + + default: + g_assert_not_reached(); + } + + float_raise(flags, s); + return r; +} From patchwork Thu Jun 3 21:41:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453308 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp625989jao; Thu, 3 Jun 2021 14:42:00 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzhpIjYAsUtn1XzfHlEnemVGumAcnsee6R+ilfakZ1A1gVn3ixk6CNE/OIXiSQhdjBirQo0 X-Received: by 2002:a92:1310:: with SMTP id 16mr1280221ilt.60.1622756520371; Thu, 03 Jun 2021 14:42:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756520; cv=none; d=google.com; s=arc-20160816; b=f0by9/8DW+J0x8Pj4Jxymu6QfsGF9nhrLBGg0BEyFqTLh+mqNWrT21ZJJOh+myEiyR 8BrD2Ozt1NGw7co4mkIwcmo0D9IwoNWZnFcFq8JFaUhd7yFClya5jvkiQR0cYc4y4EYZ r00idRayLPxSQvDtTXA32rbm5fZbJ4aeNpqWJDAQYlCTwCByoWaKbbsyeWMu5JX1u+BC X3cK8Fd4NI0c3071V8vnMTNxCkjYi0JKhzdLeDAErlUt8y2t4BEEG9V3GkalN+ukoo0R HLNBrEo07VV6gMLh8hUv9TBuZQpk1itO1vT5II9NboBfeM+rRMQCuLGptvD38esNRISn YlOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=jExZoW94fQf1KTDSzPZo60kTKr+L9V1ApVnhdi+DwN4=; b=EkedQlbDNsR5yGLATCDVAgCQOjxsKfhjHTsMb/tti+0l3R4XiQ45iYsAC+HM+Z8QXT zeKBEl6837uk4KF481CRNRtFk6B+ri1fmFwrD3yvVJ/kQ21Lezdv1663nUTHlhjSvgla aRcTKC8hXOm3xqCmJDxNcg+0aEzr5ywAKJR9CecOH0v/gJIblQLbxuQIQz89FdV5GPik Xb0SlOoVxjPI0Ip+wFIaFZ0ZmymFv4p+rZ687VL593spjqYmiqNTUocm5J1oZur+uhzC hTj2nu44vawh2aZB2qoPZsKvxaEoDFgJe0zlojTj/e2yzWq4k3LBJdB6ZwQ4umB+HTLJ MimA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=omRWt91q; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id q10si4426544ilu.60.2021.06.03.14.42.00 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:42:00 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=omRWt91q; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:45188 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lov6F-00023g-PC for patch@linaro.org; Thu, 03 Jun 2021 17:41:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58202) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov5u-0001zP-GU for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:38 -0400 Received: from mail-pg1-x535.google.com ([2607:f8b0:4864:20::535]:42605) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5r-0000zu-BK for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:38 -0400 Received: by mail-pg1-x535.google.com with SMTP id t8so6149200pgb.9 for ; Thu, 03 Jun 2021 14:41:34 -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=jExZoW94fQf1KTDSzPZo60kTKr+L9V1ApVnhdi+DwN4=; b=omRWt91qfFzA3nkkwRbpAZIY+cSyYlCri9Bj5NJ4zOYe2ZfSLMB+r+wtG5kI2wNG+Y r8XWdO6XgS+8pxSJpYT/qrv+C+d30RFlHrurwvwbdjXq7Kdd4uV+YDa1hKyql1vDs5XX IIODnjr9NzdkV7TaG/XLrR+YwLakawYTnY8LM/A70OokKXkAC7lLVYobUEDJYIj3QVG2 J+lOzXQ0dlT5ZVNFAci5r5oJfLCrjipO9fooRlddtp4FRmmnMVKbe9K63n1pAdJiTOUR raSxAmGqjgGqCYTYgpgL0pqJC6XuL+Qss/CGLcDaoHOlsxGfvboSkfxELULBT6G/k57X rkTw== 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=jExZoW94fQf1KTDSzPZo60kTKr+L9V1ApVnhdi+DwN4=; b=EjTLwQKNvYVM7NyshoicmvN//KfMEPEPtQOmH/2tT8yTdRESt+Dlabouh+ubKfQdJ3 Zu5r/NNmInMQfUiKu303RJB/gX5OfAnZcDlHFtsX+9cB28wzmWNSvwj8XUn0T5sr6326 zC7tn157A00nL4ZbJHjkKWvyGec0eJphY9DQR6YFBiHb35b7lzutXpEKDn8CWr9lEN3o y0fKa5LzEbuAaWugpJ8k0t9Cdp52I6k5NH8Sx+OE43sjM3pwg3V6mNgIDWVOyH9OqYaa HtEqWNr8nSEyKWL1eYf93n2NnDDWSoziLNL4ZjX/etIU5Yw879Wp8jZalNcv7B3XLsPc WLLw== X-Gm-Message-State: AOAM530/vroE5hyDJtzXxGck1YS8eVmBAw596iavrLvpgc3lFf4wjpX9 nOSuS99ZPr9ci79h9OxSrWaJOxLuxDpc/Q== X-Received: by 2002:a62:3344:0:b029:24c:735c:4546 with SMTP id z65-20020a6233440000b029024c735c4546mr1409766pfz.1.1622756494055; Thu, 03 Jun 2021 14:41:34 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:33 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 02/29] softfloat: Move int_to_float to softfloat-parts.c.inc Date: Thu, 3 Jun 2021 14:41:04 -0700 Message-Id: <20210603214131.629841-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::535; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x535.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: =?utf-8?q?Alex_Benn=C3=A9e?= , David Hildenbrand Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Rename to parts$N_sint_to_float. Reimplement int{32,64}_to_float128 with FloatParts128. Reviewed-by: Alex Bennée Reviewed-by: David Hildenbrand Signed-off-by: Richard Henderson --- fpu/softfloat.c | 136 +++++++++++--------------------------- fpu/softfloat-parts.c.inc | 32 +++++++++ 2 files changed, 70 insertions(+), 98 deletions(-) -- 2.25.1 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) +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) } /* - * 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 */ -static FloatParts64 int_to_float(int64_t a, int scale, float_status *status) -{ - FloatParts64 r = { .sign = false }; - - if (a == 0) { - r.cls = float_class_zero; - } else { - uint64_t f = a; - int shift; - - r.cls = float_class_normal; - if (a < 0) { - f = -f; - r.sign = true; - } - shift = clz64(f); - scale = MIN(MAX(scale, -0x10000), 0x10000); - - r.exp = DECOMPOSED_BINARY_POINT - shift + scale; - r.frac = f << shift; - } - - return r; -} - float16 int64_to_float16_scalbn(int64_t a, int scale, float_status *status) { - FloatParts64 pa = 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); } 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 *status) float32 int64_to_float32_scalbn(int64_t a, int scale, float_status *status) { - FloatParts64 pa = 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); } 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 *status) float64 int64_to_float64_scalbn(int64_t a, int scale, float_status *status) { - FloatParts64 pa = 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); } 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 *status) return int64_to_float64_scalbn(a, 0, status); } -/* - * 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 *status) { - FloatParts64 pa = 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); } bfloat16 int32_to_bfloat16_scalbn(int32_t a, int scale, float_status *status) @@ -3106,6 +3088,19 @@ bfloat16 int16_to_bfloat16(int16_t a, float_status *status) return int64_to_bfloat16_scalbn(a, 0, status); } +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) } -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' to -| the quadruple-precision floating-point format. The conversion is performed -| 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 == 0 ) return packFloat128( 0, 0, 0, 0 ); - zSign = ( a < 0 ); - absA = zSign ? - a : a; - shiftCount = clz32(absA) + 17; - zSig0 = absA; - return packFloat128( zSign, 0x402E - shiftCount, zSig0<cls = float_class_zero; + return; + } + + p->cls = float_class_normal; + if (a < 0) { + f = -f; + p->sign = true; + } + shift = clz64(f); + scale = MIN(MAX(scale, -0x10000), 0x10000); + + p->exp = DECOMPOSED_BINARY_POINT - shift + scale; + p->frac_hi = f << shift; +} From patchwork Thu Jun 3 21:41:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453314 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp627576jao; Thu, 3 Jun 2021 14:44:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyqCif4k0xP716gHRs4YqhXHjr+iQWcxNYbaim2Lr8/stOeR8KnUqng5IJctQCRMMwoU9k9 X-Received: by 2002:a67:fbc5:: with SMTP id o5mr578386vsr.28.1622756684451; Thu, 03 Jun 2021 14:44:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756684; cv=none; d=google.com; s=arc-20160816; b=Eu4Hhilu4TUjDxxZh0GoGgyJkXJtNpgK0sfS6ZJ9mYK+sKp51C/sN1a/QIyZ595GoE C5r+EyqefY77elJyA+gumYV1QDh9pa79cAIHgXVcsyb2l8bwe+C8J1SkZ9UBi123ufgd +1QIkjFYUxZdU2Kxx2CTklOSqBYSgJ/oY9xrcCDueWPSDUBqJTxFMO7u0DUhLeF+d8mw 4aCNyEafUKqlVs8l+l1bjSeV9mH0Esy1WLHJkFZ2q0eKZhT3tGG5Zb74ZTkCQp9LAL9e ad7LsXFTtrfwD5txgJkMyl2gdU4nPTueqddeKN/BkHRetTIGssJg4oCxx/vOznRrCqBy ePwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=/O3G+s5zkrQ27z7duiC08BP2nW9q9ClatbZtV+eVQt0=; b=yj/PLqI65GeYCsiMlH/ODY+sTSbY2xj8tRgHWytAarrTEaCbpGLL4if0XK9mMnWk45 Bh2KiyyFo6GUM4kSdcmM3IxeKGUZk0UmzLMjqdhXjHcDmkMnFi8WaVtJG1A88pN+E621 M6yJVvTDFYj8Jt/CeigYR2o10Y6D6HTdTHq0GISDWVUhe+x6LY2HXtlG/8KLZwzHOp9J DrzZ9jArFxcDWgdRGT8YeC83ITuuAAOCuJPZYfIbl/eOiPdYxi0Mm4ltTiEdwcqEWK15 VyBkqYBLsoruANDqbPbnpYGw9CBAxsFjPEmxA1XU+rZp3TOC/OIyEiXAF1zXXeW87RaF jLDg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AdXiEiXz; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 128si2030409vsq.307.2021.06.03.14.44.44 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:44:44 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AdXiEiXz; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:59862 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lov8t-0003RY-Pv for patch@linaro.org; Thu, 03 Jun 2021 17:44:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58248) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov5w-00025j-Sl for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:40 -0400 Received: from mail-pf1-x42a.google.com ([2607:f8b0:4864:20::42a]:47023) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5s-000117-1f for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:40 -0400 Received: by mail-pf1-x42a.google.com with SMTP id u126so1935757pfu.13 for ; Thu, 03 Jun 2021 14:41:35 -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=/O3G+s5zkrQ27z7duiC08BP2nW9q9ClatbZtV+eVQt0=; b=AdXiEiXz11/DSAfCNJlFbgdN1GA1QAjYQX+j1qseJZEdu0oxXrsxodCmygAuVA5JRU jDX4bpxKJFI2qVyRwwJi6Lu4LIr+xtVYgPV0e8fBdedH1babfzDGHY5OKjOJ8QIQo0ou YdyI0jQK+/+Uf4hMDT2WMdFgNBwOXbpaFiOUObtlpjKByUAHWLDJdtbnULk8mdT/FShP mK6pEVZUl7zvhJQSMLOU77AYLc3pTJA/hxSYiEe9LYh3JAtZCUMEaWDsHKs+jxjqyqK5 tg7v+aDO/2pWFxY2YNvuwWbjl5u0RavUp2R3NT62pZ6GVvTvafOfMeLf5zszK6CnpHRJ iz2Q== 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=/O3G+s5zkrQ27z7duiC08BP2nW9q9ClatbZtV+eVQt0=; b=NvAk19pSV/hdHK49RrCBfOPSWaDsqKVnJvgpfbx/eSoHrgwlgNOiEfuO+k0fByoYGr RC8zWPs7JsE3rlqbXWeEKPQiIx7vM/G6RnqpAhSy8Fsi1+WsMMdZ6Yfmpp5YSdWIjbSE zt6QYIawQj11vjBajpp9/6gZoakMRbBgTg1IPqL5TNrjqAB9rtOCQk/sgL+wV3w1rXyH gJQNDmAjf3W+Ybv3413dbopASz1uvouDmXt5KqZ7UyK8wOLtGLyyJ9ET2j6zCxpLd3kM NN3tZ/hVJUqngC31CF3YCcUgVdknLMaKOzUAMXBi+UZ9OZKHRj9CHGtONA8PJdstAEuN BGMQ== X-Gm-Message-State: AOAM5327eMUkf6UXH2oz7tHBax9wUIwwtBuy4xKh42ld1xOL641PnAlt yNvDewDDD5755nbSLdwez/8oFvq2Q7Iq4g== X-Received: by 2002:a63:4b42:: with SMTP id k2mr1481437pgl.33.1622756494694; Thu, 03 Jun 2021 14:41:34 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:34 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 03/29] softfloat: Move uint_to_float to softfloat-parts.c.inc Date: Thu, 3 Jun 2021 14:41:05 -0700 Message-Id: <20210603214131.629841-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42a; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42a.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: =?utf-8?q?Alex_Benn=C3=A9e?= , David Hildenbrand Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Rename to parts$N_uint_to_float. Reimplement uint64_to_float128 with FloatParts128. Reviewed-by: Alex Bennée Reviewed-by: David Hildenbrand Signed-off-by: Richard Henderson --- fpu/softfloat.c | 83 ++++++++++++++++----------------------- fpu/softfloat-parts.c.inc | 23 +++++++++++ 2 files changed, 56 insertions(+), 50 deletions(-) -- 2.25.1 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, int64_t a, #define parts_sint_to_float(P, I, Z, S) \ PARTS_GENERIC_64_128(sint_to_float, P)(P, I, Z, S) +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) } /* - * 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 */ -static FloatParts64 uint_to_float(uint64_t a, int scale, float_status *status) -{ - FloatParts64 r = { .sign = false }; - int shift; - - if (a == 0) { - r.cls = float_class_zero; - } else { - scale = MIN(MAX(scale, -0x10000), 0x10000); - shift = clz64(a); - r.cls = float_class_normal; - r.exp = DECOMPOSED_BINARY_POINT - shift + scale; - r.frac = a << shift; - } - - return r; -} - float16 uint64_to_float16_scalbn(uint64_t a, int scale, float_status *status) { - FloatParts64 pa = 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); } float16 uint32_to_float16_scalbn(uint32_t a, int scale, float_status *status) @@ -3165,8 +3153,10 @@ float16 uint8_to_float16(uint8_t a, float_status *status) float32 uint64_to_float32_scalbn(uint64_t a, int scale, float_status *status) { - FloatParts64 pa = 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); } float32 uint32_to_float32_scalbn(uint32_t a, int scale, float_status *status) @@ -3196,8 +3186,10 @@ float32 uint16_to_float32(uint16_t a, float_status *status) float64 uint64_to_float64_scalbn(uint64_t a, int scale, float_status *status) { - FloatParts64 pa = 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); } float64 uint32_to_float64_scalbn(uint32_t a, int scale, float_status *status) @@ -3225,15 +3217,12 @@ float64 uint16_to_float64(uint16_t a, float_status *status) return uint64_to_float64_scalbn(a, 0, status); } -/* - * 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 *status) { - FloatParts64 pa = 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); } bfloat16 uint32_to_bfloat16_scalbn(uint32_t a, int scale, float_status *status) @@ -3261,6 +3250,14 @@ bfloat16 uint16_to_bfloat16(uint16_t a, float_status *status) return uint64_to_bfloat16_scalbn(a, 0, status); } +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) } -/*---------------------------------------------------------------------------- -| Returns the result of converting the 64-bit unsigned integer `a' -| to the quadruple-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 uint64_to_float128(uint64_t a, float_status *status) -{ - if (a == 0) { - return float128_zero; - } - return normalizeRoundAndPackFloat128(0, 0x406E, 0, a, status); -} - /*---------------------------------------------------------------------------- | Returns the result of converting the single-precision floating-point value | `a' to the extended double-precision floating-point format. The conversion diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index b7486f02db..2eb7bb96b3 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -915,3 +915,26 @@ static void partsN(sint_to_float)(FloatPartsN *p, int64_t a, p->exp = DECOMPOSED_BINARY_POINT - shift + scale; p->frac_hi = 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 == 0) { + p->cls = float_class_zero; + } else { + int shift = clz64(a); + scale = MIN(MAX(scale, -0x10000), 0x10000); + p->cls = float_class_normal; + p->exp = DECOMPOSED_BINARY_POINT - shift + scale; + p->frac_hi = a << shift; + } +} From patchwork Thu Jun 3 21:41:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453312 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp627263jao; Thu, 3 Jun 2021 14:44:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwg5uQJQr4hidk5JgdZcf1HPqz1+KY1UTosgLAdGPcmsZwpYQd/ED9qL4ZGEFoEnQRwxwKU X-Received: by 2002:a1f:31cd:: with SMTP id x196mr516817vkx.24.1622756646981; Thu, 03 Jun 2021 14:44:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756646; cv=none; d=google.com; s=arc-20160816; b=G742u1NkhqvUVTnsjLow2Jr4wy0XSbxlaxnmWIifEPlp6kUBOeqJg/b4kUnuQgC7ZQ 4Nh9OzOMkP2Bad1jAEOerNgrx/LbWDmZUCL7erNk43MnAOyyOlHqcB4Zib0gzrE9u9uY gJqpmDO5qnY8mlXYqTeDLYltuvajB4IhnznKCJcDtRuyZZkP10Bx9uriIu+i2g79Qdm3 3vhWG3u5m0snHzxiCXfXsMHmEI+vk5E8D6m0Ehc/LLbWFkJGL+WjP3rJ0hRNhGCDvFc7 4RcFwLbIkUeJ5CRJBEl3owA79Bdnfv5+ygQiXvfT6UyDvH7z2504TXiw6FwQyZTogbnI 8b6Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=ZyqAk3JV1lMheoleEpLdtdhruI6JP69rj7H32n7LYXs=; b=B7Sv+q8/Ryrqw6rCtRNJYhLGOahp6wKuCPSnXGhkw1MT+z4iZ3vPiWYvkbhQ1FalKh 9gUS0sySx/LARyAu3alnCYXO3psc9E8MDWOFzCI1msfIGyPgiIaiDsuowa/62XRSE0VY Ss9nq+qT1MD6miXEdyKtcc/5uCrHSEJgkIwwUeZPmcyVpvMOuAF55agMhzleLzhbSTc2 0/7N/u3TxEVIYqKHtQjepiugQE6PQhur6QKmyhurnV+FuUwISxK+QmXIVq+Q592Y6xgX rhVTO/X3IDNKI869apT1HPMFe1hzpzPhWk5Qywra1HuJ7+ad2REMpFp5Y6ThWsy0Mm4E Vswg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RSVhTeGQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id g20si982542uan.122.2021.06.03.14.44.06 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:44:06 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RSVhTeGQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:53488 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lov8I-0007c2-AG for patch@linaro.org; Thu, 03 Jun 2021 17:44:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58212) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov5v-00020o-2q for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:39 -0400 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]:50901) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5s-00011T-O3 for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:38 -0400 Received: by mail-pj1-x102b.google.com with SMTP id i22so4470922pju.0 for ; Thu, 03 Jun 2021 14:41:36 -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=ZyqAk3JV1lMheoleEpLdtdhruI6JP69rj7H32n7LYXs=; b=RSVhTeGQm/Y7zgKdYqb0hfCRi7df6m1rpJB9L5tyag2dP+VEPzb8nUAfw8o+mBdklf l3Rzwk5pIcusQf0Gfmc7M2LRDYD9m3Y6ajgsBmBC+bCOvWIq4tbmakoIATPFI8aIKUtN rdgY4gVLJBFtN+gbApAAnRRAMyqWOCgzRdNmyAaxj5S5xI+gm7eLR9EbpcIA7kbgIjZC Z/Axjr7nzyA5G18Zzhnxa7vfXvlhOX99OnA/xS4Uw/7AzDbr7giE4wRfMA1adP2k1BTu rpzIvh6hWkdh09XBmbq7IgJ1Nfno7s/s/dccNRBhWxqG8ia+mbIIjwgkALZbcAGzQXJh 2vew== 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=ZyqAk3JV1lMheoleEpLdtdhruI6JP69rj7H32n7LYXs=; b=LzAlBmSik1crI2bkgrhPIRFS+BoKCCoYnrsh7OQUvnFmuqd8AiRj7M21thh0uJeQBF h4VOaZ4P+Le2ReSzyXhz/6jNQTcpxU04oJ/4n7ERDORbQ08Eqq1jjGSQSpV77GchdIfN pxiHSn9RKVXAQ58mtmnIf0z4ACoYztoRyDchq7xEASXZar9dR4EoP3AuIReN52TMvTXO J+sxvu2UNogi3T5Im3wAU7/OtE06XnMhBnBFkzB57nYcloNdCYOaSOdRHI/pWpdEFv1m LP7bWgz6EtMTm6IE1vZzh0JiOB6uIZYcuioOVScUgUJGF6sHpuzsyXWgPhHU2N0j/ncU makQ== X-Gm-Message-State: AOAM530UUfTETpBbyHLfvFT3FxR7AIdHSuLvkO8jU9JZm9FtuitRF7Ag Z6M/PEEkz4dQU7z3Y8DJUf4LH4hQ9e+Eew== X-Received: by 2002:a17:902:728c:b029:f6:6aff:4d66 with SMTP id d12-20020a170902728cb02900f66aff4d66mr1114100pll.20.1622756495406; Thu, 03 Jun 2021 14:41:35 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:35 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 04/29] softfloat: Move minmax_flags to softfloat-parts.c.inc Date: Thu, 3 Jun 2021 14:41:06 -0700 Message-Id: <20210603214131.629841-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 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: David Hildenbrand Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Rename to parts$N_minmax. Combine 3 bool arguments to a bitmask. Introduce ftype_minmax functions as a common optimization point. Fold bfloat16 expansions into the same macro as the other types. Reviewed-by: David Hildenbrand Signed-off-by: Richard Henderson --- fpu/softfloat.c | 198 ++++++++++++++------------------------ fpu/softfloat-parts.c.inc | 80 +++++++++++++++ 2 files changed, 152 insertions(+), 126 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index db14bd09aa..ef750e1e95 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -482,6 +482,15 @@ enum { float_cmask_anynan = float_cmask_qnan | float_cmask_snan, }; +/* Flags for parts_minmax. */ +enum { + /* Set for minimum; clear for maximum. */ + minmax_ismin = 1, + /* Set for the IEEE 754-2008 minNum() and maxNum() operations. */ + minmax_isnum = 2, + /* Set for the IEEE 754-2008 minNumMag() and minNumMag() operations. */ + minmax_ismag = 4, +}; /* 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, uint64_t a, #define parts_uint_to_float(P, I, Z, S) \ PARTS_GENERIC_64_128(uint_to_float, P)(P, I, Z, S) +static FloatParts64 *parts64_minmax(FloatParts64 *a, FloatParts64 *b, + float_status *s, int flags); +static FloatParts128 *parts128_minmax(FloatParts128 *a, FloatParts128 *b, + float_status *s, int flags); + +#define parts_minmax(A, B, S, F) \ + PARTS_GENERIC_64_128(minmax, A)(A, B, S, F) + /* * Helper functions for softfloat-parts.c.inc, per-size operations. */ @@ -3258,145 +3275,74 @@ float128 uint64_to_float128(uint64_t a, float_status *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 - * 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 ismin, - bool ieee, bool ismag, float_status *s) + +static float16 float16_minmax(float16 a, float16 b, float_status *s, int flags) { - 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, *pr; - switch (a.cls) { - case float_class_normal: - a_exp = a.exp; - break; - case float_class_inf: - a_exp = INT_MAX; - break; - case float_class_zero: - a_exp = INT_MIN; - break; - default: - g_assert_not_reached(); - break; - } - switch (b.cls) { - case float_class_normal: - b_exp = b.exp; - break; - case float_class_inf: - b_exp = INT_MAX; - break; - case float_class_zero: - b_exp = INT_MIN; - break; - default: - g_assert_not_reached(); - break; - } + float16_unpack_canonical(&pa, a, s); + float16_unpack_canonical(&pb, b, s); + pr = parts_minmax(&pa, &pb, s, flags); - if (ismag && (a_exp != b_exp || a.frac != b.frac)) { - bool a_less = a_exp < b_exp; - if (a_exp == b_exp) { - a_less = a.frac < b.frac; - } - return a_less ^ ismin ? b : a; - } - - if (a.sign == b.sign) { - bool a_less = a_exp < b_exp; - if (a_exp == b_exp) { - a_less = a.frac < b.frac; - } - return a.sign ^ a_less ^ ismin ? b : a; - } else { - return a.sign ^ ismin ? b : a; - } - } + return float16_round_pack_canonical(pr, s); } -#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 = 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, *pr; + + bfloat16_unpack_canonical(&pa, a, s); + bfloat16_unpack_canonical(&pb, b, s); + pr = parts_minmax(&pa, &pb, s, flags); + + return bfloat16_round_pack_canonical(pr, s); } -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 flags) +{ + FloatParts64 pa, pb, *pr; -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) + float32_unpack_canonical(&pa, a, s); + float32_unpack_canonical(&pb, b, s); + pr = parts_minmax(&pa, &pb, s, flags); -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 = minmax_floats(pa, pb, ismin, isiee, ismag, s); \ - return bfloat16_round_pack_canonical(&pr, s); \ + return float32_round_pack_canonical(pr, s); } -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 flags) +{ + FloatParts64 pa, pb, *pr; -#undef BF16_MINMAX + float64_unpack_canonical(&pa, a, s); + float64_unpack_canonical(&pb, b, s); + pr = parts_minmax(&pa, &pb, s, flags); + + return float64_round_pack_canonical(pr, s); +} + +#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 /* Floating point compare */ static FloatRelation compare_floats(FloatParts64 a, FloatParts64 b, bool is_quiet, diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index 2eb7bb96b3..b9094768db 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -938,3 +938,83 @@ static void partsN(uint_to_float)(FloatPartsN *p, uint64_t a, p->frac_hi = a << shift; } } + +/* + * Float min/max. + */ +static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b, + float_status *s, int flags) +{ + int ab_mask = 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) ? b : a; + } + return parts_pick_nan(a, b, s); + } + + a_exp = a->exp; + b_exp = b->exp; + + if (unlikely(ab_mask != float_cmask_normal)) { + switch (a->cls) { + case float_class_normal: + break; + case float_class_inf: + a_exp = INT16_MAX; + break; + case float_class_zero: + a_exp = INT16_MIN; + break; + default: + g_assert_not_reached(); + break; + } + switch (b->cls) { + case float_class_normal: + break; + case float_class_inf: + b_exp = INT16_MAX; + break; + case float_class_zero: + b_exp = INT16_MIN; + break; + default: + g_assert_not_reached(); + break; + } + } + + /* Compare magnitudes. */ + cmp = a_exp - b_exp; + if (cmp == 0) { + cmp = frac_cmp(a, b); + } + + /* + * Take the sign into account. + * For ismag, only do this if the magnitudes are equal. + */ + if (!(flags & minmax_ismag) || cmp == 0) { + if (a->sign != b->sign) { + /* For differing signs, the negative operand is less. */ + cmp = a->sign ? -1 : 1; + } else if (a->sign) { + /* For two negative operands, invert the magnitude comparison. */ + cmp = -cmp; + } + } + + if (flags & minmax_ismin) { + cmp = -cmp; + } + return cmp < 0 ? b : a; +} From patchwork Thu Jun 3 21:41:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453315 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp627795jao; Thu, 3 Jun 2021 14:45:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwARGHRSqmCKoO2tFNlKWuoXhbLiFan3s2ZGh71trbUhT/ukwPmE/CPNqkgHDC5dLE2ZXum X-Received: by 2002:a05:6102:2046:: with SMTP id q6mr483267vsr.51.1622756710400; Thu, 03 Jun 2021 14:45:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756710; cv=none; d=google.com; s=arc-20160816; b=rtvw7c0cpeVqdc990aUoEQkjKQX3EmiMf9IKDiLxZu54IVbb+9F0907ykYMXeVccLZ LZPaxntLxykL0SndZkuF2HRwwrypXni0PEqTdDdQUmhUCEvVuJ0C5VefO645umwqmOod ee8LbVI6BLmbAVSB36o1kqM2T/FPlzxJ17fPeE1RgPyhK236TqDKPTAp93LcqyEbHid/ z5HuOJqh9hKJWkML1Da6g9m+z9zA2sJVDJxW5nBfiIhwZXL5Z/jyaczz+lZeH5Mp0Xaw E98D4TyfMYCfuz8U2KAmecpSjHefMyFFTVX3CKSE+gFfV+o+IZViD5jA5g7/XPJaUuP2 mNXw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=keKjVz3imnmcUE3wTIllL+iQylaB2Eebnx0eXWC+uoM=; b=0MhocXv4vJB0CMlS4KyLZKfxBu905qGGc9pQZXbyPxlX+jsn0v1gI5o8Qoo4peS6j9 omQY5URZpeOQyUOxP1f/Y+px2fCR7eeqdriJca9so6F9IVsynn7Rhgw7w2Rwzeqp6h3I Ni1Jn5tiEeQxrGqYvnkw30Hydm7eVHdmO17Rhkd+DgJRCWATlXJFMAYursOE5DdUk89K B/L/qSKWwhHpZF/9k8i3JLc9C6Blts05GI2eqvYHqb5KOSLR3E71DPgrC2iORrt2KUog MU/HfCmZcsgoNW27m/1tYCKZDxVacDHe7by+YdZLl5zBGrkNzb76iAraXdZMnjL721gm BYZw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Jg6erSt0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id f3si2033959uab.107.2021.06.03.14.45.10 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:45:10 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Jg6erSt0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:33996 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lov9J-0004yd-M9 for patch@linaro.org; Thu, 03 Jun 2021 17:45:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58218) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov5v-00021f-GS for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:39 -0400 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]:53094) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5t-00011b-NH for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:39 -0400 Received: by mail-pj1-x1030.google.com with SMTP id h16so4445410pjv.2 for ; Thu, 03 Jun 2021 14:41:36 -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=keKjVz3imnmcUE3wTIllL+iQylaB2Eebnx0eXWC+uoM=; b=Jg6erSt06mrzVQ8iwCmUTSU+JmpntcyfKNOvUAEPdki+s6Of3krtkKHY12lyzaL0vE L5e40lnB7C6j/uHh7YQk7pfkQAaUCNIh3r05qFZRGUXbmR2FAUsNNhAPkRqDI1Bkn5XI 0thG+6ob0GwXYgeug/99gQm1pdey7Z/4cutfhFvdoSImSk7nfwTESNdG7/rakXEHC04h TRHGUvRuVkkO/lM7maNK7Ym7hVYiMK7CeAWZcz0VzpFcyLIahYA0H0qqk2s3+luFxqsW L7wpLubvhxzniHBzrqlnRSzgEpXIGAHjBFFETimxg7N65zIbZBDEkLITaSngAtG0xWuI xiTg== 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=keKjVz3imnmcUE3wTIllL+iQylaB2Eebnx0eXWC+uoM=; b=HBfZotLArGYevFsgkn8GxbfDVFOqdpzrNhtpHPlJEbxqSYjVxB+NNGhMx14SuTlk3r CKcUEgliiBlf0Lib15YVyq5PBsjeKQjMyB6ZQ9X/7xUp6qBtWhcmGCYHjRF6ktREDUYt YXfClmb1CnSvDFBeComGJIZ8xjx9pIlG4S5R/zlafV4hNulC4uImAJnOKPwwyacrAk4N BlSs9QnGT22JjhKmY9pFHLCf4FFnZTAKY6hJnzrh7M2+k9MH9dALG3xxMt7O0Emu2CEr SZYLhWdacooIik8maH11b5pyd9CgZR++k/ByGLIRCjqMHs1P2Z45Ybj1VSAFi0uJMu6i FHMQ== X-Gm-Message-State: AOAM5327B1DjiL5SthUaJChyt9X7YZ2gxGsfKs2pGE4HUp36z4qdRTVY uBpsMak8/xV+gRf++0LRI91GuBFFBFx5Ng== X-Received: by 2002:a17:902:ea92:b029:103:a022:c545 with SMTP id x18-20020a170902ea92b0290103a022c545mr1192574plb.43.1622756496107; Thu, 03 Jun 2021 14:41:36 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:35 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 05/29] softfloat: Implement float128_(min|minnum|minnummag|max|maxnum|maxnummag) Date: Thu, 3 Jun 2021 14:41:07 -0700 Message-Id: <20210603214131.629841-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1030; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1030.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: David Hildenbrand Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: David Hildenbrand The float128 implementation is straight-forward. Unfortuantely, we don't have any tests we can simply adjust/unlock. Signed-off-by: David Hildenbrand Message-Id: <20210517142739.38597-24-david@redhat.com> [rth: Update for changed parts_minmax return value] Signed-off-by: Richard Henderson --- include/fpu/softfloat.h | 6 ++++++ fpu/softfloat.c | 13 +++++++++++++ 2 files changed, 19 insertions(+) -- 2.25.1 diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 53f2c2ea3c..ed32040aa9 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -1204,6 +1204,12 @@ float128 float128_rem(float128, float128, float_status *status); float128 float128_sqrt(float128, float_status *status); FloatRelation float128_compare(float128, float128, float_status *status); FloatRelation float128_compare_quiet(float128, float128, float_status *status); +float128 float128_min(float128, float128, float_status *status); +float128 float128_max(float128, float128, float_status *status); +float128 float128_minnum(float128, float128, float_status *status); +float128 float128_maxnum(float128, float128, float_status *status); +float128 float128_minnummag(float128, float128, float_status *status); +float128 float128_maxnummag(float128, float128, float_status *status); bool float128_is_quiet_nan(float128, float_status *status); bool float128_is_signaling_nan(float128, float_status *status); float128 float128_silence_nan(float128, float_status *status); diff --git a/fpu/softfloat.c b/fpu/softfloat.c index ef750e1e95..4fee5a6cb7 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3324,6 +3324,18 @@ static float64 float64_minmax(float64 a, float64 b, float_status *s, int flags) return float64_round_pack_canonical(pr, s); } +static float128 float128_minmax(float128 a, float128 b, + float_status *s, int flags) +{ + FloatParts128 pa, pb, *pr; + + float128_unpack_canonical(&pa, a, s); + float128_unpack_canonical(&pb, b, s); + pr = parts_minmax(&pa, &pb, s, flags); + + return float128_round_pack_canonical(pr, s); +} + #define MINMAX_1(type, name, flags) \ type type##_##name(type a, type b, float_status *s) \ { return type##_minmax(a, b, s, flags); } @@ -3340,6 +3352,7 @@ MINMAX_2(float16) MINMAX_2(bfloat16) MINMAX_2(float32) MINMAX_2(float64) +MINMAX_2(float128) #undef MINMAX_1 #undef MINMAX_2 From patchwork Thu Jun 3 21:41:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453319 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp629191jao; Thu, 3 Jun 2021 14:47:51 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzUeV9MEdhfAbAmMTvMsMoNBNVw2rPOedh7CLdR6wlqg70lPJlafwNBMeW8FlKGAeqfyOZP X-Received: by 2002:a05:6214:883:: with SMTP id cz3mr1755086qvb.38.1622756870950; Thu, 03 Jun 2021 14:47:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756870; cv=none; d=google.com; s=arc-20160816; b=umv91pkEbRt4i4t0OiFEeUMUilxXKjMETan/INjK1V1TIeCzZshUYf0eGEensRw6Ry cOh6DysBfBL8a4nRqoweXClsKZKKf4vHCLhm9phS8dL9krMmZzxFxHY98IJQvYdlQpm+ b8vy/wnr6aMNqbrkpZ1/a1qJkS+JDu0PZc6DCVWTDFX29SpREPV0pmzI8W2IUEOYcuDw 3/Z73XUZ1wvf4RNF6+qfgTsEIjEoKvNJDuSAxZcF/vp9THOAUj/+nbgLJnR+0iyOxUvy D2tE1WY6gi6MJieS06bKascLsbqOJwKQOEbC02nBImyEucKZ4FPP7eWQEHR0pMVjOo55 Uzsg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=mH+tBMzgWSEdrBM44cETXcgu3S/9bsd4y7eciPgdKaQ=; b=sxLtiderScpW8oCuaZ7umb8dtHxd71nPSRkNK15NCNmNzKSaFnz3QI9//NO51yz2g8 ksChjyfbq1kcPEzoItZ0OogvbCasMREXK+3e0C8EYI+QPUehHgsYK6sc1tNC647x8cdT fnOeZKhrIp8zAQqj9Ro/WpLHvAa3BfVuIjUvSNTl4EfXij81eSEMsGFW8fU8aocS3IPq hjkIOHXJOXRHVVkuqkTvzN9sI646qmh9l70T/nEb8SBPPSz50Mxmdh0C4w4tMmpJoAyR 7Z2+yd6EdgXj4i99HeW+qV6+aQpbwHrSX9HP1J1ZIaBwrEQRhbtj+dV8zwhnhaouE3gs e1uA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GEBYsj+x; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id g3si2610977qti.37.2021.06.03.14.47.50 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:47:50 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GEBYsj+x; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:42564 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovBu-0002MF-BB for patch@linaro.org; Thu, 03 Jun 2021 17:47:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58264) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov5x-00028u-Oi for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:41 -0400 Received: from mail-pg1-x52b.google.com ([2607:f8b0:4864:20::52b]:46710) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5u-00011r-6X for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:41 -0400 Received: by mail-pg1-x52b.google.com with SMTP id n12so6135079pgs.13 for ; Thu, 03 Jun 2021 14:41:37 -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=mH+tBMzgWSEdrBM44cETXcgu3S/9bsd4y7eciPgdKaQ=; b=GEBYsj+xwXsyz5iTrIAIm4WNtRTzfubAC5blxqb4mKwHOiPcLEIIPKNlLJeFQNNPR6 w2JerqyCqwaQgVMMdYTjR6IN4JlLFFapLalfbpKg/TidN5Wb/05R5StlvTUV+B5n1PTi RC1DZOCXJ2jxbid+7YfYmDgkWJATqHMgw1rVAr0ByyHv5h6r2emxZemN0moLafWGRnAI IxI+8h6HA4eA+3LNADyEqDe0YFOR+iuB27JKnXcSiZboby4nbrkOaofNgb/a4jgpKuos jszG+e+3iQtVx96lME2+XbgxWdZivbSDykKdcF9PT3JchQi1VjFm2Z9busdSxDQqkuYW 5LFw== 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=mH+tBMzgWSEdrBM44cETXcgu3S/9bsd4y7eciPgdKaQ=; b=rUUwnXVzlUs83BY6AKcCy5XE4iJ5g1QW0UjO+S3v43MOesa99MuuHZyqEnldIVgJhe s/erVd5XTQbwPMdUeDsg8ymuYN+jhrq60Di5yU9oAjDfydp3GTmZZGDWoKkJ4yPbQnNZ 9grWnm5koPGYzV/BTJ71Cf9GRrRzfDD8I+G10wgRSHyEU3A2bBVlAebvQFeDVBL1c8+O v5n9knmBFjaoInXkSthRPsn0ZQBSzk5AXrQmYpbdJVB/6bt01vZxVbyN456Z0BQu6Lbl SximNNO8YCh+WbYidkI9Ia7xh/PoSNmDdVTP+ZDRd7AtwDK3ADFBASlA+71Du2Av/IpQ erSw== X-Gm-Message-State: AOAM532wuGGF9db5LVRPIu3SPR5Pvwbtt2vF0599XFus1qXSQ/Ld05ol nYF6UeHpngXJBB7VD3mFGAlOXAOb35dQXQ== X-Received: by 2002:a63:fc20:: with SMTP id j32mr1515221pgi.8.1622756496756; Thu, 03 Jun 2021 14:41:36 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:36 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 06/29] softfloat: Move compare_floats to softfloat-parts.c.inc Date: Thu, 3 Jun 2021 14:41:08 -0700 Message-Id: <20210603214131.629841-7-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 208 ++++++++++++++------------------------ fpu/softfloat-parts.c.inc | 57 +++++++++++ 2 files changed, 133 insertions(+), 132 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 4fee5a6cb7..6f1bbbe6cf 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -882,6 +882,14 @@ static FloatParts128 *parts128_minmax(FloatParts128 *a, FloatParts128 *b, #define parts_minmax(A, B, S, F) \ PARTS_GENERIC_64_128(minmax, A)(A, B, S, F) +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. */ @@ -3357,92 +3365,42 @@ MINMAX_2(float128) #undef MINMAX_1 #undef MINMAX_2 -/* Floating point compare */ -static FloatRelation compare_floats(FloatParts64 a, FloatParts64 b, bool is_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 == float_class_snan || - b.cls == float_class_snan) { - float_raise(float_flag_invalid, s); - } - return float_relation_unordered; - } + FloatParts64 pa, pb; - if (a.cls == float_class_zero) { - if (b.cls == float_class_zero) { - return float_relation_equal; - } - return b.sign ? float_relation_greater : float_relation_less; - } else if (b.cls == 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 == float_class_inf) { - if ((b.cls == float_class_inf) && (a.sign == b.sign)) { - return float_relation_equal; - } - return a.sign ? float_relation_less : float_relation_greater; - } else if (b.cls == float_class_inf) { - return b.sign ? float_relation_greater : float_relation_less; - } - - if (a.sign != b.sign) { - return a.sign ? float_relation_less : float_relation_greater; - } - - if (a.exp == b.exp) { - if (a.frac == 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_greater; - } 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); } -#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); } 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); } 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; @@ -3463,25 +3421,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); } 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); } 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); } 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; @@ -3502,41 +3471,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); } 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); } 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); } 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; 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); } 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); } 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); } /* Multiply A by 2 raised to the power N. */ @@ -6609,52 +6599,6 @@ FloatRelation floatx80_compare_quiet(floatx80 a, floatx80 b, return floatx80_compare_internal(a, b, 1, status); } -static inline FloatRelation -float128_compare_internal(float128 a, float128 b, bool is_quiet, - float_status *status) -{ - bool aSign, bSign; - - if (( ( extractFloat128Exp( a ) == 0x7fff ) && - ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) || - ( ( extractFloat128Exp( b ) == 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 = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0 ) { - /* zero case */ - return float_relation_equal; - } else { - return 1 - (2 * aSign); - } - } else { - if (a.low == b.low && a.high == 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 *status) -{ - 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 b9094768db..3dacb5b4f0 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1018,3 +1018,60 @@ static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b, } return cmp < 0 ? b : a; } + +/* + * Floating point compare + */ +static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b, + float_status *s, bool is_quiet) +{ + int ab_mask = float_cmask(a->cls) | float_cmask(b->cls); + int cmp; + + if (likely(ab_mask == float_cmask_normal)) { + if (a->sign != b->sign) { + goto a_sign; + } + if (a->exp != b->exp) { + cmp = a->exp < b->exp ? -1 : 1; + } else { + cmp = frac_cmp(a, b); + } + if (a->sign) { + cmp = -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 == float_cmask_zero) { + return float_relation_equal; + } else if (a->cls == float_class_zero) { + goto b_sign; + } else { + goto a_sign; + } + } + + if (ab_mask == float_cmask_inf) { + if (a->sign == b->sign) { + return float_relation_equal; + } + } else if (b->cls == float_class_inf) { + goto b_sign; + } else { + g_assert(a->cls == 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; +} From patchwork Thu Jun 3 21:41:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453313 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp627555jao; Thu, 3 Jun 2021 14:44:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxB4heSug1qD7NoB0ByKvyBD8JapFDTmiiM2dbzaS3wGco+YnonieU7zeUKJXXvDA5n1MHO X-Received: by 2002:a05:6808:b22:: with SMTP id t2mr8545602oij.67.1622756681732; Thu, 03 Jun 2021 14:44:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756681; cv=none; d=google.com; s=arc-20160816; b=QKtDOqBXU/dcAQ79MBOdA2XKyszuaRuNai24iZcXPibMolTguy+bwhgse/BboMYSGk CsMGT6zSSQ9iHUZ+so/bG0Tm6ECLA2h7rmF5316FDYfvuv8jB/XLGiBuzxdiXSVUloR1 h96O8GO2zLPOZYGJKaBVzaEJPMXSqthewyRRTza8z7UJ+sqdL+y/rEv4h5j73RkOhmNi BdNq1FeH1QKYT4DRH0xinw0C2sMVt1Wc/EIDiws979I2nBqwl8SbjnlfABMaixfCP0FM Qv3hgh0RQP703QOcLDjwYfhtpJbL6c2aaJ9C0wO7H8k4rXLeikUT6TYzKUsYQcrRzNY/ fuKQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=WsA5H1SuomDIfHMs/+kNzjnQxEcCGSovs51rLnUzoiU=; b=U2TC6ePuwOx3WYxejfA6LObCCkShq86iiujzHMlqcs95s/OR6yNGxmWeT6xr5svhbY O8ULjvr6fJxCrS/Brcnkl1+XGKM/dRMDs4WNslilnZGmG24ONPeC6Qc3o04CeNBmXFFF TkCQxvOwrjSK7PtBLlFMI9D72XSM1B9eMIxrIpLk9opWDPw/5IkmmXDwqiFORIAkg1xd z2uu3PL17ni1SiXMhfK+bdXRPXU8N1hBoI5TfQYKwykWa1J5HX8AtlgzOX2HvYKHsRwQ jytSHCHFIcf8/SGr1nMD/xQa5gkDIDKztfFIQ6GBHYVW953tlNjn27bjpbg5dPwaLyYg Gc5g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dP7hLQuV; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id p16si159956oto.74.2021.06.03.14.44.41 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:44:41 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dP7hLQuV; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:57010 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lov8r-0001XP-4G for patch@linaro.org; Thu, 03 Jun 2021 17:44:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58280) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov5y-0002Ah-99 for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:42 -0400 Received: from mail-pl1-x632.google.com ([2607:f8b0:4864:20::632]:42771) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5u-00012e-Oh for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:42 -0400 Received: by mail-pl1-x632.google.com with SMTP id v13so3582253ple.9 for ; Thu, 03 Jun 2021 14:41:38 -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=WsA5H1SuomDIfHMs/+kNzjnQxEcCGSovs51rLnUzoiU=; b=dP7hLQuVnKWMn920KUn1YXKSwBLOwSDF9yjYp9atbS4QrOYTthuPJlpEAh4oqu1w0T +30ja24isQQiEEIAlzixdbtTtkaAhb7ygX8kRP3sL1/KQmn0+l4xA66XQTtUSpMXNOaz sbpmVYxh/sG3euRekcSKfMeyyTkG4DGOR9mJpbobGs20fdUPPyX4XmHO9P9LruSbVyHp pEPEWZnlLRVyiuhJ7bwwI9ZIM0JLwsKs6cDAcTY5HoJleTM3afR4wpgYwofVlA1FdJkN P8lIHFEpGd+KGCVQ34ixxRNQCy+gxBLaW7QuegI4DkoyoDgB9cne1+ByfhIdzqB/o/1J wGQw== 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=WsA5H1SuomDIfHMs/+kNzjnQxEcCGSovs51rLnUzoiU=; b=b+E+4rN5rAEbuBIKnN94h/g9Md9YyctexWntp1AMnclb/KjOebQdPOsD981FAtsP8J FNqAEx9OU0UjnZSjajiOrRAc/n90DGGoIlUf/BsYPDSEtBi1xj6b+8aTeEmGvWW+ahw+ X0MYwvwgSsNFZYVO7x4wtBTRhRJUXnDp0KlZWE3jMcYDjy2iCdann+f2+k2Ds1KX1xg1 zNlyK9fDr2vaz19MT1fiqeJRqGieYo+vXA0eDXTHcd77WIDiqXrY+q39EZqzB6ZzOYEj ueaHf0YF76X9L1H422anBNguLFZovynNyn+8UjISqWu50cNqatOKPF+dgK0RA9s69SQC NIoA== X-Gm-Message-State: AOAM530t3CkqhUJoEb7OtbeYO8bD0WT7CYCjA+ZW8oCKrUezn+KH+ShF XGg69C2RIvQNNG3IMBI0j1eIz84p5nuuuQ== X-Received: by 2002:a17:902:9f91:b029:107:5976:f9de with SMTP id g17-20020a1709029f91b02901075976f9demr1163505plq.38.1622756497301; Thu, 03 Jun 2021 14:41:37 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:37 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 07/29] softfloat: Move scalbn_decomposed to softfloat-parts.c.inc Date: Thu, 3 Jun 2021 14:41:09 -0700 Message-Id: <20210603214131.629841-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::632; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x632.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Rename to parts$N_scalbn. Reimplement float128_scalbn with FloatParts128. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 103 +++++++++++++------------------------- fpu/softfloat-parts.c.inc | 21 ++++++++ 2 files changed, 55 insertions(+), 69 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6f1bbbe6cf..666b5a25d6 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -890,6 +890,12 @@ static int parts128_compare(FloatParts128 *a, FloatParts128 *b, #define parts_compare(A, B, S, Q) \ PARTS_GENERIC_64_128(compare, A)(A, B, S, Q) +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. */ @@ -3529,58 +3535,53 @@ FloatRelation float128_compare_quiet(float128 a, float128 b, float_status *s) return float128_do_compare(a, b, s, true); } -/* 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 == float_class_normal) { - /* The largest float type (even though not supported by FloatParts64) - * 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 = MIN(MAX(n, -0x10000), 0x10000); - a.exp += n; - } - return a; -} +/* + * Scale by 2**N + */ float16 float16_scalbn(float16 a, int n, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; - float16_unpack_canonical(&pa, a, status); - pr = 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); } float32 float32_scalbn(float32 a, int n, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; - float32_unpack_canonical(&pa, a, status); - pr = 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); } float64 float64_scalbn(float64 a, int n, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; - float64_unpack_canonical(&pa, a, status); - pr = 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); } bfloat16 bfloat16_scalbn(bfloat16 a, int n, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; - bfloat16_unpack_canonical(&pa, a, status); - pr = 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); } /* @@ -6638,42 +6639,6 @@ floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) aSign, aExp, aSig, 0, status); } -float128 float128_scalbn(float128 a, int n, float_status *status) -{ - bool aSign; - int32_t aExp; - uint64_t aSig0, aSig1; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return propagateFloat128NaN(a, a, status); - } - return a; - } - if (aExp != 0) { - aSig0 |= UINT64_C(0x0001000000000000); - } else if (aSig0 == 0 && aSig1 == 0) { - return a; - } else { - aExp++; - } - - if (n > 0x10000) { - n = 0x10000; - } else if (n < -0x10000) { - n = -0x10000; - } - - aExp += 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 3dacb5b4f0..bf935c4fc2 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1075,3 +1075,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 += MIN(MAX(n, -0x10000), 0x10000); + break; + default: + g_assert_not_reached(); + } +} From patchwork Thu Jun 3 21:41:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453311 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp627023jao; Thu, 3 Jun 2021 14:43:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwNZL5TyeMwiQYup64J4T93uvYSJm8QhQw5l1WB6fUL9WXZou60vE/Y7z4se1XLij9M6vrJ X-Received: by 2002:a9d:7312:: with SMTP id e18mr1121271otk.334.1622756624382; Thu, 03 Jun 2021 14:43:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756624; cv=none; d=google.com; s=arc-20160816; b=epo2MYX3FkVAaTwpbGQ7HA8fcXkIX63mqfc4j8GGlh1kKRiAE/YeR1+S+bSajlGgJ+ x4V4OLRBV06ehOjwxFeOYU+cuw22QBBFchmRqnZKO5zYyUg3yKeDNb8Pd7NPndOnLLDS qxR9LLZAxJv6NDJRHRU8hmZJBC9SqO4oBKbWTrgz0IK0i2dQxGYdCLgryATdHyh13EbS 2ZPQLmwxuUXcdXvmnOozT2GJ9DjiYQppXE47DatPS7mbqBBzFvplkKsZwBky8Z26IxXw SabRltPfXjJJRwXAiYSn+W60StdjnYONQJDgvorzIKhLF7TtfXgzRM3jD+3G8ODbvJjN mo6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=daxdDiwfd3WqyKzbUdPQYbEO4yA2SpqfeiJ6sgOBQMg=; b=EX1VDB3zr5IFKG3AVRVRr4F5+BGi0p4+2pWhl2PevWlIwm5vqE3uXWnVt8U+J/0YjI ycZlkz0QWHs6NXEmbzHxB9C/L9dCHce0+Jk77k4dAekImm5NkuRCa52wuH1P28nS03Er 4wN+EZIZixlUe3TR7FbHX6H91ZzyjXQ10I+gaWNyxRNhnkOTGbEpZXV/i+N5bFeb9LDX 542pdTRzt8bNas3m1kHij3P+wQhMHx98u44rJMOmpJPh0+w+JBV+qYsUyauSt4u9NqjX PQc7NEVs4VILTthGF9prYr2qyFnRpUr4xo2S7T6l6spS2aUUr+TR8ACdqQyNb2HYoDbx oZJw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=fbNFpLS8; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id h188si156006oia.62.2021.06.03.14.43.44 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:43:44 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=fbNFpLS8; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:53858 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lov7v-0007rz-MH for patch@linaro.org; Thu, 03 Jun 2021 17:43:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58296) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov5y-0002CJ-QE for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:42 -0400 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]:46067) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5v-00014G-He for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:42 -0400 Received: by mail-pj1-x1031.google.com with SMTP id z3-20020a17090a3983b029016bc232e40bso1272994pjb.4 for ; Thu, 03 Jun 2021 14:41:39 -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=daxdDiwfd3WqyKzbUdPQYbEO4yA2SpqfeiJ6sgOBQMg=; b=fbNFpLS8iB0+BpgaAa3xSu/YDsI5SqSL1+abePnjyI6JpUXNuThMLdKYlnjK9QJIbE zgKlqW7oO9a8u0BBW0AEBfgMM3izEh95VEqjnGSsB518+MR1ec7BGvqEH1/fuw9NGW9A TzblLTUbgJW2SmGKMdZ0UwAvM6JlaoateR0pxxVJmsP4IpNTC7JejUExz8PPEKwvqpij NmIKPgGbhkfvWDKf3rKttQUlNz+4NyBySavT7Ebuz0POob8czuQrXeWoQe1GAAu294xK o4bQMATZTjRV7F+hdn9mx7u+enLghY2t7JVkJEBnlZmVH2CKcwzGLoC0pBRDegK5hmxF GTnA== 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=daxdDiwfd3WqyKzbUdPQYbEO4yA2SpqfeiJ6sgOBQMg=; b=eiFxP6PNFlxgm/kRRoESSCsj/dt5WBSsWGA0v+LtuECzzTQ+ZVZuM7gT93Ck7m5F6q qo6AtIUtHYfu5pbcGv4Iy8NOfKQhhf7W0/bS9sP74hXX0dP8YxuyA5Y5ZxinOS485ftr 6dKOgcQ+QXs4NkV5xbnHm1GVNpRI4H+k4LOcP+cP4cKsm9HOz2EpJauE21yyCb0fl84F KUO1/lbjrmead1w/nqtrnAw6GrMnib48pr6IK27Yiosi7gZ3LvZwTU69cCv1MDqprxwS VUtrDFnJo0YTZrLFj3P65g+iCjGCZuruaN/iW8Ubdf9esDyY/IDTzUq/D9R4tzg52zdK LSmw== X-Gm-Message-State: AOAM531nO3izDYVQW/RKZR6HA7U0tuE7OwwS/06RS6i1eMymcj6pxhbj /FzCSPl9w42czXYZji9lEvI+GTuCSjLnTA== X-Received: by 2002:a17:90a:e98f:: with SMTP id v15mr13320945pjy.235.1622756498028; Thu, 03 Jun 2021 14:41:38 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:37 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 08/29] softfloat: Move sqrt_float to softfloat-parts.c.inc Date: Thu, 3 Jun 2021 14:41:10 -0700 Message-Id: <20210603214131.629841-9-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1031; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1031.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, 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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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. Tested-by: Alex Bennée Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 207 ++++++++++---------------------------- fpu/softfloat-parts.c.inc | 206 +++++++++++++++++++++++++++++++++++++ 2 files changed, 261 insertions(+), 152 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 666b5a25d6..0f2eed8d29 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -820,6 +820,12 @@ static FloatParts128 *parts128_div(FloatParts128 *a, FloatParts128 *b, #define parts_div(A, B, S) \ PARTS_GENERIC_64_128(div, A)(A, B, S) +static void parts64_sqrt(FloatParts64 *a, float_status *s, const FloatFmt *f); +static void parts128_sqrt(FloatParts128 *a, float_status *s, const FloatFmt *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, FloatParts128 *a) #define frac_widen(A, B) FRAC_GENERIC_64_128(widen, B)(A, B) +/* + * 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] = { + 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) @@ -3586,103 +3616,35 @@ float128 float128_scalbn(float128 a, int n, float_status *status) /* * 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. */ -static FloatParts64 sqrt_float(FloatParts64 a, float_status *s, const FloatFmt *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 == float_class_zero) { - return a; /* sqrt(+-0) = +-0 */ - } - if (a.sign) { - float_raise(float_flag_invalid, s); - parts_default_nan(&a, s); - return a; - } - if (a.cls == float_class_inf) { - return a; /* sqrt(+inf) = +inf */ - } - - assert(a.cls == 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 = a.frac >> (2 - (a.exp & 1)); - a.exp >>= 1; - - /* Bit-by-bit computation of sqrt. */ - r_frac = 0; - s_frac = 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 = DECOMPOSED_BINARY_POINT - 2; - last_bit = MAX(p->frac_shift - 4, 0); - do { - uint64_t q = 1ULL << bit; - uint64_t t_frac = s_frac + q; - if (t_frac <= a_frac) { - s_frac = t_frac + q; - a_frac -= t_frac; - r_frac += q; - } - a_frac <<= 1; - } while (--bit >= last_bit); - - /* Undo the right shift done above. If there is any remaining - * fraction, the result is inexact. Set the sticky bit. - */ - a.frac = (r_frac << 2) + (a_frac != 0); - - return a; -} - float16 QEMU_FLATTEN float16_sqrt(float16 a, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; - float16_unpack_canonical(&pa, a, status); - pr = 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); } static float32 QEMU_SOFTFLOAT_ATTR soft_f32_sqrt(float32 a, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; - float32_unpack_canonical(&pa, a, status); - pr = 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); } static float64 QEMU_SOFTFLOAT_ATTR soft_f64_sqrt(float64 a, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; - float64_unpack_canonical(&pa, a, status); - pr = 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); } float32 QEMU_FLATTEN float32_sqrt(float32 xa, float_status *s) @@ -3741,11 +3703,20 @@ float64 QEMU_FLATTEN float64_sqrt(float64 xa, float_status *s) bfloat16 QEMU_FLATTEN bfloat16_sqrt(bfloat16 a, float_status *status) { - FloatParts64 pa, pr; + FloatParts64 p; - bfloat16_unpack_canonical(&pa, a, status); - pr = 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); } /*---------------------------------------------------------------------------- @@ -6473,74 +6444,6 @@ float128 float128_rem(float128 a, float128 b, float_status *status) status); } -/*---------------------------------------------------------------------------- -| 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 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if (aSig0 | aSig1) { - return propagateFloat128NaN(a, a, status); - } - if ( ! aSign ) return a; - goto invalid; - } - if ( aSign ) { - if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; - invalid: - float_raise(float_flag_invalid, status); - return float128_default_nan(status); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE; - aSig0 |= UINT64_C(0x0001000000000000); - zSig0 = estimateSqrt32( aExp, aSig0>>17 ); - shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 ); - zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); - doubleZSig0 = zSig0<<1; - mul64To128( zSig0, zSig0, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (int64_t) rem0 < 0 ) { - --zSig0; - doubleZSig0 -= 2; - add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); - if ( ( zSig1 & 0x1FFF ) <= 5 ) { - if ( zSig1 == 0 ) zSig1 = 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 |= 1; - term2 |= doubleZSig0; - add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 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 bf935c4fc2..d69f357352 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -597,6 +597,212 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatPartsN *b, return a; } +/* + * 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 = 3u << 30; + const uint64_t three64 = 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 != 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 = 4^e frac; with integer e, and frac in [1, 4) + * m = 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 = a->exp & 1; + index = extract64(a->frac_hi, 57, 6) | (!exp_odd << 6); + if (!exp_odd) { + frac_shr(a, 1); + } + + /* + * Approximate r ~= 1/sqrt(m) and s ~= sqrt(m) when m in [1, 4). + * + * Initial estimate: + * 7-bit lookup table (1-bit exponent and 6-bit significand). + * + * The relative error (e = r0*sqrt(m)-1) of a linear estimate + * (r0 = 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 = m*r + * d = s*r + * u = 3 - d + * r = r*u/2 + * + * Fixed point representations: + * m, s, d, u, three are all 2.30; r is 0.32 + */ + m64 = a->frac_hi; + m32 = m64 >> 32; + + r32 = rsqrt_tab[index] << 16; + /* |r*sqrt(m) - 1| < 0x1.FDp-9 */ + + s32 = ((uint64_t)m32 * r32) >> 32; + d32 = ((uint64_t)s32 * r32) >> 32; + u32 = three32 - d32; + + if (N == 64) { + /* float64 or smaller */ + + r32 = ((uint64_t)r32 * u32) >> 31; + /* |r*sqrt(m) - 1| < 0x1.7Bp-16 */ + + s32 = ((uint64_t)m32 * r32) >> 32; + d32 = ((uint64_t)s32 * r32) >> 32; + u32 = three32 - d32; + + if (fmt->frac_size <= 23) { + /* float32 or smaller */ + + s32 = ((uint64_t)s32 * u32) >> 32; /* 3.29 */ + s32 = (s32 - 1) >> 6; /* 9.23 */ + /* s < sqrt(m) < s + 0x1.08p-23 */ + + /* compute nearest rounded result to 2.23 bits */ + uint32_t d0 = (m32 << 16) - s32 * s32; + uint32_t d1 = s32 - d0; + uint32_t d2 = d1 + s32 + 1; + s32 += d1 >> 31; + a->frac_hi = (uint64_t)s32 << (64 - 25); + + /* increment or decrement for inexact */ + if (d2 != 0) { + a->frac_hi += ((int32_t)(d1 ^ d2) < 0 ? -1 : 1); + } + goto done; + } + + /* float64 */ + + r64 = (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 = three64 - d64; + + mul64To128(s64, u64, &s64, &discard); /* 3.61 */ + s64 = (s64 - 2) >> 9; /* 12.52 */ + + /* Compute nearest rounded result */ + uint64_t d0 = (m64 << 42) - s64 * s64; + uint64_t d1 = s64 - d0; + uint64_t d2 = d1 + s64 + 1; + s64 += d1 >> 63; + a->frac_hi = s64 << (64 - 54); + + /* increment or decrement for inexact */ + if (d2 != 0) { + a->frac_hi += ((int64_t)(d1 ^ d2) < 0 ? -1 : 1); + } + goto done; + } + + r64 = (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 = three64 - d64; + mul64To128(u64, r64, &r64, &discard); + r64 <<= 1; + /* |r*sqrt(m) - 1| < 0x1.a5p-31 */ + + mul64To128(m64, r64, &s64, &discard); + mul64To128(s64, r64, &d64, &discard); + u64 = 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, &discard); + 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 += 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 = sl; + a->frac_hi = sh; + + done: + /* Convert back from base 4 to base 2. */ + a->exp >>= 1; + if (!(a->frac_hi & DECOMPOSED_IMPLICIT_BIT)) { + frac_add(a, a, a); + } else { + a->exp += 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 From patchwork Thu Jun 3 21:41:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453309 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp626716jao; Thu, 3 Jun 2021 14:43:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyRBGKKlDv75zbmCE2CzaKVfZ8Fy4lmHJmMsoILDkp/sOG8wszBeAvUaaljFoZCKt9gefcO X-Received: by 2002:a67:eb85:: with SMTP id e5mr452679vso.16.1622756595829; Thu, 03 Jun 2021 14:43:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756595; cv=none; d=google.com; s=arc-20160816; b=y0126GLeLVHag88bhJiJycFuWlQNH9I7ZE+x3RigWvFXBcMp8FOLufa2vVHOkugU8n NYzUuD8AwBhD/Lj3cV4AmZmR8Au+MNZ6vxjI5t5DZc4h5GL8oMnekPXQH0BH5FTzKG3N Ef0sa+dFjRlVjcRTWzFsmR6IRUupWfcBEzYCdFi+Y2d37zDMYOkp+8PA+XAb6N5Vhiij t2baC720YG+KUblJh3evV+bjxNVF/T/sD46PEM5sgUQp4LQzmXK0NAmKIfP6m+m0q5s7 YLNWvKdNxNtMLLUC9vb/fSBgQ+8yws63w1frKc/5jWejDNjYMCOd9YrcyYocInFsVHp1 PZvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=X7rkp8u5Uk7lnJ0IeUz2DjyUeUy9fzT1UPPQAOiqDA8=; b=UgR3biqWjaIaiWKCXmyC/lN5o+3rvMtOxTFbGj8FQjBlDQRg9AZx/pIMcNO4mIfPnP Iy/b9wuHeW4t4VWfge817FsDEQmKISj55vWTQHOSGrVIYc5aF33TkgTk3TroYEpe1xlJ OUKO9DdZ7FTs9YARNED/J7kKv3UzMqAk+glbTqOiqNK8OLSzqdRY955WkUSfoVRmc10n Eg7ZsqHbH8v5TTJebzSlCgBBcFUN2Qe9xv+a6FZwKG0fjH6W2YcD5zBjW7Oqqr+MI3je ZFkyQEj7HlDWysQQonrHrDD4ore/nocidubwwkRY1m2gkmLe0RLynUHWdy+5aRVHPUPH ATQg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UZv6SVXs; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id c9si1995575vsh.270.2021.06.03.14.43.15 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:43:15 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UZv6SVXs; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:48542 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lov7S-0004Ls-95 for patch@linaro.org; Thu, 03 Jun 2021 17:43:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58270) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov5x-00029k-V6 for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:41 -0400 Received: from mail-pg1-x52a.google.com ([2607:f8b0:4864:20::52a]:44772) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5w-00014W-2i for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:41 -0400 Received: by mail-pg1-x52a.google.com with SMTP id 29so6148241pgu.11 for ; Thu, 03 Jun 2021 14:41:39 -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=X7rkp8u5Uk7lnJ0IeUz2DjyUeUy9fzT1UPPQAOiqDA8=; b=UZv6SVXsy9sTyZRnlyZjyODYqzlOChVUaAogKSHtq6KQ0lAzkVVd3C+r2erz2ec8Ik S0C5z46iK+RANLWOMKxWcMCtk0OIWX5kWoFEGaGQ7iw92g5+UtWpB6sxtgcD2N2vj/Po LHSRt+3ztwTpa+9SfpFmTQyBXeYHse/vVZ4dCXTOHEizPoMON6puNQ7q4qsgUcWz+NTp +Bk+Uht6TFy2MrLVvAwpMlu3HG0wQ2ZTuThdpspg47ioL2IqpRowoUUrxmUtxAAOfMDJ T8KP3p/97EpcFdwCQbNdDCPFZp3HcmawyCePAxAkzGV0nNnhNTHPRCyFLY1V9l8X+aet vNwQ== 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=X7rkp8u5Uk7lnJ0IeUz2DjyUeUy9fzT1UPPQAOiqDA8=; b=lzX1QHZ0V9L9+zeXuPTG4YeGRPQ1RMtiazKcMFxW0ipkTO56QkV5M6SBQ9fGmlmcSk G0P8O/25DBFRmOHUWQ7Uh1kvYhgvrqjVY1I41W22Z/DiuODeJUxNuf+zBgxE5LpaOhGm ybC+EorOCIC/mafYzWWxZCDkYrgqI8rLL2SIqPCh/jED5PpeX0gnEt1Yni742JKapJ98 LjehA9DOhO6pzEQ25mSseqU/B/q9RIuaHA6FUP9loQuny/RVCOcyIQbFYYsjUSXDDYwe i4gqytKMh9N/9rR/O2qhyZfooPJabzK5qgNw1C32yGvtmp8pyRz82CwY+LBjse62vZGm Jy4w== X-Gm-Message-State: AOAM531/5MQ8AHwrzEGh0kLvsUVM5gUkQbYJiUPWKzJeAurBh7Gg8PjU nGyjZdzSx2g646NYYRGsfl1+UrQLEDMfFw== X-Received: by 2002:a63:fa51:: with SMTP id g17mr1503659pgk.340.1622756498802; Thu, 03 Jun 2021 14:41:38 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:38 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 09/29] softfloat: Split out parts_uncanon_normal Date: Thu, 3 Jun 2021 14:41:11 -0700 Message-Id: <20210603214131.629841-10-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52a; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52a.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" We will need to treat the non-normal cases of floatx80 specially, so split out the normal case that we can reuse. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 8 ++++++ fpu/softfloat-parts.c.inc | 59 +++++++++++++++++++++------------------ 2 files changed, 40 insertions(+), 27 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 0f2eed8d29..ea7ee13201 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -764,6 +764,14 @@ static void parts128_canonicalize(FloatParts128 *p, float_status *status, #define parts_canonicalize(A, S, F) \ PARTS_GENERIC_64_128(canonicalize, A)(A, S, F) +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 d69f357352..e05909db8c 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 = fmt->exp_max; const int frac_shift = fmt->frac_shift; @@ -150,33 +150,9 @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s, const uint64_t round_mask = fmt->round_mask; const uint64_t roundeven_mask = fmt->roundeven_mask; uint64_t inc; - bool overflow_norm; + bool overflow_norm = false; int exp, flags = 0; - if (unlikely(p->cls != float_class_normal)) { - switch (p->cls) { - case float_class_zero: - p->exp = 0; - frac_clear(p); - return; - case float_class_inf: - g_assert(!fmt->arm_althp); - p->exp = fmt->exp_max; - frac_clear(p); - return; - case float_class_qnan: - case float_class_snan: - g_assert(!fmt->arm_althp); - p->exp = fmt->exp_max; - frac_shr(p, fmt->frac_shift); - return; - default: - break; - } - g_assert_not_reached(); - } - - overflow_norm = false; switch (s->float_rounding_mode) { case float_round_nearest_even: inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0); @@ -284,6 +260,35 @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s, float_raise(flags, s); } +static void partsN(uncanon)(FloatPartsN *p, float_status *s, + const FloatFmt *fmt) +{ + if (likely(p->cls == float_class_normal)) { + parts_uncanon_normal(p, s, fmt); + } else { + switch (p->cls) { + case float_class_zero: + p->exp = 0; + frac_clear(p); + return; + case float_class_inf: + g_assert(!fmt->arm_althp); + p->exp = fmt->exp_max; + frac_clear(p); + return; + case float_class_qnan: + case float_class_snan: + g_assert(!fmt->arm_althp); + p->exp = 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 From patchwork Thu Jun 3 21:41:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453316 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp628300jao; Thu, 3 Jun 2021 14:46:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwlj0IMAkBF6J7HnQDbgezyz2hnNPyB3vGE+J9buTQ7SR/8uk3o8yZJ+b+84krf4w96GDzO X-Received: by 2002:a1f:6dc6:: with SMTP id i189mr506837vkc.19.1622756766623; Thu, 03 Jun 2021 14:46:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756766; cv=none; d=google.com; s=arc-20160816; b=CZS9z5SPdfAcTBqAuQ7baDxACqGGdcsGKN33z5WM46avawAt/GC15UsdUN/qhYrMd7 of8KSFGAVF/kBBQgqDuANjIuvDbhcQhBdltc1yHHm+pan7YXoLBbjBGZT2odQpv0PjgZ VFm4aVZcYbuozuQdvTqw8y2ycRj8bwEsfOzY3fhN4iW3xTHIdceENK8kG5CpXFhZI/6L AzZ7E/QXZMwi5q4Wv2V7aBn0TRlDrKcY6ot0QQ2qrQBU6vnP7bWuRMrVHyosuK4Su3Gp Xn5wQn4YIjTWIdl1SrttUaVyN0h1BJCYDDm0FyGcEgHoO/u+Lq3vNTPednj8HePqwiYq OQqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=ppZ1jH79N3swPQMu5gvh4yX8BmZmZOhaiSlhleLfgRI=; b=G91PlmohxYsqcMyd8qUoxFaWTnbofdLeD6gz/boBRogJtolqoRFY8ds0Bh14b+427K RjVw1Ej8ZlM6tU+YMBxkLBcScHm0KlHIbaRrwV64rPuin0Qkcmwl0iNoTQlwyWuSQxdq +sZt6w18xSwZFCWQM2rMRL0fOJNKjK5fW5YPQlJLbWyxbrjy3hDqUvbPmL5pNotpMLIw 4O/F+W/oxYCRFwG4mB/BcszXOMH84sPTvYaUXn3SDZKchm1rLsO0ezrRE60lrNq03ELu NDurVsmjtRkci8yExSG52WeKJdrbdcAsgW3E/9Qm1SDnzwmWMunJOybcWQySObqNsj20 568w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WhqXS0Sn; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id l8si1370730vsq.378.2021.06.03.14.46.06 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:46:06 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WhqXS0Sn; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:34260 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovAD-000596-Ui for patch@linaro.org; Thu, 03 Jun 2021 17:46:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58316) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov5z-0002Ex-Gq for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:43 -0400 Received: from mail-pl1-x630.google.com ([2607:f8b0:4864:20::630]:44020) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5w-00014r-Km for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:43 -0400 Received: by mail-pl1-x630.google.com with SMTP id v12so3580090plo.10 for ; Thu, 03 Jun 2021 14:41:40 -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=ppZ1jH79N3swPQMu5gvh4yX8BmZmZOhaiSlhleLfgRI=; b=WhqXS0Sn8Talgk2LHvsCcZ0eoJvIQSuH9KMIaqVPwzFt/CXUvmIBjNySjuzYC6Bogq mzuoosyX6GhaZa/e45hUP6GhjRRLYjmcE8kbu2kAtCeXxGasnunE/TZ8Gp6Nt5+x4nC6 /l3hecSz/CUQD8uMg+fkWJLW4xmSS8zd+MsMHlwoirJrpwMv0aslwqRChbgxPYznGaB1 8ZamjSTbe9x70w7cfCFtd4Pcu/DQDxbAiSEHLj1CS+9IVEsZLsRVL+Vy6CzdSomTAanR kQ6c40+jpsSRNhk9nqy4vbKOEqCZNqvNMe5n3pGq9t6fw7zocJ04O/1Uhmfn5Zq3Q7U7 d+bw== 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=ppZ1jH79N3swPQMu5gvh4yX8BmZmZOhaiSlhleLfgRI=; b=nizagitmPVRCXExu8KaGeqKtRZ8/9n0dG3GEaEZYWBNlKOSP2atWM8SONpzxr2lCM0 YuSEszSgsDJGw/ZnVKNI7iOSBc2EGeIPjV8Rf2YZSD54/wAz8Ahk+Cv89TzcbYjLWMnm H1SnBRGpKyuK9CHhbgO5BhzfYoMxIuoJtzR7K10GUAqzEtvk9PRr835kcAXJ/vwvzCD/ NxznkEBzxX8TvkxAJEjh2i6cIzaa4Bjz6q4xN8EReBiO1B7dEv8kFGCTlT7oVvVpX39+ Fot+OPdM6k9Npadlon8hKgDZHp5zPSJZtnbSwahw2+jzv5wkZBcz2y4yAsfekFG89b5L yl/w== X-Gm-Message-State: AOAM530cBmigjxrTy0eoPpST40iLSmmrzlioUJU+C2PBnQUOWXLniEzB +K8JB6V9BRGCDT5tGH3g1cakRWgvshyj2g== X-Received: by 2002:a17:902:cec3:b029:10d:22fa:183c with SMTP id d3-20020a170902cec3b029010d22fa183cmr1189303plg.53.1622756499291; Thu, 03 Jun 2021 14:41:39 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:39 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 10/29] softfloat: Reduce FloatFmt Date: Thu, 3 Jun 2021 14:41:12 -0700 Message-Id: <20210603214131.629841-11-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::630; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x630.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 29 ++++++++++++----------------- fpu/softfloat-parts.c.inc | 6 +++--- 2 files changed, 15 insertions(+), 20 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index ea7ee13201..741480c568 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_POINT * 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; /* Expand fields based on the size of exponent and fraction */ -#define FLOAT_PARAMS(E, F) \ - .exp_size = E, \ - .exp_bias = ((1 << E) - 1) >> 1, \ - .exp_max = (1 << E) - 1, \ - .frac_size = F, \ - .frac_shift = (-F - 1) & 63, \ - .frac_lsb = 1ull << ((-F - 1) & 63), \ - .frac_lsbm1 = 1ull << ((-F - 2) & 63), \ - .round_mask = (1ull << ((-F - 1) & 63)) - 1, \ - .roundeven_mask = (2ull << ((-F - 1) & 63)) - 1 +#define FLOAT_PARAMS_(E, F) \ + .exp_size = E, \ + .exp_bias = ((1 << E) - 1) >> 1, \ + .exp_max = (1 << E) - 1, \ + .frac_size = F + +#define FLOAT_PARAMS(E, F) \ + FLOAT_PARAMS_(E, F), \ + .frac_shift = (-F - 1) & 63, \ + .round_mask = (1ull << ((-F - 1) & 63)) - 1 static const FloatFmt float16_params = { FLOAT_PARAMS(5, 10) diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index e05909db8c..a026581c33 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -145,10 +145,10 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s, { const int exp_max = fmt->exp_max; const int frac_shift = fmt->frac_shift; - const uint64_t frac_lsb = fmt->frac_lsb; - const uint64_t frac_lsbm1 = fmt->frac_lsbm1; const uint64_t round_mask = fmt->round_mask; - const uint64_t roundeven_mask = fmt->roundeven_mask; + const uint64_t frac_lsb = round_mask + 1; + const uint64_t frac_lsbm1 = round_mask ^ (round_mask >> 1); + const uint64_t roundeven_mask = round_mask | frac_lsb; uint64_t inc; bool overflow_norm = false; int exp, flags = 0; From patchwork Thu Jun 3 21:41:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453323 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp630356jao; Thu, 3 Jun 2021 14:50:01 -0700 (PDT) X-Google-Smtp-Source: ABdhPJydmxryi4Ogi3z/fKh4uS2xTuB9kjaGeK2D4r7O1/sms4a0ozWIOSL8kcvj+/BZ8QmShpf7 X-Received: by 2002:a05:6638:2190:: with SMTP id s16mr973400jaj.133.1622757001481; Thu, 03 Jun 2021 14:50:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757001; cv=none; d=google.com; s=arc-20160816; b=rBQelsVr4YBmT/ccRMH74zemJuMeI5zAsPssBl2aP5qkTLurB83CBrgNWktqR76bDz 5hIKSBGTXym/ZdZBm2xngVg+RBVgkjJ1m0djnj/yKStIY4LaTHyx0q9t/PSTEvnSnUP9 vQPcSo0aj2xoVP0dh8cyalNEQyG78z4WhI7hXbvG5rCrcGqyRXAPy7ZndiTb1tVY54Jt P7PmbEBr+AuqhKX4POP5igzpbZcU1TeV2vNLFrVEGs/4K64XwBfr94GRo/QVt27pos2/ TWPqedxatw/823I4OIiIaVTbTXXvMdy23UfUY43YFDEL4X5oCR3H9QKxpgeB9r+D7EqX aUsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=N/g7nU1jXwHYS7i47w36mxpzZE/kQjQsIkKUyVBW8ZU=; b=rJ0Mzdg33QkDhgNkKIfsFIT1K/YZ/pGQglnxFyh+q++VQHlF6kfYEXosB3KN4pgKmQ l1FcWk3jlPM+yK/BSibp6TWcvu4Np1rMU/VdN3bujHKjMPicrg3hCBdGjJ9zEWtAGlEN t/i6Obcc7OYw95Q2ho2olKg3eQlHzcipwmhmLOY7Q3aZ/PSTr1PhGNMcCLOWmWoMcdR+ YutY7OUTl+KrHCxqrJgR0+qBUFP14EU8HSngL7l6teLougwqCr3Jd3XJBr5b6AR/Pmyk iA8BHaxp+xNkTG9M1ivfwZeIgVQf1mGfJGfLVT821J6lF6/ko6CD7DsXC4LWdkenzGV1 BY0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=azS349mx; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id v4si960213jan.104.2021.06.03.14.50.01 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:50:01 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=azS349mx; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:51414 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovE0-0008Fa-Lh for patch@linaro.org; Thu, 03 Jun 2021 17:50:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58382) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov62-0002NA-JS for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:47 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]:50904) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5x-00015I-JF for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:46 -0400 Received: by mail-pj1-x102e.google.com with SMTP id i22so4471032pju.0 for ; Thu, 03 Jun 2021 14:41:41 -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=N/g7nU1jXwHYS7i47w36mxpzZE/kQjQsIkKUyVBW8ZU=; b=azS349mxBIsPXBB+njOgoREebbu5/nizgvZYSoxLjt9nQ8ClunTWdLYnvAJ23ylFlL CUO5Xr8aYmWuN1A+RgvDZWotGk9JIZR3mTK6DkR7bB8L/b3E+nKQhwTddzg1xN74Am/O JWUNk9EC48ecE1ZEjC+sbE4UYjR5NwD75ELBdNRR6H0I7ZTREPZz4JriR4VYi9D9z95w vM6zmhAFnDwwvl3gil9WENOUPCshEevR9vj8SnWvEkXVQwMqPPCw0Olg3s/HsBgrpPYm qdNvnfvNJiXyXKnjoGF2TG6c6AUHrCblKjGsezHZelDDWCSTgSD6sRYY+Lgz6FxfNxGT ceQA== 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=N/g7nU1jXwHYS7i47w36mxpzZE/kQjQsIkKUyVBW8ZU=; b=YVPjnGVfyOfoYZO1Bv7NLqYd8/B0Di3gt5A4+Podfe6H9e0fbP+TXibpoFhxVyloYf 752rf4JFeOfqHJaaAUsDdNUkayqwdBdPFWAC77/z19BB4x1B+GwDkXp+a2tzxDVsEsRR O4afFtdn2FNxVekgNQqbM1rB7Fn5Me6NdOhpBkbY6EEtzxBXw/KdkPhqjMcpApXDC5hR GQUoRWWzDbB39S6HsuRLb+sj+5Cp0k+xLCfP/qAg8uPOf8OMxdn0VoHYl5yhZP47jvOJ m8qZv5+A166neE+6OkMad2UIa9b+cMjfcr3JVLwvCb3CVDU+epbkOHj+r4+Re9IdA/Qx DQZQ== X-Gm-Message-State: AOAM530AluHh6UOjeuLVnQc8jQf/aO+XCbQTkc9nC568g1g4SYENWdk5 ZDGx2YsfTMHjwqVM9eTcm5nxT1kCGDUS9g== X-Received: by 2002:a17:90a:4817:: with SMTP id a23mr13703935pjh.192.1622756499982; Thu, 03 Jun 2021 14:41:39 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:39 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 11/29] softfloat: Introduce Floatx80RoundPrec Date: Thu, 3 Jun 2021 14:41:13 -0700 Message-Id: <20210603214131.629841-12-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Use an enumeration instead of raw 32/64/80 values. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- 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(-) -- 2.25.1 diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.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, float_status *status) status->float_exception_flags = val; } -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 = val; @@ -120,7 +120,8 @@ static inline int get_float_exception_flags(float_status *status) return status->float_exception_flags; } -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 3b757c3d6a..5bcbd041f7 100644 --- a/include/fpu/softfloat-types.h +++ b/include/fpu/softfloat-types.h @@ -154,6 +154,14 @@ enum { float_flag_output_denormal = 128 }; +/* + * Rounding precision for floatx80. + */ +typedef enum __attribute__((__packed__)) { + floatx80_precision_x, + floatx80_precision_d, + floatx80_precision_s, +} FloatX80RoundPrec; /* * Floating Point Status. Individual architectures may maintain @@ -165,7 +173,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 ed32040aa9..ec7dca0960 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. *----------------------------------------------------------------------------*/ -floatx80 roundAndPackFloatx80(int8_t roundingPrecision, bool zSign, +floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status); @@ -1165,7 +1165,7 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecision, bool zSign, | normalized. *----------------------------------------------------------------------------*/ -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 741480c568..b6a50e5e95 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -4342,10 +4342,10 @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_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 @@ -4353,27 +4353,29 @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr, | Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -floatx80 roundAndPackFloatx80(int8_t roundingPrecision, bool zSign, +floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign, 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; roundingMode = status->float_rounding_mode; roundNearestEven = ( roundingMode == float_round_nearest_even ); - if ( roundingPrecision == 80 ) goto precision80; - if ( roundingPrecision == 64 ) { + switch (roundingPrecision) { + case floatx80_precision_x: + goto precision80; + case floatx80_precision_d: roundIncrement = UINT64_C(0x0000000000000400); roundMask = UINT64_C(0x00000000000007FF); - } - else if ( roundingPrecision == 32 ) { + break; + case floatx80_precision_s: roundIncrement = UINT64_C(0x0000008000000000); roundMask = UINT64_C(0x000000FFFFFFFFFF); - } - else { - goto precision80; + break; + default: + g_assert_not_reached(); } zSig0 |= ( zSig1 != 0 ); switch (roundingMode) { @@ -4550,7 +4552,7 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecision, bool zSign, | normalized. *----------------------------------------------------------------------------*/ -floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision, +floatx80 normalizeRoundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status) @@ -6203,7 +6205,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, status); } 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) void SetRoundingPrecision(const unsigned int opcode) { - int rounding_precision; - FPA11 *fpa11 = GET_FPA11(); + FloatX80RoundPrec rounding_precision; + FPA11 *fpa11 = GET_FPA11(); #ifdef MAINTAIN_FPCR - fpa11->fpcr &= ~MASK_ROUNDING_PRECISION; + fpa11->fpcr &= ~MASK_ROUNDING_PRECISION; #endif - switch (opcode & MASK_ROUNDING_PRECISION) - { - case ROUND_SINGLE: - rounding_precision = 32; + switch (opcode & MASK_ROUNDING_PRECISION) { + case ROUND_SINGLE: + rounding_precision = floatx80_precision_s; #ifdef MAINTAIN_FPCR - fpa11->fpcr |= ROUND_SINGLE; + fpa11->fpcr |= ROUND_SINGLE; #endif - break; + break; - case ROUND_DOUBLE: - rounding_precision = 64; + case ROUND_DOUBLE: + rounding_precision = floatx80_precision_d; #ifdef MAINTAIN_FPCR - fpa11->fpcr |= ROUND_DOUBLE; + fpa11->fpcr |= ROUND_DOUBLE; #endif - break; + break; - case ROUND_EXTENDED: - rounding_precision = 80; + case ROUND_EXTENDED: + rounding_precision = floatx80_precision_x; #ifdef MAINTAIN_FPCR - fpa11->fpcr |= ROUND_EXTENDED; + fpa11->fpcr |= ROUND_EXTENDED; #endif - break; + break; - default: rounding_precision = 80; - } - set_floatx80_rounding_precision(rounding_precision, &fpa11->fp_status); + default: + rounding_precision = floatx80_precision_x; + break; + } + set_floatx80_rounding_precision(rounding_precision, &fpa11->fp_status); } /* 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) void update_fp_status(CPUX86State *env) { - int rnd_type; + FloatRoundMode rnd_mode; + FloatX80RoundPrec rnd_prec; /* set rounding mode */ switch (env->fpuc & FPU_RC_MASK) { default: case FPU_RC_NEAR: - rnd_type = float_round_nearest_even; + rnd_mode = float_round_nearest_even; break; case FPU_RC_DOWN: - rnd_type = float_round_down; + rnd_mode = float_round_down; break; case FPU_RC_UP: - rnd_type = float_round_up; + rnd_mode = float_round_up; break; case FPU_RC_CHOP: - rnd_type = float_round_to_zero; + rnd_mode = 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 = 32; + rnd_prec = floatx80_precision_s; break; case 2: - rnd_type = 64; + rnd_prec = floatx80_precision_d; break; case 3: default: - rnd_type = 80; + rnd_prec = floatx80_precision_x; break; } - set_floatx80_rounding_precision(rnd_type, &env->fp_status); + set_floatx80_rounding_precision(rnd_prec, &env->fp_status); } void helper_fldcw(CPUX86State *env, uint32_t val) @@ -1074,7 +1076,8 @@ void helper_f2xm1(CPUX86State *env) &sig2); /* This result is inexact. */ sig1 |= 1; - ST0 = normalizeRoundAndPackFloatx80(80, sign, exp, sig0, sig1, + ST0 = 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 = env->fp_status.float_rounding_mode; - signed char save_prec = env->fp_status.floatx80_rounding_precision; + FloatX80RoundPrec save_prec = + env->fp_status.floatx80_rounding_precision; env->fp_status.float_rounding_mode = float_round_nearest_even; - env->fp_status.floatx80_rounding_precision = 80; + env->fp_status.floatx80_rounding_precision = floatx80_precision_x; /* Find the nearest multiple of 1/32 to the argument. */ tmp = floatx80_scalbn(ST0, 5, &env->fp_status); @@ -1183,7 +1187,8 @@ void helper_f2xm1(CPUX86State *env) env->fp_status.float_rounding_mode = save_mode; /* This result is inexact. */ asig1 |= 1; - ST0 = normalizeRoundAndPackFloatx80(80, asign, aexp, asig0, asig1, + ST0 = normalizeRoundAndPackFloatx80(floatx80_precision_x, + asign, aexp, asig0, asig1, &env->fp_status); } @@ -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 = env->fp_status.floatx80_rounding_precision; - env->fp_status.floatx80_rounding_precision = 80; + FloatX80RoundPrec save_prec = + env->fp_status.floatx80_rounding_precision; + env->fp_status.floatx80_rounding_precision = floatx80_precision_x; ST1 = floatx80_div(ST1, ST0, &env->fp_status); env->fp_status.floatx80_rounding_precision = save_prec; if (!floatx80_is_zero(ST1) && @@ -1321,7 +1327,8 @@ void helper_fpatan(CPUX86State *env) if (exp == 0) { normalizeFloatx80Subnormal(sig, &exp, &sig); } - ST1 = normalizeRoundAndPackFloatx80(80, sign, exp, sig - 1, + ST1 = 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 = env->fp_status.float_rounding_mode; - signed char save_prec = env->fp_status.floatx80_rounding_precision; + FloatX80RoundPrec save_prec = + env->fp_status.floatx80_rounding_precision; env->fp_status.float_rounding_mode = float_round_nearest_even; - env->fp_status.floatx80_rounding_precision = 80; + env->fp_status.floatx80_rounding_precision = floatx80_precision_x; if (arg0_exp == 0) { normalizeFloatx80Subnormal(arg0_sig, &arg0_exp, &arg0_sig); @@ -1448,7 +1456,8 @@ void helper_fpatan(CPUX86State *env) * Split x as x = t + y, where t = n/8 is the nearest * multiple of 1/8 to x. */ - x8 = normalizeRoundAndPackFloatx80(80, false, xexp + 3, xsig0, + x8 = normalizeRoundAndPackFloatx80(floatx80_precision_x, + false, xexp + 3, xsig0, xsig1, &env->fp_status); n = floatx80_to_int32(x8, &env->fp_status); if (n == 0) { @@ -1569,7 +1578,7 @@ void helper_fpatan(CPUX86State *env) /* Compute z^2. */ mul128To256(zsig0, zsig1, zsig0, zsig1, &z2sig0, &z2sig1, &z2sig2, &z2sig3); - z2 = normalizeRoundAndPackFloatx80(80, false, + z2 = 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 |= 1; - ST1 = normalizeRoundAndPackFloatx80(80, rsign, rexp, + ST1 = normalizeRoundAndPackFloatx80(floatx80_precision_x, rsign, rexp, rsig0, rsig1, &env->fp_status); } @@ -1890,7 +1899,8 @@ static void helper_fyl2x_common(CPUX86State *env, floatx80 arg, int32_t *exp, */ mul128To256(tsig0, tsig1, tsig0, tsig1, &t2sig0, &t2sig1, &t2sig2, &t2sig3); - t2 = normalizeRoundAndPackFloatx80(80, false, texp + texp - 0x3ffe, + t2 = normalizeRoundAndPackFloatx80(floatx80_precision_x, false, + texp + texp - 0x3ffe, t2sig0, t2sig1, &env->fp_status); /* Compute the lower parts of the polynomial expansion. */ @@ -2004,15 +2014,17 @@ void helper_fyl2xp1(CPUX86State *env) exp += arg1_exp - 0x3ffe; /* This result is inexact. */ sig1 |= 1; - ST1 = normalizeRoundAndPackFloatx80(80, arg0_sign ^ arg1_sign, exp, + ST1 = 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 = env->fp_status.float_rounding_mode; - signed char save_prec = env->fp_status.floatx80_rounding_precision; + FloatX80RoundPrec save_prec = + env->fp_status.floatx80_rounding_precision; env->fp_status.float_rounding_mode = float_round_nearest_even; - env->fp_status.floatx80_rounding_precision = 80; + env->fp_status.floatx80_rounding_precision = floatx80_precision_x; helper_fyl2x_common(env, ST0, &aexp, &asig0, &asig1); /* @@ -2027,7 +2039,8 @@ void helper_fyl2xp1(CPUX86State *env) /* This result is inexact. */ asig1 |= 1; env->fp_status.float_rounding_mode = save_mode; - ST1 = normalizeRoundAndPackFloatx80(80, arg0_sign ^ arg1_sign, aexp, + ST1 = normalizeRoundAndPackFloatx80(floatx80_precision_x, + arg0_sign ^ arg1_sign, aexp, asig0, asig1, &env->fp_status); env->fp_status.floatx80_rounding_precision = save_prec; } @@ -2111,9 +2124,10 @@ void helper_fyl2x(CPUX86State *env) int32_t int_exp; floatx80 arg0_m1; FloatRoundMode save_mode = env->fp_status.float_rounding_mode; - signed char save_prec = env->fp_status.floatx80_rounding_precision; + FloatX80RoundPrec save_prec = + env->fp_status.floatx80_rounding_precision; env->fp_status.float_rounding_mode = float_round_nearest_even; - env->fp_status.floatx80_rounding_precision = 80; + env->fp_status.floatx80_rounding_precision = floatx80_precision_x; if (arg0_exp == 0) { normalizeFloatx80Subnormal(arg0_sig, &arg0_exp, &arg0_sig); @@ -2170,7 +2184,8 @@ void helper_fyl2x(CPUX86State *env) /* This result is inexact. */ asig1 |= 1; env->fp_status.float_rounding_mode = save_mode; - ST1 = normalizeRoundAndPackFloatx80(80, asign ^ arg1_sign, aexp, + ST1 = normalizeRoundAndPackFloatx80(floatx80_precision_x, + asign ^ arg1_sign, aexp, asig0, asig1, &env->fp_status); } @@ -2252,12 +2267,12 @@ void helper_fscale(CPUX86State *env) } } else { int n; - signed char save = env->fp_status.floatx80_rounding_precision; + FloatX80RoundPrec save = env->fp_status.floatx80_rounding_precision; uint8_t save_flags = get_float_exception_flags(&env->fp_status); set_float_exception_flags(0, &env->fp_status); n = 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 = 80; + env->fp_status.floatx80_rounding_precision = floatx80_precision_x; ST0 = floatx80_scalbn(ST0, n, &env->fp_status); env->fp_status.floatx80_rounding_precision = 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 *env) { 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_status); break; case FPCR_PREC_S: /* single */ - set_floatx80_rounding_precision(32, &env->fp_status); + set_floatx80_rounding_precision(floatx80_precision_s, &env->fp_status); break; case FPCR_PREC_D: /* double */ - set_floatx80_rounding_precision(64, &env->fp_status); + set_floatx80_rounding_precision(floatx80_precision_d, &env->fp_status); break; case FPCR_PREC_U: /* undefined */ default: @@ -111,9 +111,9 @@ static void m68k_restore_precision_mode(CPUM68KState *env) 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_status); } else { /* double */ - set_floatx80_rounding_precision(64, &env->fp_status); + set_floatx80_rounding_precision(floatx80_precision_d, &env->fp_status); } } @@ -166,8 +166,8 @@ void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val) #define PREC_BEGIN(prec) \ do { \ - int old; \ - old = get_floatx80_rounding_precision(&env->fp_status); \ + FloatX80RoundPrec old = \ + get_floatx80_rounding_precision(&env->fp_status); \ set_floatx80_rounding_precision(prec, &env->fp_status) \ #define PREC_END() \ @@ -176,14 +176,14 @@ void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val) void HELPER(fsround)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d = floatx80_round(val->d, &env->fp_status); PREC_END(); } void HELPER(fdround)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d = floatx80_round(val->d, &env->fp_status); PREC_END(); } @@ -195,14 +195,14 @@ void HELPER(fsqrt)(CPUM68KState *env, FPReg *res, FPReg *val) void HELPER(fssqrt)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d = floatx80_sqrt(val->d, &env->fp_status); PREC_END(); } void HELPER(fdsqrt)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d = floatx80_sqrt(val->d, &env->fp_status); PREC_END(); } @@ -214,14 +214,14 @@ void HELPER(fabs)(CPUM68KState *env, FPReg *res, FPReg *val) void HELPER(fsabs)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d = floatx80_round(floatx80_abs(val->d), &env->fp_status); PREC_END(); } void HELPER(fdabs)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d = floatx80_round(floatx80_abs(val->d), &env->fp_status); PREC_END(); } @@ -233,14 +233,14 @@ void HELPER(fneg)(CPUM68KState *env, FPReg *res, FPReg *val) void HELPER(fsneg)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d = floatx80_round(floatx80_chs(val->d), &env->fp_status); PREC_END(); } void HELPER(fdneg)(CPUM68KState *env, FPReg *res, FPReg *val) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d = floatx80_round(floatx80_chs(val->d), &env->fp_status); PREC_END(); } @@ -252,14 +252,14 @@ void HELPER(fadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) void HELPER(fsadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d = floatx80_add(val0->d, val1->d, &env->fp_status); PREC_END(); } void HELPER(fdadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d = floatx80_add(val0->d, val1->d, &env->fp_status); PREC_END(); } @@ -271,14 +271,14 @@ void HELPER(fsub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) void HELPER(fssub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d = floatx80_sub(val1->d, val0->d, &env->fp_status); PREC_END(); } void HELPER(fdsub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d = floatx80_sub(val1->d, val0->d, &env->fp_status); PREC_END(); } @@ -290,14 +290,14 @@ void HELPER(fmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) void HELPER(fsmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d = floatx80_mul(val0->d, val1->d, &env->fp_status); PREC_END(); } void HELPER(fdmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d = floatx80_mul(val0->d, val1->d, &env->fp_status); PREC_END(); } @@ -307,7 +307,7 @@ void HELPER(fsglmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) FloatRoundMode rounding_mode = get_float_rounding_mode(&env->fp_status); floatx80 a, b; - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); set_float_rounding_mode(float_round_to_zero, &env->fp_status); a = floatx80_round(val0->d, &env->fp_status); b = floatx80_round(val1->d, &env->fp_status); @@ -323,14 +323,14 @@ void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) void HELPER(fsdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); res->d = floatx80_div(val1->d, val0->d, &env->fp_status); PREC_END(); } void HELPER(fddiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) { - PREC_BEGIN(64); + PREC_BEGIN(floatx80_precision_d); res->d = floatx80_div(val1->d, val0->d, &env->fp_status); PREC_END(); } @@ -340,7 +340,7 @@ void HELPER(fsgldiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1) FloatRoundMode rounding_mode = get_float_rounding_mode(&env->fp_status); floatx80 a, b; - PREC_BEGIN(32); + PREC_BEGIN(floatx80_precision_s); set_float_rounding_mode(float_round_to_zero, &env->fp_status); a = floatx80_round(val1->d, &env->fp_status); b = 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 *status) int32_t aExp; uint64_t aSig, fSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; 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 *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; compact = floatx80_make_compact(aExp, aSig); @@ -426,7 +427,8 @@ floatx80 floatx80_logn(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig, fSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; 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 = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; compact = floatx80_make_compact(aExp, aSig); @@ -594,7 +596,8 @@ floatx80 floatx80_log10(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; floatx80 fp0, fp1; @@ -626,7 +629,7 @@ floatx80 floatx80_log10(floatx80 a, float_status *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; fp0 = floatx80_logn(a, status); fp1 = 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; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; floatx80 fp0, fp1; @@ -686,7 +690,7 @@ floatx80 floatx80_log2(floatx80 a, float_status *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; if (aSig == one_sig) { /* X is 2^k */ status->float_rounding_mode = user_rnd_mode; @@ -718,7 +722,8 @@ floatx80 floatx80_etox(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; 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 = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; adjflag = 0; @@ -902,7 +907,8 @@ floatx80 floatx80_twotox(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; 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 *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; fp0 = a; @@ -1052,7 +1058,8 @@ floatx80 floatx80_tentox(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; 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 *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; fp0 = a; @@ -1207,7 +1214,8 @@ floatx80 floatx80_tan(floatx80 a, float_status *status) int32_t aExp, xExp; uint64_t aSig, xSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; 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 *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; compact = floatx80_make_compact(aExp, aSig); @@ -1417,7 +1425,8 @@ floatx80 floatx80_sin(floatx80 a, float_status *status) int32_t aExp, xExp; uint64_t aSig, xSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; 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 *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; compact = floatx80_make_compact(aExp, aSig); @@ -1656,7 +1665,8 @@ floatx80 floatx80_cos(floatx80 a, float_status *status) int32_t aExp, xExp; uint64_t aSig, xSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; 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 *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; compact = floatx80_make_compact(aExp, aSig); @@ -1893,7 +1903,8 @@ floatx80 floatx80_atan(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; int32_t compact, tbl_index; floatx80 fp0, fp1, fp2, fp3, xsave; @@ -1920,7 +1931,7 @@ floatx80 floatx80_atan(floatx80 a, float_status *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; if (compact < 0x3FFB8000 || compact > 0x4002FFFF) { /* |X| >= 16 or |X| < 1/16 */ @@ -2090,7 +2101,8 @@ floatx80 floatx80_asin(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; int32_t compact; floatx80 fp0, fp1, fp2, one; @@ -2124,7 +2136,7 @@ floatx80 floatx80_asin(floatx80 a, float_status *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; one = packFloatx80(0, one_exp, one_sig); fp0 = a; @@ -2155,7 +2167,8 @@ floatx80 floatx80_acos(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; int32_t compact; floatx80 fp0, fp1, one; @@ -2193,7 +2206,7 @@ floatx80 floatx80_acos(floatx80 a, float_status *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; one = packFloatx80(0, one_exp, one_sig); fp0 = a; @@ -2224,7 +2237,8 @@ floatx80 floatx80_atanh(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; int32_t compact; floatx80 fp0, fp1, fp2, one; @@ -2257,7 +2271,7 @@ floatx80 floatx80_atanh(floatx80 a, float_status *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; one = packFloatx80(0, one_exp, one_sig); fp2 = packFloatx80(aSign, 0x3FFE, one_sig); /* SIGN(X) * (1/2) */ @@ -2289,7 +2303,8 @@ floatx80 floatx80_etoxm1(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; 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 *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; if (aExp >= 0x3FFD) { /* |X| >= 1/4 */ compact = floatx80_make_compact(aExp, aSig); @@ -2541,7 +2556,8 @@ floatx80 floatx80_tanh(floatx80 a, float_status *status) int32_t aExp, vExp; uint64_t aSig, vSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; int32_t compact; floatx80 fp0, fp1; @@ -2565,7 +2581,7 @@ floatx80 floatx80_tanh(floatx80 a, float_status *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; compact = floatx80_make_compact(aExp, aSig); @@ -2656,7 +2672,8 @@ floatx80 floatx80_sinh(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; int32_t compact; floatx80 fp0, fp1, fp2; @@ -2681,7 +2698,7 @@ floatx80 floatx80_sinh(floatx80 a, float_status *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; compact = floatx80_make_compact(aExp, aSig); @@ -2744,7 +2761,8 @@ floatx80 floatx80_cosh(floatx80 a, float_status *status) int32_t aExp; uint64_t aSig; - int8_t user_rnd_mode, user_rnd_prec; + FloatRoundMode user_rnd_mode; + FloatX80RoundPrec user_rnd_prec; int32_t compact; floatx80 fp0, fp1; @@ -2767,7 +2785,7 @@ floatx80 floatx80_cosh(floatx80 a, float_status *status) user_rnd_mode = status->float_rounding_mode; user_rnd_prec = status->floatx80_rounding_precision; status->float_rounding_mode = float_round_nearest_even; - status->floatx80_rounding_precision = 80; + status->floatx80_rounding_precision = floatx80_precision_x; compact = floatx80_make_compact(aExp, aSig); 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 = !!(attrs & FUNC_ARG_EXACT); for (k = 0; k < 3; k++) { + FloatX80RoundPrec qsf_prec80 = floatx80_precision_s; int prec80 = 32; int l; if (k == 1) { prec80 = 64; + qsf_prec80 = floatx80_precision_d; } else if (k == 2) { prec80 = 80; + qsf_prec80 = floatx80_precision_x; } verCases_roundingPrecision = 0; slow_extF80_roundingPrecision = prec80; - qsf.floatx80_rounding_precision = prec80; + qsf.floatx80_rounding_precision = qsf_prec80; if (attrs & FUNC_EFF_ROUNDINGPRECISION) { verCases_roundingPrecision = prec80; From patchwork Thu Jun 3 21:41:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453320 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp629220jao; Thu, 3 Jun 2021 14:47:53 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzr5WOtDMocbg/2m3k96is5LCRhof5fBjiqZ8IKv9sX8xPJ+X+02b5WAY2Eqblcjc4roPE+ X-Received: by 2002:ac8:5e51:: with SMTP id i17mr1616496qtx.263.1622756873658; Thu, 03 Jun 2021 14:47:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756873; cv=none; d=google.com; s=arc-20160816; b=mQK+pzL3ZKVS3cbVOGIaoAQRMJviHBJh/3O4RKnPwNjBE0R50LS4SnAPoeSvFY30xp dUzp0IuP2nO13w5wVb7GC0H/2thobIWxhMcX102XTOZL+LU9n+tZRjOJ7Iw/GXs//sHL 4yVrVmC6rOzN9JU+qR2fmAqDwPnNTH8bvNydXK2HSpoCKOESraEAOJGGuhfLtwZBMl7u K+Q57ZUeeXtN8ChUn00jGMRNP+4/K/u3zeSzHWk3NW4vdJWq00CPDPTO8EQVJoSAisxP /d/M/1PkCIu3/cnb665WlNsjWXsF9beyK37GEuAH+/VT4Q+DYTOgxjqC9gTtmznKVFh7 wWdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=j87cuN4oaVGPOQrr81JQNoweh6RR6j9zmHwWvD1f2qc=; b=q4bL3/y5RWXJ22EPWRwnE/wsqOXIJxMwQELCqapXXsepM1ECaDQ7HJCKlc2bTpTzP4 3nOfmUCu1Et/HMbnUW3GyV8G+dzoH/38x6Ib9cjVpH0XouNF/U2sJygYPWA6dRKQdCfg avByvpnJuWEkEK2pv4Yk4OGbgiiOH4cMlD+e6/J19NeNiVQjVYgUTloAYCqPeUXV4dtg s5YSzErN4xU2sjcGMkJSyJ8kooq7cxyrcVPai3tfmB2YgctCdcBIQyA8zi/36uEHvo8v 9mHkEQlbR102Q5ELZtH72dC+H3kvFB9/TWgzEZR+jKoNneurocXbutUbVGrSxLE7M2Md Jhgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=p++rPMhX; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id q7si2931748qtl.262.2021.06.03.14.47.53 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:47:53 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=p++rPMhX; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:42866 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovBx-0002b7-1C for patch@linaro.org; Thu, 03 Jun 2021 17:47:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58368) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov61-0002L8-Pq for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:45 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]:38644) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5y-00015o-0B for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:45 -0400 Received: by mail-pj1-x102a.google.com with SMTP id m13-20020a17090b068db02901656cc93a75so6260034pjz.3 for ; Thu, 03 Jun 2021 14:41:41 -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=j87cuN4oaVGPOQrr81JQNoweh6RR6j9zmHwWvD1f2qc=; b=p++rPMhXyzBlFbk7pzdg7LIjaJw0oMzMDfr+VOHY9KCQo+pI2EP+5cjPY1M78LcIo6 TPP7pSq2L/3dPLXOGL0BJU1/2jEW5uOEo3bG6VzwF/Ru5b213cZOwYgwSzsm/dDqsict 7EdKwClekqJB5s+v8AUPQQZNyXKHZc/mY3g3yAruSuJI7hq8v6vASbwhxOchPEgTb7Id Q4k8XH6t1Sp3tXNoiGP3eDvxxMsBPAlRT9DBTPFnxgCxu1xYneSL4LZO7mp7FqgAp3nV Kww8lUFEsWDzPjuYxetpbYbSdLLYFELQk0HwriI8c+eAAbqkiULiFDex9Km6HnTFpike FNFw== 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=j87cuN4oaVGPOQrr81JQNoweh6RR6j9zmHwWvD1f2qc=; b=jrax/S20T4csW60x3NTmn0oBZP4Z+TLyjIy2JApHVB1Uf9o4vH061RS1Ajx/XSH4+Q oUV8lzqni+105JDhZJwvgDknZEypbKOyti3gIcFS2Fx9e2TZweGX+MJqiZUKjRvkDBkQ S7V5DifHuzkIRGFQax+jqYI5vTIIst0vHhTVG6Vh2I0zsBwIdu+k6uC8/z/Z5AAKgKe5 MphsZL7XKeEnG5XO+5R3ysRWwFYQCjsdIzF5mOijNXgqkuD5hgNhX49qphh11VP4Zi4i 6zxlVFU4KFyQsjFevmM1WPnGDkDjLkKrn4mmzyb2JyuBmfZWE0+97H3AhVLcdiriIQ4R d+0w== X-Gm-Message-State: AOAM533463Xsok7BynInarns27lFGLkNlgmxiGvv/m//0b6op//69dHP bRi8L1pp6TrgG/vG1k5P/AYK6a5hElT5Rw== X-Received: by 2002:a17:90a:1150:: with SMTP id d16mr1346065pje.180.1622756500644; Thu, 03 Jun 2021 14:41:40 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:40 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 12/29] softfloat: Adjust parts_uncanon_normal for floatx80 Date: Thu, 3 Jun 2021 14:41:14 -0700 Message-Id: <20210603214131.629841-13-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" With floatx80_precision_x, the rounding happens across the break between words. Notice this case with frac_lsb = round_mask + 1 -> 0 and check the bits in frac_hi as needed. In addition, since frac_shift == 0, we won't implicitly clear round_mask via the right-shift, so explicitly clear those bits. This fixes rounding for floatx80_precision_[sd]. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat-parts.c.inc | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index a026581c33..efb81bbebe 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -155,7 +155,13 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s, switch (s->float_rounding_mode) { case float_round_nearest_even: - inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0); + if (N > 64 && frac_lsb == 0) { + inc = ((p->frac_hi & 1) || (p->frac_lo & round_mask) != frac_lsbm1 + ? frac_lsbm1 : 0); + } else { + inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 + ? frac_lsbm1 : 0); + } break; case float_round_ties_away: inc = frac_lsbm1; @@ -176,7 +182,11 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s, overflow_norm = true; /* fall through */ case float_round_to_odd_inf: - inc = p->frac_lo & frac_lsb ? 0 : round_mask; + if (N > 64 && frac_lsb == 0) { + inc = p->frac_hi & 1 ? 0 : round_mask; + } else { + inc = 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, float_status *s, p->frac_hi |= DECOMPOSED_IMPLICIT_BIT; exp++; } + p->frac_lo &= ~round_mask; } - frac_shr(p, frac_shift); 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, float_status *s, flags = float_flag_invalid; exp = exp_max; frac_allones(p); + p->frac_lo &= ~round_mask; } } else if (unlikely(exp >= exp_max)) { flags |= float_flag_overflow | float_flag_inexact; if (overflow_norm) { exp = exp_max - 1; frac_allones(p); + p->frac_lo &= ~round_mask; } else { p->cls = float_class_inf; exp = exp_max; frac_clear(p); } } + frac_shr(p, frac_shift); } else if (s->flush_to_zero) { flags |= float_flag_output_denormal; p->cls = float_class_zero; @@ -232,18 +245,29 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s, /* Need to recompute round-to-even/round-to-odd. */ switch (s->float_rounding_mode) { case float_round_nearest_even: - inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 - ? frac_lsbm1 : 0); + if (N > 64 && frac_lsb == 0) { + inc = ((p->frac_hi & 1) || + (p->frac_lo & round_mask) != frac_lsbm1 + ? frac_lsbm1 : 0); + } else { + inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 + ? frac_lsbm1 : 0); + } break; case float_round_to_odd: case float_round_to_odd_inf: - inc = p->frac_lo & frac_lsb ? 0 : round_mask; + if (N > 64 && frac_lsb == 0) { + inc = p->frac_hi & 1 ? 0 : round_mask; + } else { + inc = p->frac_lo & frac_lsb ? 0 : round_mask; + } break; default: break; } flags |= float_flag_inexact; frac_addi(p, p, inc); + p->frac_lo &= ~round_mask; } exp = (p->frac_hi & DECOMPOSED_IMPLICIT_BIT) != 0; From patchwork Thu Jun 3 21:41:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453322 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp630337jao; Thu, 3 Jun 2021 14:49:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwPcNqZUjvCTy0TkZrkXpVWCli5skv0cq61owDQmMzUC8zSpdKrZxA9BYUk6pkOvNQ3O2/0 X-Received: by 2002:a05:6830:192:: with SMTP id q18mr1210011ota.79.1622756998758; Thu, 03 Jun 2021 14:49:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756998; cv=none; d=google.com; s=arc-20160816; b=pWWNGtOLqlkHd6JVYPLbwc1A2/eO0IuI+0GrWQKkGE0W/TOYDXnNk8Cp6wfClhb7tD jGpZjggnn9L9Kay7t5t9AI/bQTVaNZrduyj8Mmjo1ZUSNGsbMPwAtk5MzJeqo+/wIa8G Zlqrlm4COQS8+TmckwYggS6NtsmQPPYb2jPDK1PCc413H91Wy8LwfcQ08qI6bis6mzz+ CK2tIHldRTjX5B0tjaB30aplc2e+T64GLkGSMBSMRljupx3PBxIUuuErRwOr8fnG2EoX C2nwlWDKEINJmLmo/behEPZMSP3QE1eLez9Y/Qwue0nWOIWL9yq/zEuvppeGidvWBgSm QHxQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=v63kiMKs6E/Jl628TTWBVtvYw6v1ob0t2PY/usIP/Gs=; b=tLwY9Z/B1cf6gtrjM+xcQDJl5rQA5wD29QdlsrgqvsFiuZF1ApIJb/yGMIi5xjxIul k6l7RiixHIEifXE/ensRznlJUCfv6WQp2F5Bl2PwPZT0FXqWkDQvNk0YVRnYllSo1yox Oof1ewu27C9HZ+6ZRlMFwDCootwcUtXO0Dk9fza8+X150fs1kiAQyoyhXz69Km715Kta SPZ2RPxhiErdloeRHbemnDcYykKA4IoZoBxdwOQrv3w8EpWgADCHpItBhmqkvJ34Ghrz WAIRiAUF0HH/t4KiGLEHmHadk0G6Zl/w0zSHHzK2RyzEZspJY10c1ReR4phQR81P6YXy m3rg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mnMbrQz2; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id t7si143714otk.242.2021.06.03.14.49.58 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:49:58 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mnMbrQz2; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:51234 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovDy-00088Y-6L for patch@linaro.org; Thu, 03 Jun 2021 17:49:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58328) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov60-0002I4-Cd for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:44 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]:55112) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5y-00016d-H5 for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:44 -0400 Received: by mail-pj1-x102f.google.com with SMTP id g24so4421130pji.4 for ; Thu, 03 Jun 2021 14:41:42 -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=mnMbrQz2S8ISX8o9F8kxHblhgPWF71lExIx3xQ36W2tjozJqByN8XSCa9QCbhtVgnd 9k4tj1xmPraCKqNOoN6t2RyU2uO4N+hT+gC1JpA+JP0OyeTTpmDX3r/VhFlMp6KaDKiK t5DfOrus3HZ8tHUtzLcbLLWQ9vno+ooz1xDkf/shPvneglxyxgkM2nyEtvwBffJaNtNn SSphmmMdazqRcCtnY1RV1+nuCbqniby2wEgPYi9W66acXvHIdvK9qLOF35q/W3ARShit QSoMIGwhlwu5tG3mSbfYKKUn4QoVZq63rHXaoDYIV5at0jYmg0b6V8k3j0c/62/5r/OU uj4Q== 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=QABSbAAcL3Y/wMOD4LeHgSX54TwwGMdCSUuOO0yOLKfMNusyz2El+9tLAo2oznAuS3 vopQYWuZbXyCAf7ugke0+27J1N5SdfKcchZpvqW7JDtq7OV9e7NSDUnXn7Tn5ac5DqCq O0zFk7RifXWQbKlLQL8kBAZaD4D/H0VJPvWsOeLqEr5wUCBpUOfhVCGc9jyl/lrJvW8a jA4AE1cwtCM1wbAXB4xaYwTyTDvfqDlaZRRwjnQUZQXpytbuNAdZ+T+zXJdVbpQYMnnr hyZTeV0y0Da2b+6TuvG/9LEZjqSTukam5eFqsrYjJHj//6YQVB47xOIjLJgJi7W1LEEy u1Ng== X-Gm-Message-State: AOAM530z3OkGoLkiFtrKmXXLC5fl63hPoYF+u8HqrxacgS1y5nxWSCVR KCHdTKLmagRROVSTCD9cW5GgHDqlS7xRCQ== X-Received: by 2002:a17:902:c403:b029:106:7793:3fcc with SMTP id k3-20020a170902c403b029010677933fccmr1060530plk.81.1622756501138; Thu, 03 Jun 2021 14:41:41 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:40 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 13/29] tests/fp/fp-test: Reverse order of floatx80 precision tests Date: Thu, 3 Jun 2021 14:41:15 -0700 Message-Id: <20210603214131.629841-14-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée Signed-off-by: Richard Henderson --- tests/fp/fp-test.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) -- 2.25.1 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 = !!(attrs & FUNC_ARG_EXACT); for (k = 0; k < 3; k++) { - FloatX80RoundPrec qsf_prec80 = floatx80_precision_s; - int prec80 = 32; + FloatX80RoundPrec qsf_prec80 = floatx80_precision_x; + int prec80 = 80; int l; if (k == 1) { prec80 = 64; qsf_prec80 = floatx80_precision_d; } else if (k == 2) { - prec80 = 80; - qsf_prec80 = floatx80_precision_x; + prec80 = 32; + qsf_prec80 = floatx80_precision_s; } verCases_roundingPrecision = 0; From patchwork Thu Jun 3 21:41:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453326 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp631362jao; Thu, 3 Jun 2021 14:51:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyOilfPoSzsSeU3GxjvU1DbfCrmWl9mSb6rH2dtbeR40/SZBGoHIuKuPdg23tpbKTNA+bBf X-Received: by 2002:a54:460a:: with SMTP id p10mr8803379oip.47.1622757108624; Thu, 03 Jun 2021 14:51:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757108; cv=none; d=google.com; s=arc-20160816; b=Iql5eU64OHNGIlN7z5VnSDEu8kAAjYWtws8NZgYllKQHX7OvxqrHt7awzCWkgYkcK0 lnVmegxax99Svj8MbYVMJUeKzy44yTPCPreVuCpnHRDdUkRX96wLFZivIvkBNtYIsQ7+ b8nphW90hPCZA12NiFJ1NqU8CKu22lZWMtuCoeezUOkksScKvgpjr9GR+vXYy3il/SEj 2OLWCrvGv3IBB8AGawVzHZEokL9+a7kT6yKPUN6I9R8bRCWnPJpsTZ26QyqTIaGY6xzq T5ykVOusOuyWl4+geYfRnh4ZMa7fDRN998RVs/egpFLRZ+Pj/IxxDwWToJFSi72kVbyw FG6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=zdB+URSmwAXojvo8XHizqXqw1GaDXnIRRudI5sdslWY=; b=v3c1+Srvl3GAdHgPJmLTp+cpZxV+Z65Iw81yBKNvMd45hvpxcnZ09U+r4FsAq/U34c 8fZNHxnpPpT2ci6GAgZn9ghUqdijLfX7xWB23r+fpPLteJnqKJC6lBD2vcuu4OiSO6TZ OT01lbtzd/6hqusc9P5cnJwyxkovgnWA2M0eyatdNQy9qXQjPHUIQKJfiYv8BnLRr+Pw ORXDix9CS6O+XZzWEwey/wn5gRG8x2VlqPY4JMrj58cOv6lO/ts6TBNKkLYDvJU6/97j T0PABLyan6naYDfLjF1hCMBl3pc/tZogeKfGFPWzol1oRtcITtJWyAXWnJTfAQvYccV2 cq2A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=yVLdHeCc; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id n23si101154oor.21.2021.06.03.14.51.48 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:51:48 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=yVLdHeCc; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:59524 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovFj-0005JU-US for patch@linaro.org; Thu, 03 Jun 2021 17:51:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58428) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov66-0002WO-SV for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:51 -0400 Received: from mail-pg1-x532.google.com ([2607:f8b0:4864:20::532]:43758) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5z-00017B-Gs for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:50 -0400 Received: by mail-pg1-x532.google.com with SMTP id e22so6157069pgv.10 for ; Thu, 03 Jun 2021 14:41:42 -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=zdB+URSmwAXojvo8XHizqXqw1GaDXnIRRudI5sdslWY=; b=yVLdHeCcT8I8Irb3DMBW427lsq1qyJAmm8vG6/tlOfTauhKQCMvxYMKiVLTmFquCan wPrs74hGl8bM8RAeSVFEyBRnzHZN3o1CxW3oxNEDtqGNC0PW51CGmEu5ZBuyDLpzu/9V ieskC84K61XLDIw/HXGe7pbtCto9Ots8G/51N1daX4H0CcqFpag/Cwe9cgUXpc5w9svi fCkdUw6fZTj2yBBMX2He5bbKr3Raz8UpRnpHxf1nynnZs9fIm/Zmnl0tInLRBKfZcQrN 7JXROHPCiwDilKT56ZZ0eOmftnLsi33I6L8zH7+cKbhoWuLN6i20PfP2ZjDMwn/7JYQ/ UBdA== 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=zdB+URSmwAXojvo8XHizqXqw1GaDXnIRRudI5sdslWY=; b=A12w28GVy8QQ6+0yUGnaSkuaRqq2UOeRA9IY2+Z1R/EfEWCCdYrfO5ampa7NIH3CZp /tpB/DtnWv600JnoNug4q8aSCzMwqp7g3LrAQy9nFGaFNJb+8T7nkRLUlY8/GPBtmPYj /aQjnTyQozLdiAyXe9scawUk7bG5Aw/4nQfq/UlEQdORMguCwBbM33u5Wf62h7EzlfeR X9PUVefgKJi/Ne6zjF8rYiOAJ3BVr95acD6pa/z9iSHZas8hY1gqpF3ufjau2Y2gJ+7w EqxFat+rKhn91V8BdsR5xfF2Vi1Tw3ADplxw+/3NU+nPclzyFb3udEyro0vB5SSKL3Dl Z4kQ== X-Gm-Message-State: AOAM531QFO3v0cShxmoAK7WpkhvKvjEZpDnXBDIZkBrYEtCw2nj5PnWp VuMtWozl54G/sCqWeKidnRdfrvfwjtRK8A== X-Received: by 2002:a63:5b66:: with SMTP id l38mr1467292pgm.241.1622756501976; Thu, 03 Jun 2021 14:41:41 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:41 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 14/29] softfloat: Convert floatx80_add/sub to FloatParts Date: Thu, 3 Jun 2021 14:41:16 -0700 Message-Id: <20210603214131.629841-15-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Since this is the first such, this includes all of the packing and unpacking routines as well. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 339 +++++++++++++++++++----------------------------- 1 file changed, 136 insertions(+), 203 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index b6a50e5e95..737f5d7701 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -578,14 +578,14 @@ typedef struct { } FloatFmt; /* Expand fields based on the size of exponent and fraction */ -#define FLOAT_PARAMS_(E, F) \ +#define FLOAT_PARAMS_(E) \ .exp_size = E, \ .exp_bias = ((1 << E) - 1) >> 1, \ - .exp_max = (1 << E) - 1, \ - .frac_size = F + .exp_max = (1 << E) - 1 #define FLOAT_PARAMS(E, F) \ - FLOAT_PARAMS_(E, F), \ + FLOAT_PARAMS_(E), \ + .frac_size = F, \ .frac_shift = (-F - 1) & 63, \ .round_mask = (1ull << ((-F - 1) & 63)) - 1 @@ -614,6 +614,18 @@ static const FloatFmt float128_params = { FLOAT_PARAMS(15, 112) }; +#define FLOATX80_PARAMS(R) \ + FLOAT_PARAMS_(15), \ + .frac_size = R == 64 ? 63 : R, \ + .frac_shift = 0, \ + .round_mask = R == 64 ? -1 : (1ull << ((-R - 1) & 63)) - 1 + +static const FloatFmt floatx80_params[3] = { + [floatx80_precision_s] = { FLOATX80_PARAMS(23) }, + [floatx80_precision_d] = { FLOATX80_PARAMS(52) }, + [floatx80_precision_x] = { FLOATX80_PARAMS(64) }, +}; + /* Unpack a float to parts, but do not canonicalize. */ static void unpack_raw64(FloatParts64 *r, const FloatFmt *fmt, uint64_t raw) { @@ -648,6 +660,16 @@ static inline void float64_unpack_raw(FloatParts64 *p, float64 f) unpack_raw64(p, &float64_params, f); } +static void floatx80_unpack_raw(FloatParts128 *p, floatx80 f) +{ + *p = (FloatParts128) { + .cls = float_class_unclassified, + .sign = extract32(f.high, 15, 1), + .exp = extract32(f.high, 0, 15), + .frac_hi = f.low + }; +} + static void float128_unpack_raw(FloatParts128 *p, float128 f) { const int f_size = float128_params.frac_size - 64; @@ -1536,6 +1558,92 @@ static float128 float128_round_pack_canonical(FloatParts128 *p, return float128_pack_raw(p); } +/* 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 != 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 &= MAKE_64BIT_MASK(0, 63); + p->cls = (p->frac_hi == 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 = &floatx80_params[s->floatx80_rounding_precision]; + uint64_t frac; + int exp; + + switch (p->cls) { + case float_class_normal: + if (s->floatx80_rounding_precision == floatx80_precision_x) { + parts_uncanon_normal(p, s, fmt); + frac = p->frac_hi; + exp = p->exp; + } else { + FloatParts64 p64; + + p64.sign = p->sign; + p64.exp = p->exp; + frac_truncjam(&p64, p); + parts_uncanon_normal(&p64, s, fmt); + frac = p64.frac; + exp = p64.exp; + } + if (exp != 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 = floatx80_infinity_low; + exp = fmt->exp_max; + break; + + case float_class_zero: + frac = 0; + exp = 0; + break; + + case float_class_snan: + case float_class_qnan: + /* NaNs have the integer bit set. */ + frac = p->frac_hi | (1ull << 63); + exp = 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); } +static floatx80 QEMU_FLATTEN +floatx80_addsub(floatx80 a, floatx80 b, float_status *status, bool subtract) +{ + FloatParts128 pa, pb, *pr; + + if (!floatx80_unpack_canonical(&pa, a, status) || + !floatx80_unpack_canonical(&pb, b, status)) { + return floatx80_default_nan(status); + } + + pr = 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 */ @@ -5731,205 +5863,6 @@ floatx80 floatx80_round_to_int(floatx80 a, float_status *status) } -/*---------------------------------------------------------------------------- -| 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 NaN. -| 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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) { - if ( aExp == 0x7FFF ) { - if ((uint64_t)(aSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) --expDiff; - shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return packFloatx80(zSign, - floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp == 0 ) ++expDiff; - shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); - zExp = bExp; - } - else { - if ( aExp == 0x7FFF ) { - if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) { - return propagateFloatx80NaN(a, b, status); - } - return a; - } - zSig1 = 0; - zSig0 = aSig + bSig; - if ( aExp == 0 ) { - if ((aSig | bSig) & UINT64_C(0x8000000000000000) && zSig0 < aSig) { - /* At least one of the values is a pseudo-denormal, - * and there is a carry out of the result. */ - zExp = 1; - goto shiftRight1; - } - if (zSig0 == 0) { - return packFloatx80(zSign, 0, 0); - } - normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 ); - goto roundAndPack; - } - zExp = aExp; - goto shiftRight1; - } - zSig0 = aSig + bSig; - if ( (int64_t) zSig0 < 0 ) goto roundAndPack; - shiftRight1: - shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); - zSig0 |= 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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 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 == 0 ) { - aExp = 1; - bExp = 1; - } - zSig1 = 0; - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloatx80(status->float_rounding_mode == float_round_down, 0, 0); - bExpBigger: - if ( bExp == 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return packFloatx80(zSign ^ 1, floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp == 0 ) ++expDiff; - shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); - bBigger: - sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 ); - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FFF ) { - if ((uint64_t)(aSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) --expDiff; - shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); - aBigger: - sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 ); - zExp = aExp; - normalizeRoundAndPack: - return normalizeRoundAndPackFloatx80(status->floatx80_rounding_precision, - 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 = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign == 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 = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign == 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 From patchwork Thu Jun 3 21:41:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453331 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp632866jao; Thu, 3 Jun 2021 14:54:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyw1lic0brjHPL+xxan7vF7lMl1gtQh0bAYeBV5s9RE6pDc5+JhT44Z1Z0JaV5MIg+Kzh7O X-Received: by 2002:a05:6214:18ce:: with SMTP id cy14mr1508800qvb.8.1622757269865; Thu, 03 Jun 2021 14:54:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757269; cv=none; d=google.com; s=arc-20160816; b=Y9hxI9U0i01cHeWVEaCjoU9bO1FUygcVI+5cUYKVTrnsu6mHfq0iuLrS9tCYrYRFqQ 8NXK5IKeKuwPI6VvVDMErhGLPrpV2dP6eDYnghavzNeJ4cTowy5PosY2kCtdxmutLDKV EVspDu0xnSLO2Q3ZTHviHWR87tlgdzZN+CgQt1A670ufOh0Qwg8ZCtG5uNhJ5G3FWCR3 egsC7PiutpvQXQQEObHBuUKkOaV1+DVIT3EIXcW9dP+dkVW5QGXRjnejZsN7DDNulfjm At6AJ3/esRfzZX19axgmOtu7ltmDZaB2mzNuwq1MDtd59B+m8pOU8u5+5ElhRgWDwWIO U+WQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=q8lAbNppcyHGJO57X+8D3vs8Lmd+nrqoL0h5uKHL3jg=; b=ilfmh440Cy9JoVSalobDgpuT3emkydMtAvXHXT38kL9ycAyDUR65n1CFWOB7D3Uz5Y ONljXHooGf414lRq4cHZCtvHD/JOX8GS0L8t40EdLu/axwUihSIH9wSYzV3wa8aUmlAa 7QzuLjeHqMrzkycskKSw7UjfZomHgOzv8pT+6G+JA/bMtyObopCL4DC1piWT0xtCqQ1G SuIl+d8sRjINlp18eRVbUz7MwosALDJWgOe3N9aQqnhI4YBWWRM9HdoQk1sL+agNcCkL pbbKNYAATLdKVc9TjV6htJYYSymzmVzLL/VmAipVmENuQPH2t+ndYi9dW3gYzaZNBvwD PjHw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=f0h9kkYQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 6si2409669qtz.185.2021.06.03.14.54.29 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:54:29 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=f0h9kkYQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:43608 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovIL-00052T-7i for patch@linaro.org; Thu, 03 Jun 2021 17:54:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58498) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6C-0002hg-TI for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:56 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]:42719) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov5z-00017q-Pb for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:56 -0400 Received: by mail-pj1-x102f.google.com with SMTP id l23-20020a17090a0717b029016ae774f973so4044548pjl.1 for ; Thu, 03 Jun 2021 14:41:43 -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=q8lAbNppcyHGJO57X+8D3vs8Lmd+nrqoL0h5uKHL3jg=; b=f0h9kkYQtht//enboMld31rdes5z4fiTZoCk/iov1xAG5M6QK7hNQUnjZ1+jWTRAbG 5ocuDuvsM+te9U/A6WhCR0UShI0szqcX1AfOk9c/R55Gx5SQoBSP7TG78SSsv3zrJ/Db Oxeq5iGgRTa0vboZoUfcbdZJk83zXBlreINrsWl5BhDzd/ao52UtgSlvCkMM5kqsznwh EkTfvhcL/SfhHyX76HaxZhYtDGRumkfB6paahONnfa859OY2fPeo4FC+YOwgry1Ygt2X /4V3sggAmmQbOumJHaSpsG8ODYMzNF8erjQBdvzBtX7VIcLcOuTmZJnveUYjGS+XT84P oGjQ== 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=q8lAbNppcyHGJO57X+8D3vs8Lmd+nrqoL0h5uKHL3jg=; b=m9UbV+U6l2XzRjQRyJ3Y9E9tj6fNT6jW9jOZuVJF730Fp1Hw6pJ8/nC4vQBqSt4S+V sSfOxZW/8KqSM5q6HI/3N+9n6FpYl86LtI4iGhcYS8MOqlibfM0bTCIGjqKiR3HHgwH8 2joyd2ZNvcJkqjst5qDiDTQvy+GWvYkWoxg8YgK0gpwi2s/LACYMdKIgEVY8zI+92TfA LRAI31/Bf1Ih5mYanYJbkRxj9eQT1xFhEP9K8YSkwo+/2Qp8tlrlrsIm6a+yzYeuXwLU 495IMgeJGgNNnYn8t8ir3OrW+/7SqzFLNNMcpvGbnfqhBrgrHOSlQ858y2xuQKQfa+6k DB/Q== X-Gm-Message-State: AOAM531KwIPLcyIvjcWEHxr+jA38+JaUuMKeBLbIXzHwJQsP132jzXRH mVcvQXz8n9tRwIbaTnPvpK2qtesfsw7y6g== X-Received: by 2002:a17:902:ee8c:b029:fe:dc5f:564 with SMTP id a12-20020a170902ee8cb02900fedc5f0564mr1176093pld.71.1622756502496; Thu, 03 Jun 2021 14:41:42 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:42 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 15/29] softfloat: Convert floatx80_mul to FloatParts Date: Thu, 3 Jun 2021 14:41:17 -0700 Message-Id: <20210603214131.629841-16-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 76 +++++++++---------------------------------------- 1 file changed, 14 insertions(+), 62 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 737f5d7701..ae2e7aa274 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1944,6 +1944,20 @@ float128_mul(float128 a, float128 b, float_status *status) return float128_round_pack_canonical(pr, status); } +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 = parts_mul(&pa, &pb, status); + return floatx80_round_pack_canonical(pr, status); +} + /* * Fused multiply-add */ @@ -5863,68 +5877,6 @@ floatx80 floatx80_round_to_int(floatx80 a, float_status *status) } -/*---------------------------------------------------------------------------- -| 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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - bSign = extractFloatx80Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( (uint64_t) ( aSig<<1 ) - || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) { - return propagateFloatx80NaN(a, b, status); - } - if ( ( bExp | bSig ) == 0 ) goto invalid; - return packFloatx80(zSign, floatx80_infinity_high, - floatx80_infinity_low); - } - if ( bExp == 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - if ( ( aExp | aSig ) == 0 ) { - invalid: - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - return packFloatx80(zSign, floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - zExp = 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-point | value `a' by the corresponding value `b'. The operation is performed From patchwork Thu Jun 3 21:41:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453328 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp631947jao; Thu, 3 Jun 2021 14:52:47 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwLHEd9M8npwtqS/6FRTOeMkgw5cFBu1gBd+SQvOEifruEx2MvXL2srwD0YoeBMpcFPO4yL X-Received: by 2002:a9d:6453:: with SMTP id m19mr1185295otl.63.1622757167023; Thu, 03 Jun 2021 14:52:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757167; cv=none; d=google.com; s=arc-20160816; b=s5qMROO6LdMmlflw7sqSy5Fm94b2x3LBjO6moV691w7FuYACQJvlF2Zx88sjsXoJwN dIFBgylttzlWVBY2tIEDq0/8Pzn2peehBYPu4cAsqLS/23hCBvphq1PxQWUp9vUslACJ 56tWO3aSNwV25MrFE7vi20cB2Lvn0D5NeTwWbsTWjNINQqDJRof/56oeNg+P3Cj0Pmzh uxXQIdZmG2ZqcCuwpghT8UNBwwD1el1temuoy9cY4T9wVGrol+JfdnqhuxMxJOnrJMVi KZD/vLfGj6zRSvXzHCnKBo0nr9RjIUxA6hHqIE2kiphdRlJdUDdig7FhLkMfOt74ixwM ZvCQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=jsR0mGCWglTMXoS6de3IaqXp8GNTb2/ROWC0tZcxiWk=; b=HawtoSxcBPYL7hyMjGKqlYyypuXcT9XCjjq/j7WqwwzLrvlmGYEZvOvpkQN2uDeBBU ehl3zMu1v1ktm1Rt+4jxMcfSpeeklmDvQXzZJxC0eJzBMun4NMjAMT9NCP38hxIrAiMJ hSJ5D6MkyXz6ZuFD5Td69WXHWBBa/rCqvcRyi3iQayDBQYGcFsWnWFffITpBuNjTxvaB FCX8HWavu2kAwrF0JKfl5o4+FfdVPnSTLf8xP9Kuf4i2K59laS0/ub3K81zwzekCu/wk qOJx2bFwAxXt+U4LS3RiYC+Ifs5Acj7oGlITyIGqZb193WPhzHcfEnG7qBpbL2yTP1Z9 gwow== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UrFi3pSv; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 8si140355oix.32.2021.06.03.14.52.46 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:52:47 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UrFi3pSv; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:35110 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovGg-0007pG-EO for patch@linaro.org; Thu, 03 Jun 2021 17:52:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58446) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov67-0002Yf-LP for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:53 -0400 Received: from mail-pf1-x431.google.com ([2607:f8b0:4864:20::431]:41805) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov60-000186-Dy for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:51 -0400 Received: by mail-pf1-x431.google.com with SMTP id x73so5921289pfc.8 for ; Thu, 03 Jun 2021 14:41:43 -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=jsR0mGCWglTMXoS6de3IaqXp8GNTb2/ROWC0tZcxiWk=; b=UrFi3pSveaG22A0ssi1yj502GiL63JDT39ZLaSptjkLbp4evKPZ0ZJv5T72dzO057I x+V9ek6FJJzeSL4kUkB8ESkzEWC7YytzoApfR1NtaGY25BVQNZHpvJBgFoRcoR46AKTs 3tfWYlYEeOpe/zLjI21d3pMVrExaaHfL/w5wp7seeKvZ/zUojMHIMCH/R3JLU0Em4WZx yDezCZsZRl3o4JhUtNM11CPrWy4/LZ4UBuG3kteR4pZaPj5TwqUKTH0gb2/c+/bksVJV IwUOk9Vh5z1i3uDGiOBWFfBlJpmraqRr93E+sp6nv04Ri7wXr08t6LWzIjfRQshECCbj BJAg== 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=jsR0mGCWglTMXoS6de3IaqXp8GNTb2/ROWC0tZcxiWk=; b=FZ88/M4BuhHFuj31xAYne6F1VZ4WEskeJ5RlJ0alpSeXwU8NQpLE9yW1S7afasDaF2 hcq24Z8u+gmhyVcelsLOpp4uSw1EAzUkV1oyccpB4yS94L5i0xrBhSJFuIml8uYvcbjP cCiGpXwXl4y3+Mj8g8RBCD/DTKAqiaZQUn5ByxWe0pLHzKv8KXxDytinqqNof0e5PLWu DZlt4E9N/z4kJafQaig22RDWo2bkKeW0fDXVQqNfkWGBRkeWz3XH6jilljT5emnGbez7 pue9n3JRLhPjusE4DkLr6heVjIQWSzodsOmjE4iAGLWj9zpDbmf8bjVUBszgvl0dd9wM tGHQ== X-Gm-Message-State: AOAM531XzvGTVd6K6Mm8SBWSvcOvqWteISwQcUyLfAV30dSPqBFcFXXK DSqqyyMxbl8dILa9HYiNMxQ4z/3Hd+IOCQ== X-Received: by 2002:a63:bc19:: with SMTP id q25mr1483310pge.211.1622756503107; Thu, 03 Jun 2021 14:41:43 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:42 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 16/29] softfloat: Convert floatx80_div to FloatParts Date: Thu, 3 Jun 2021 14:41:18 -0700 Message-Id: <20210603214131.629841-17-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::431; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x431.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 100 +++++++----------------------------------------- 1 file changed, 13 insertions(+), 87 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index ae2e7aa274..9c26ba5960 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2294,6 +2294,19 @@ float128_div(float128 a, float128 b, float_status *status) return float128_round_pack_canonical(pr, status); } +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 = parts_div(&pa, &pb, status); + return floatx80_round_pack_canonical(pr, status); +} + /* * Float to Float conversions * @@ -5877,93 +5890,6 @@ floatx80 floatx80_round_to_int(floatx80 a, float_status *status) } -/*---------------------------------------------------------------------------- -| Returns the result of dividing the extended double-precision floating-point -| 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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - bSign = extractFloatx80Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ((uint64_t)(aSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - if ( bExp == 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - goto invalid; - } - return packFloatx80(zSign, floatx80_infinity_high, - floatx80_infinity_low); - } - if ( bExp == 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - return packFloatx80( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 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 == 0 ) { - if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x3FFE; - rem1 = 0; - if ( bSig <= aSig ) { - shift128Right( aSig, 0, 1, &aSig, &rem1 ); - ++zExp; - } - zSig0 = 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 = estimateDiv128To64( rem1, 0, bSig ); - if ( (uint64_t) ( zSig1<<1 ) <= 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 |= ( ( rem1 | rem2 ) != 0 ); - } - return roundAndPackFloatx80(status->floatx80_rounding_precision, - zSign, zExp, zSig0, zSig1, status); -} - /*---------------------------------------------------------------------------- | Returns the remainder of the extended double-precision floating-point value | `a' with respect to the corresponding value `b'. The operation is performed From patchwork Thu Jun 3 21:41:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453321 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp629996jao; Thu, 3 Jun 2021 14:49:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyozog1BN2akoljvU+x04XNnBdMjTGujoufQMt4ai4psR+Ay2fm9/zniQXFQFETei/KJP7m X-Received: by 2002:ac8:75d4:: with SMTP id z20mr1567565qtq.265.1622756963070; Thu, 03 Jun 2021 14:49:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756963; cv=none; d=google.com; s=arc-20160816; b=yRfdI1ZOkGLBrm3jYxSzp8ACPyweyK1Vh1aZaW7/0ko3KImeMrtGPRhomQCNDbGdbb umSsZZSeTdf5Y2LeLH5VUb3rbQd8EIQnf3SlrioXdWJQvD1+KxmSx0geZO5SsZ5uhqUe TC+BVHjIhX+8sbrLONDjLR+HnZ0WAvlK9aQOqpdvpg3O9avCPcoZBfT/WPxTAiT2vXu3 /jkVdntcQ2ioi9Iwl2AS/QH/u5jFsf5QwsT/mULk3vVYTh/LyAN7UEbVq2ZeuympU1AH Z1dR1xkmdy72oiNoDz7xGq4t75KAztiva+CiE4gx7MtfrH5t5bIlBUJmkEB+Xw9oT5/d vuYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=JCtl3D+YOh8X1zQYr/wZ8dY/TYd7h1wTuPlU6E6ST7c=; b=BB9Zzv7kZZQUeqFBEubsHRf4FMh4PTvwNxEyOq3jHOybKU2dK6HO4KQgFhyvYBVXBf 6daDG3H2iNGNNZ88XhuGzjQQNlhr2UfBfb3gwP2V90I1FILFhMml04C0d90OlKcIsdE2 Nzux5DdR+HImHb2qi95ZMKDahOcN2d+IXR5zMAwA9hdiDrVORfu/6PYm4buD7/4cY3s6 xB/U0xAHzAE5q01Pm9RFUhyKxfOaSInrFGiKx6nYqTYXu3TUIA6Bd5PHdCygtaSZweFA daL1GwNIPap+5xlXlp1OtOeZMpjbX85u52x2h+ArPQqCZbPBXwPWM2NBAQmNTM2dTIin xATA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LFSWzP1R; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id gu1si2701726qvb.208.2021.06.03.14.49.22 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:49:23 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LFSWzP1R; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:46148 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovDO-0004lF-Ca for patch@linaro.org; Thu, 03 Jun 2021 17:49:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58480) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6B-0002gK-CR for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:56 -0400 Received: from mail-pg1-x52e.google.com ([2607:f8b0:4864:20::52e]:36422) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov61-00018E-Fo for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:55 -0400 Received: by mail-pg1-x52e.google.com with SMTP id 27so6185220pgy.3 for ; Thu, 03 Jun 2021 14:41:44 -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=JCtl3D+YOh8X1zQYr/wZ8dY/TYd7h1wTuPlU6E6ST7c=; b=LFSWzP1RsHR87z55Pf+z5JcHJqYYlIjXi332fm7PJMiVsw6wJ/D+eXlqlF59pW2oJ7 Y/GxX3LWRJxVDBBA4FmZrQtj/1re7e7+Q5YQoBbL26dcBO53n6KrpP3ZQ2oVPH80tYXH IO4TPgLvoGp+eqLSEy7oum66PpspSDrl9JZC6hHAatdXbYssdsaAIMpBsiXBCd1I6xDq q7PTPrqfj5BiDQbKH5p45yzMJO6n5h5CMAuAHZ+jnmT1kNCUAWMh/L3eytlOrNJWeUEJ /CgJJxMMTv1lqGGoLrxJoo4zw8gCAkGIX7oJSjLcEY0A9W+2MgksaaXPXsLRk8hgB0cr grKA== 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=JCtl3D+YOh8X1zQYr/wZ8dY/TYd7h1wTuPlU6E6ST7c=; b=nKmYwzdaXeln4yri7H18kNJdPJ331zTCs6bWiaoGGRuzXn+XFEMXutmKVK5FjVg2KI YQCCxGWGa5LA9Ja96cytj7OPS2tOm4S4RTGv9lkUmUZX3BTdjzOxI2gihWKHkbyqCH4g YwJJGKZgrygJr5LhHMGo1RMryAoq54+MP5E8pC5z7c+iiwrdHHbQ+d7FFDOwLWWPYk6x jNWm/YwlDgEM5n5S0sWZXQnmONgET1hPEN+KCUNjfhD0TMcjS1SFvRZsnMqW+PHYOnSL Inf+jr++1Q+0TZR/KoPw+8O4z+KWfAFT02mcD8+EA951BHd49ALkSSlkzJQ8Qj1f1ld+ I/iA== X-Gm-Message-State: AOAM532Ih98cxKIBC8Em9kHByvQFhOeQlcyYNTGoKeNPG0l1+KAgGWri tUa8x0LN2S6wm1SNCSG9wMLVz1iUR9s1Dw== X-Received: by 2002:a63:fc06:: with SMTP id j6mr1501156pgi.226.1622756503686; Thu, 03 Jun 2021 14:41:43 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:43 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 17/29] softfloat: Convert floatx80_sqrt to FloatParts Date: Thu, 3 Jun 2021 14:41:19 -0700 Message-Id: <20210603214131.629841-18-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52e; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52e.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 82 +++++++------------------------------------------ 1 file changed, 11 insertions(+), 71 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 9c26ba5960..5a320e5302 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3881,6 +3881,17 @@ float128 QEMU_FLATTEN float128_sqrt(float128 a, float_status *status) return float128_round_pack_canonical(&p, status); } +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. *----------------------------------------------------------------------------*/ @@ -6044,77 +6055,6 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status) return floatx80_modrem(a, b, true, "ient, status); } -/*---------------------------------------------------------------------------- -| 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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ((uint64_t)(aSig0 << 1)) { - return propagateFloatx80NaN(a, a, status); - } - if ( ! aSign ) return a; - goto invalid; - } - if ( aSign ) { - if ( ( aExp | aSig0 ) == 0 ) return a; - invalid: - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - if ( aExp == 0 ) { - if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 ); - normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); - } - zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; - zSig0 = estimateSqrt32( aExp, aSig0>>32 ); - shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 ); - zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); - doubleZSig0 = zSig0<<1; - mul64To128( zSig0, zSig0, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (int64_t) rem0 < 0 ) { - --zSig0; - doubleZSig0 -= 2; - add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); - if ( ( zSig1 & UINT64_C(0x3FFFFFFFFFFFFFFF) ) <= 5 ) { - if ( zSig1 == 0 ) zSig1 = 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 |= 1; - term2 |= doubleZSig0; - add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); - } - shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 ); - zSig0 |= 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 From patchwork Thu Jun 3 21:41:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453317 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp628541jao; Thu, 3 Jun 2021 14:46:34 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyI7H88x05+HTwggGUB0gWlcrvEZznr9UFdSnbFh1od3f0AAh/2IxP0b7aP/VERSD9Y1uEO X-Received: by 2002:a05:6808:10cd:: with SMTP id s13mr8929609ois.113.1622756794358; Thu, 03 Jun 2021 14:46:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756794; cv=none; d=google.com; s=arc-20160816; b=RiO3qL7Trp2aMGOkxc6tmrHHALGR+ktoqc5K6y64iygidZRmwVTZpOeXeDsMeruGMx r87FDI+kEPzT+lKPUrun4BvmGgAyB8gy7pI1kOdYnW3Rwgzb3OmlMQXpQ/FOu99r7vid zHSOwMYkiTfFKE6xC5/6JpiF2ycTGq4TxJUDWwSYpYIWXfzo6xqHN+nYiBtR0C2uckc6 DmDjqmHM1gKBoRclB/tQmXrr79yAtHOdZuo3vD2zwVXCEotFQgHxgLKiBU2yduA9B50X IjFgZjNAlheaUkAK2laWULxphVojTNqTA2AZaRfEyXYtC7Yz7fCC0OJPtvImDlmM6BFe D4tQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=xiaeGJWLl6eo+VnxnfAKjpi1RICpcWro/dd/W10uCac=; b=zvTO/J7PsoBZ868nkhSkPVG3oqmdGflSGouFJT7RtTYBFgoRlkEw+T62q1leUuyzVo TioyWRFKXTHG2QcO1btzS6I1xEANkyfPfSvtuFL0LJVcVXetpBhcgUZOHiQ7g7FBZP5A gYWfn3Bw2LMYogaGBI1LD67gSzLCP0E+dbwtmczNFE1I3ocFL/rB+ZsrR55NzaS/j7oR PjPcVUmlmHI5YOUlPeW+orhmc/cOiMkmqcKdk0sXQFXXmKFbnGcJgo32nSl9J34iIwO8 4ywEWI4d/YhBU42tFAaXNttO+B0NxcOusXB9XyWsHjJdpsH2IbXblUGQWNKqCB/EZvRN dQQg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SkOxuTcJ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id k20si141266oic.160.2021.06.03.14.46.34 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:46:34 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SkOxuTcJ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:37576 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovAf-0007Sa-Og for patch@linaro.org; Thu, 03 Jun 2021 17:46:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58438) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov67-0002Xq-Ey for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:51 -0400 Received: from mail-pg1-x533.google.com ([2607:f8b0:4864:20::533]:40745) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov62-00019F-0m for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:51 -0400 Received: by mail-pg1-x533.google.com with SMTP id j12so6159930pgh.7 for ; Thu, 03 Jun 2021 14:41:45 -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=xiaeGJWLl6eo+VnxnfAKjpi1RICpcWro/dd/W10uCac=; b=SkOxuTcJFwIo33ri2Ti2wRBTizyCiXTNfoBj+UmEySa9YiitHYXbtDr6y+YSUNBjja ssEH/DjqRHZl77xBzubgnPGP7e16lTMUmhq/aZY90hM5ZBaaxt+zgVK29I01CcobfLBT QxsMrGpHpUVZs6U8b3e9sT7uWHn1r6hvWMGViFyZwJWejkVnr2Q1roqQ50HUPrza3dDR NpAgTAdY8AQJwlcM8DYSTs/RzYK4EGv0q4xded1qevTeA/lhr7CbinzkRJe3DQqj0ues 6GN6KIf9+tjgVMXI/XGVJu18/ZVEjzq3Knlk//Y2NSStZ2qMUxDT4W7334UtQPWSVpHJ ACYQ== 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=xiaeGJWLl6eo+VnxnfAKjpi1RICpcWro/dd/W10uCac=; b=RvsRhikAu4iFCFM724ovjZxzHllhB8r/r+OlcBS3g2yLFyEYFIOrKSorp4qvOcCJj1 orlNuwwHwFMxBnpTZI4ro5Go6NxiluhTm9vx6rhPdeHv9VCtoxtuJVNK1SGUkxYD3wYg 1pJIbG2QB1ajnJZI7Oa5UsG0e8Ov6Vu+2Jk00ofNi3aNx9sPOLCuzC2JE6RSrrhxzU+M yorbCg/2lj7GuT8bYMWEW6GJ0oJzADx3DsD5t7/pjyeqNQgl8BTnK7lw8tlp9gvuxhz5 6yrnx7fBJI/cQ0x0+2JweGXjZbaqP4Wux3yJOZ/v7ZFnnXlL7z4jY6nkVMH8dyLSqhKv nMWw== X-Gm-Message-State: AOAM533/Zh9IDeu7Wts5gmsHwjl8cBd0oiFQCvkaajOpQHNDXxsUwLnj 4w0Fx790iaZQ86Qk6dWJZEjYPaAapVqWqA== X-Received: by 2002:a63:2dc4:: with SMTP id t187mr1537722pgt.80.1622756504356; Thu, 03 Jun 2021 14:41:44 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:44 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 18/29] softfloat: Convert floatx80_round to FloatParts Date: Thu, 3 Jun 2021 14:41:20 -0700 Message-Id: <20210603214131.629841-19-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::533; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x533.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 5a320e5302..74787d5a6e 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -5792,10 +5792,12 @@ float128 floatx80_to_float128(floatx80 a, float_status *status) 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); } /*---------------------------------------------------------------------------- From patchwork Thu Jun 3 21:41:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453318 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp628861jao; Thu, 3 Jun 2021 14:47:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyN2wY2gAQiXLQkIRge+UzNpjPJEneUeLl9by4+N/tJ1c94bn+rdaxTF+cqd94SY8bHFWQJ X-Received: by 2002:ad4:5943:: with SMTP id eo3mr1649194qvb.40.1622756831694; Thu, 03 Jun 2021 14:47:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622756831; cv=none; d=google.com; s=arc-20160816; b=a4zPLjfBfFKrxLzfkgfZgL0dDr5/BGBVX8yUj7U+EgugPXDVeiZre/hUmEGAnbGoUV qGyqZHlBnxBBiO2vM3TeXfVw6/xgBHnbAp5lhEV74NvvThH3V4lR7QMCQO9R8oRsnpVP /rXlGUx9WZZ+Vn7NgbDQrUamh3UXDOjE6MFUZpqabkGX4oqE2vpEJvDiEz5XngY117Ok wYajdyc/P1MZ92oIF0plRypMzerLa4VLUP8IwD1dFSk+bh5oVGwpeaBMjDZa79z6cNiu LZAHMd2fmW+vxzFPquIwVauoD0t0wYrJwum6xBYZ9H8GQjB2i8mlF+xruFTS0RwTHk/C oJDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=fUuOVml+4w79a3bxuCGZ23LxhkzpodhkprttyZbQk2E=; b=0M53PDyVQG1x+l3Npv7y68sOimTTWFxc+i99Jo3uxeD7v1dFntXN1e7KHjQSyg7a27 mNkXqKQZyqdxb4ktu1I7f9TR/6oF4lrM3I4Ev6dOh2BWaioiDxM8I0w9HTsbMTFaSEyD K2OtPOKP2/Ub3YT4YqQmBfQHKdMMy8Hbn8OWeEHzWfD0UInennDfJ39IBfEsCgjfKJzt zlTtZ142UHMvwJnX93cONoDqHsaOwrBuXm26zROx08t+KvPwnZFMZMUxsxwSqmQE1O6S tz5sI34Z9WjY0Y5z7aGDWSCBY2+UaY4elg9Jx1pHtqXcDxy2vlnEdwmyAdKAh0IT+XnA hHDQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="g63K/xb/"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id s28si319514qkj.102.2021.06.03.14.47.11 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:47:11 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="g63K/xb/"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:40346 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovBH-0000tp-2V for patch@linaro.org; Thu, 03 Jun 2021 17:47:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58478) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6A-0002do-QC for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:54 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]:40900) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov62-00019a-EZ for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:54 -0400 Received: by mail-pj1-x1029.google.com with SMTP id jz2-20020a17090b14c2b0290162cf0b5a35so6234952pjb.5 for ; Thu, 03 Jun 2021 14:41:46 -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=fUuOVml+4w79a3bxuCGZ23LxhkzpodhkprttyZbQk2E=; b=g63K/xb/Dkn1IpwTV0AkxycAjdOnZXPLHj4tw14bzLKwRdbChNJcmCJ/Ti08d8WDxa zxeufoRcAvvkvvZqyOyJoPRuWYIEC11gb9NpNtRfeXp4TkWkwfetsmvG5gT/O3waEML1 dduiIQxZ9K3vQAuzneIJ3tUEJfw9wSjpjkCXqtH8UWoU4Q27polpIFksc7VKMeZ485qz lwXCFqIpj1dZORMu8N8ljZtW2ECU4W/JwIP608Ba/9JBmLn8nKkoMASbh/FKvJDHAOUf ygTlAN9ciH0HeupZnW2mbGSF15WpMfMK829Bm/wBQhH5taTLIvx4qFC9LgLMXGPSW0PH ncgQ== 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=fUuOVml+4w79a3bxuCGZ23LxhkzpodhkprttyZbQk2E=; b=XI/+a+Eu09sThMisDyKQBcBajTLIjq6mYuk7PKh2o8RnIuHIYOK9WdSyhaeKxJ5BlO 7jKR4qIJmILcQmmIssS0jGwKAmmkDzMbEmOUChVKXFGoD6dVEnGdA1ao5NvNKWyzB7zv x7DkA1wPgMP/HPVmq5W9y3zgxCYdSBy+EWROC3wRBOfY2ngwlfpJJi+mkQOzHoew37eA SYVNbNLPguji7nw4CI9JncFCNbG8VSYdumSbSTwTbddr+Txi7hqf+JOVHf/RQFFsfeUd iM6rbJMOpU2IRCgHA6fKwqdahwmGZdqHTYO8A2Ic/ErEBPnJo5JxyHkcdTr3RHmXyVPV pGYg== X-Gm-Message-State: AOAM530LBTxuY7aoHtgjkH12E9tEyUjHLiNmBoTxonYKb2f4ASa1UnhF p+qk305zcwzYPGvYxLBGF5n4hJNDqyeP9Q== X-Received: by 2002:a17:902:bb92:b029:f4:4a28:3ed0 with SMTP id m18-20020a170902bb92b02900f44a283ed0mr1216920pls.48.1622756505134; Thu, 03 Jun 2021 14:41:45 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:44 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 19/29] softfloat: Convert floatx80_round_to_int to FloatParts Date: Thu, 3 Jun 2021 14:41:21 -0700 Message-Id: <20210603214131.629841-20-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1029.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 116 ++++++------------------------------------------ 1 file changed, 13 insertions(+), 103 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 74787d5a6e..9caf1ecf9c 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2610,6 +2610,19 @@ float128 float128_round_to_int(float128 a, float_status *s) return float128_round_pack_canonical(&p, s); } +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_precision]); + return floatx80_round_pack_canonical(&p, status); +} + /* * Floating-point to signed integer conversions */ @@ -5800,109 +5813,6 @@ floatx80 floatx80_round(floatx80 a, float_status *status) return floatx80_round_pack_canonical(&p, status); } -/*---------------------------------------------------------------------------- -| Rounds the extended double-precision floating-point value `a' to an integer, -| 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 = extractFloatx80Exp( a ); - if ( 0x403E <= aExp ) { - if ( ( aExp == 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) { - return propagateFloatx80NaN(a, a, status); - } - return a; - } - if ( aExp < 0x3FFF ) { - if ( ( aExp == 0 ) - && ( (uint64_t) ( extractFloatx80Frac( a ) ) == 0 ) ) { - return a; - } - float_raise(float_flag_inexact, status); - aSign = extractFloatx80Sign( a ); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - if ( ( aExp == 0x3FFE ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) - ) { - return - packFloatx80( aSign, 0x3FFF, UINT64_C(0x8000000000000000)); - } - break; - case float_round_ties_away: - if (aExp == 0x3FFE) { - return packFloatx80(aSign, 0x3FFF, UINT64_C(0x8000000000000000)); - } - 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 = 1; - lastBitMask <<= 0x403E - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - switch (status->float_rounding_mode) { - case float_round_nearest_even: - z.low += lastBitMask>>1; - if ((z.low & roundBitsMask) == 0) { - z.low &= ~lastBitMask; - } - break; - case float_round_ties_away: - z.low += lastBitMask >> 1; - break; - case float_round_to_zero: - break; - case float_round_up: - if (!extractFloatx80Sign(z)) { - z.low += roundBitsMask; - } - break; - case float_round_down: - if (extractFloatx80Sign(z)) { - z.low += roundBitsMask; - } - break; - default: - abort(); - } - z.low &= ~ roundBitsMask; - if ( z.low == 0 ) { - ++z.high; - z.low = UINT64_C(0x8000000000000000); - } - if (z.low != a.low) { - float_raise(float_flag_inexact, status); - } - return z; - -} - /*---------------------------------------------------------------------------- | Returns the remainder of the extended double-precision floating-point value | `a' with respect to the corresponding value `b'. The operation is performed From patchwork Thu Jun 3 21:41:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453335 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp634874jao; Thu, 3 Jun 2021 14:58:01 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyR2h5ENM3wp1p/KZJzUjEEGShMYY5cwDi6D0ghUlOWVQQKyj/ACfMk7Vc3uL7J108/nNHk X-Received: by 2002:a05:620a:2987:: with SMTP id r7mr1288783qkp.461.1622757481005; Thu, 03 Jun 2021 14:58:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757481; cv=none; d=google.com; s=arc-20160816; b=ndShmn37Lli43Oxf24+/QflXZHC6spImRhc2ZJlEO/S/XxYXA9Rpek9agn+mHhdE/F TIGjMvL5cY6pRNHTH5Osy2Y46IftfAdtwGkTh8cU0ec6Vcmk9SkTSFZ7Dcv1YLfaRBnh V/LjEw7stPFl4X30K/86eYiSk4B6B3+DEGrpUaRBF624VCpVK3zva3JMHZCpzhtws7mR NAJha/trLz32WMQfoz777GYU49yR4f4ov/L9KmVY1hCYLC16uycALSkmSYDdOcdoe3vt xah3ZytVYaPhdncOplZxTgHCCpvJdPb3DuDoyby8g8gdRQp2AnUscjZlMQg14TAISxnn TADg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=KMHyBtePJctFFVLhiljAsXW1cd3DwdhgWcEK6bYLQDk=; b=FN8qKYB6EddIeXsxIPbMCg1GcV4gk+cA7Fv3Rykp999DJB+fALvUo275/os17C/ScO 5Ka9V4QomxvdUptMThzBotLoUsdUnsP4AgIejcRm1NAKgHLXKRsvK4AosXXxxocGEaaX 2g4AtPu5mkKbHoCFRoRDHfKtH0UOw56amRZBjpGZkmnWTmmsvHiNC59KJzPdZFkjry7e ff59bHA/Fn0wuWQNH7xnbaPEq0jbmjVojO7VlodTGTz+vs4DXFQS091cbtnr7Zgr4VkD rd2kAAsxjLtAjXY8meoKK6GFZUF/QBvHGE4q/x7YDLAgTnW9UeL5xGAR9Mh13JYpF/Gw h3Zw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JRpLLMtd; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id u2si2487841qtg.304.2021.06.03.14.58.00 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:58:00 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JRpLLMtd; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:55906 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovLk-0004rl-Fb for patch@linaro.org; Thu, 03 Jun 2021 17:58:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58520) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6F-0002pn-6T for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:59 -0400 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]:47034) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov63-00019h-NI for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:58 -0400 Received: by mail-pf1-x435.google.com with SMTP id u126so1936059pfu.13 for ; Thu, 03 Jun 2021 14:41:46 -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=KMHyBtePJctFFVLhiljAsXW1cd3DwdhgWcEK6bYLQDk=; b=JRpLLMtdiRutBWGRjBoQ5FVYOqY+o9dGY+FOgAROcQ2hv1+bqJZ9XzipCMgER2RvNL odT0UAkgNuL36jYvoJmFJUnEWO1yPfKbYzc62OWwqTO5k5VY3FZWPPd0brBmetg8hhBK b0aNdvBzSQ9wPtLbQTboEzTWwfcIyElbwFlH5eNxOfrG+hGdNCuIuey1e+pAJQVdXKWM xpfh1mnWWHDuCBEf5viEg4qNbJfGxoylHDdNQc9aih7srm/aXXgxj205RfeHCG3XRbPI KFr2b9dIWoH3aBSlBEYqbUkBdGQfp3rqu2HziW5n1/zBu8mJF0cxrezLSUvGySjqsMvf kyBA== 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=KMHyBtePJctFFVLhiljAsXW1cd3DwdhgWcEK6bYLQDk=; b=W09kyp2w75Y620Se5kr0eS2QzcE/PzODmx9YloyuANsanAJIuWAurvwTwqwNXrM1n5 ZOUlkjVOkLyPHVOdhmQ1aBbbnJFE66jUti+WOPjG7Qr78xdc8o8PgtNX303j00s1o/Rx p2HRGysmVCWLCNBx4erxa2nC/jUID4LbvkRdnFchtrtOQEZOX1pj2GmhwnJJXZCWemmc ZOV6QB0Dc4/BFZDvm1mOZSuViestjuSmrjEXFjoSWa/AbM18Yoh/ADRV6xW1SM+TOVbw 0TbOUzfJWWffbuLbBs+mTacYtibtDAEBTYbtZTx3ytGx1IBnCwU5qeFG54jWsXIwehKF +bwQ== X-Gm-Message-State: AOAM531C6i3QA8/ModJILKnBkcOVI+6qYkL8/1V3IdN+ugo90VZLejLx b1EnrPal4lLcrvKQQSQDXwfV1k+P4F/mKw== X-Received: by 2002:a63:914b:: with SMTP id l72mr1495174pge.99.1622756505694; Thu, 03 Jun 2021 14:41:45 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:45 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 20/29] softfloat: Convert integer to floatx80 to FloatParts Date: Thu, 3 Jun 2021 14:41:22 -0700 Message-Id: <20210603214131.629841-21-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 58 +++++++++++-------------------------------------- 1 file changed, 13 insertions(+), 45 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 9caf1ecf9c..be7583780d 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); } +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 */ @@ -5033,51 +5046,6 @@ static float128 normalizeRoundAndPackFloat128(bool zSign, int32_t zExp, } - -/*---------------------------------------------------------------------------- -| 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 == 0 ) return packFloatx80( 0, 0, 0 ); - zSign = ( a < 0 ); - absA = zSign ? - a : a; - shiftCount = clz32(absA) + 32; - zSig = absA; - return packFloatx80( zSign, 0x403E - shiftCount, zSig< X-Patchwork-Id: 453324 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp630359jao; Thu, 3 Jun 2021 14:50:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzNQvzP0YtztkIQ4dCHOerATXrsh3v01JsnOz2fCOYUnoReQpYkKjhYlF6l1A2U+o0oKaWf X-Received: by 2002:a5d:94ce:: with SMTP id y14mr1154729ior.67.1622757002121; Thu, 03 Jun 2021 14:50:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757002; cv=none; d=google.com; s=arc-20160816; b=BC71nb1+T8dmwJ9u6af8gDOJxFbE+sGFxpvGZUSzaJYpfm3bpjhzuR1ljrCE9CZyMU xQ9AT2DzJyXXKnFPZMn4bu3pBZmBfw8bEb50TrJiWXJBqPNmF6+eWXjeKThf69H51K1g BojxglF7y+1/BtaQC+P5sor5+tobl6mUStgEz3UiJbxdVBzuJi//JDQay21/6rRiIwUw NasanwdYua5SdwqXmcsIVc0Pvq+n71gEbTQ+/tcI+pphZW0qOaT2RuCoHFwIx6+47Fcf 3bprC97xUIj2+eHABc535/AqiJyaDj3GQ/du1NHwhwutbCOaBWLv1K9lkEEM46rc7rGN HwOg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=twxGPFxgWB1P5xQ1RYx4pfDaFXjrIGQz83jyD9yknr8=; b=K8Xjsx3EzytaHAa5WRMNZZAgLtzoKjg3W/OGNHpOY9KzOnRSZfgwi0cmb9xe1LFYge KwE2PXylYWJb6zHImF60eeTT0GZHADa4TgBIfdvbmpgui42auVzH4eYzXaqPhTN6sSfZ A609PNTgaOYom7P+Zw/NgPIqZUO8fzElx1HhKFPgsxIE1cz8hJiID6cDPt6xGZrZuOVD C3VfbRK7IYQWNyPRPb8/L1LWFZEcoxW3YkFlCKn8RgrKLuw6PZu8ffwy+6EgIC9tztjP vqgI7pm8AHXYAT/2/3pdfBWIRSfVO22i7P186/elr2PM12RJjLnc5KJ+uyrfI58L7PWo o9iQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Aml6nMmy; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id y13si4174799ilm.43.2021.06.03.14.50.02 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:50:02 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Aml6nMmy; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:48952 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovE1-0006cz-Cn for patch@linaro.org; Thu, 03 Jun 2021 17:50:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58512) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6E-0002n6-BW for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:58 -0400 Received: from mail-pg1-x52a.google.com ([2607:f8b0:4864:20::52a]:46710) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov65-00019t-Df for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:58 -0400 Received: by mail-pg1-x52a.google.com with SMTP id n12so6135335pgs.13 for ; Thu, 03 Jun 2021 14:41:47 -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=twxGPFxgWB1P5xQ1RYx4pfDaFXjrIGQz83jyD9yknr8=; b=Aml6nMmyEnTkoq2DjSRWzEHpIbXUJXJjdaiDZvE2JF4e+QwJBF0mZ6gUgaIXLFtxjY x5eNLIZtz2Re5GEp0snW/Ggr9XDUZ6IyhCMWSTBIE6swRyNvWNA6LeRmSbqgg2WzdzPp 2OVdWekRZ+kS+ejbAAkh7WCP6IoeyREbkAGwh0oQdgu+pqKJL1tp3apfmKv1DViWLFpj 9CvLtx02t5ULn+MHhf0ffYkKTgM27Wg4bFOY8o2eaCP4+vKdXCMBgScRxefEU8R6tj61 QADPJLVSK+o+6Pus591cQ0Ef3GOcY8WVKWy/aGqVmMt14HRLylPCEMZ7UUgNbAtecfb2 KImg== 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=twxGPFxgWB1P5xQ1RYx4pfDaFXjrIGQz83jyD9yknr8=; b=E8P4nm15bm0swbvME+yri9f5UYn6DRKY4wy1lPpJr+h08D0fg5KcCHsdcYiDifZ62O JCqaKYaC/Re9sVDiHkbafh4s4ofFYN/zCORQ8RpOn5YYxAcUQ5XidQJ659TSWhv/yIqp Wv2kQ2WCbbB/UKYU2nZy31nHN2/nZw4n6R1MZL1MAYBFiRw69nP4bPKM5X4aExlIAeJi /SKTYXdpcbevx+LaK6/X6H9jFJrdnTADRxXARJhCDlfxDD0eOWi1K1xgW91MvZ+7lbWC 6DjjMMFOhtXvI7d4a7fa9qvPn96/L5ACUqoN+6YjLg+joOI+Z95o6WWKsOHiArC3xQjW Ed8A== X-Gm-Message-State: AOAM530W82+OXN2pANZ5Q2TTmO1uCfqPutEm9kWOiWy/NNimnznVNW7o SLBufaDAdfyWA5YKc+HZjtH3kHgtbwxR/w== X-Received: by 2002:a63:7e11:: with SMTP id z17mr1479444pgc.9.1622756506431; Thu, 03 Jun 2021 14:41:46 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:46 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 21/29] softfloat: Convert floatx80 float conversions to FloatParts Date: Thu, 3 Jun 2021 14:41:23 -0700 Message-Id: <20210603214131.629841-22-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52a; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52a.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This is the last use of commonNaNT and all of the routines that use it, so remove all of them for Werror. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 276 ++++++++------------------------- fpu/softfloat-specialize.c.inc | 175 --------------------- 2 files changed, 67 insertions(+), 384 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index be7583780d..acaab6a127 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); } +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 */ @@ -5046,42 +5113,6 @@ static float128 normalizeRoundAndPackFloat128(bool zSign, int32_t zExp, } -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-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 float32_to_floatx80(float32 a, float_status *status) -{ - bool aSign; - int aExp; - uint32_t aSig; - - a = float32_squash_input_denormal(a, status); - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if (aSig) { - floatx80 res = commonNaNToFloatx80(float32ToCommonNaN(a, status), - status); - return floatx80_silence_nan(res, status); - } - return packFloatx80(aSign, - floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - aSig |= 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 @@ -5318,43 +5349,6 @@ float32 float32_log2(float32 a, float_status *status) return normalizeRoundAndPackFloat32(zSign, 0x85, zSig, status); } -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-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 float64_to_floatx80(float64 a, float_status *status) -{ - bool aSign; - int aExp; - uint64_t aSig; - - a = float64_squash_input_denormal(a, status); - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if (aSig) { - floatx80 res = commonNaNToFloatx80(float64ToCommonNaN(a, status), - status); - return floatx80_silence_nan(res, status); - } - return packFloatx80(aSign, - floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp == 0 ) { - if ( aSig == 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 @@ -5665,104 +5659,6 @@ int64_t floatx80_to_int64_round_to_zero(floatx80 a, float_status *status) } -/*---------------------------------------------------------------------------- -| 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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (uint64_t) ( aSig<<1 ) ) { - float32 res = commonNaNToFloat32(floatx80ToCommonNaN(a, status), - status); - return float32_silence_nan(res, status); - } - return packFloat32( aSign, 0xFF, 0 ); - } - shift64RightJamming( aSig, 33, &aSig ); - if ( aExp || aSig ) aExp -= 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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (uint64_t) ( aSig<<1 ) ) { - float64 res = commonNaNToFloat64(floatx80ToCommonNaN(a, status), - status); - return float64_silence_nan(res, status); - } - return packFloat64( aSign, 0x7FF, 0 ); - } - shift64RightJamming( aSig, 1, &zSig ); - if ( aExp || aSig ) aExp -= 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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) { - float128 res = 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 @@ -5935,44 +5831,6 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status) return floatx80_modrem(a, b, true, "ient, status); } -/*---------------------------------------------------------------------------- -| 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 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - floatx80 res = commonNaNToFloatx80(float128ToCommonNaN(a, status), - status); - return floatx80_silence_nan(res, status); - } - return packFloatx80(aSign, floatx80_infinity_high, - floatx80_infinity_low); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - else { - aSig0 |= 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 = make_floatx80_init(floatx80_infinity_high, floatx80_infinity_low); -/*---------------------------------------------------------------------------- -| 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) } } -/*---------------------------------------------------------------------------- -| 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 = float32_val(a) >> 31; - z.low = 0; - z.high = ((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 = 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) } } -/*---------------------------------------------------------------------------- -| 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 = float64_val(a) >> 63; - z.low = 0; - z.high = 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 = 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 which | 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; } -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the -| 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 = a.high >> 15; - z.low = 0; - z.high = a.low << 1; - } else { - dflt = floatx80_default_nan(status); - z.sign = dflt.high >> 15; - z.low = 0; - z.high = 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 = UINT64_C(0x8000000000000000) | a.high >> 1; - z.high = (((uint16_t)a.sign) << 15) | 0x7FFF; - } else { - z = floatx80_default_nan(status); - } - return z; -} - /*---------------------------------------------------------------------------- | Takes two extended double-precision floating-point values `a' and `b', one | 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_status *status) } } -/*---------------------------------------------------------------------------- -| 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 = 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 |= (((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 From patchwork Thu Jun 3 21:41:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453334 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp633687jao; Thu, 3 Jun 2021 14:55:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx6V0VQ/eq4jvRcT4MsNRA7RrnjKditFhZy11tYgdjaR68WfWKwGqHR5JyvWGmX3U6cEW1I X-Received: by 2002:a6b:f10f:: with SMTP id e15mr1103437iog.155.1622757355160; Thu, 03 Jun 2021 14:55:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757355; cv=none; d=google.com; s=arc-20160816; b=cAJLwVdgksEL/c76h1fivufJn6xy9b/f7NqhDcXgXt6sgE4eDOryal6vFWUjJritV+ lRQkFj1YgDcIPHK6iBgL2UZh3QFu7Y6RerVpk/n8rk8FWi5mI40TiKIi/5PwQgnKEx8W nF3qZhOAXrYEECOaWhC9VZzAUU46MigwQOZopEzE6V68fZHCM4X3CzbBWUQLzLbErsLw MJTSPx64Gw0u11QlfhgHCTR8llJmM3qIEpesacv6J/E9GijMe4RomsKq2YRGHGCHeReU P950fDWADVVIJgTUUw8Ho1bOTgHWY1xIwcerQ+jVfxbSYsxVOjxjYOibmuxJS1/xzM8u d+wg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=eDlW17rU8x/GJbEZkz3v/6Nuf9ddIpOuVKL6VdfQvSc=; b=NYh2XzWci++pUWOPftlXmdWh75Q7aRhzydNLUEEE4QXYbWl7+XMzQxkW338z15HHi5 RN6XfEZoF+jtDE8EocW44Eq9db9uWUpdAmsUI4dn6/EEzixZN7rxJhhaXpyOYtoqjzZ0 NrBDdT0kyMeX4htOEscprMCu98WCOVqRQ7g+3v/QgEbi0lw+aqj1Kk5asYTunf39WG2o 9dtwuAmi2LjbeQb9vhtf9iVIHMn2W7cTjvLsiZv4njfwrxE/cyWnRvhO+AXfa/W0GLiQ JNXGomiJ+5jUuYiz37aoRcCHQCEUXbRbrlbfDMPezr0zz868Lu3Ucb7a7zFhacmnd/wA X5uA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=B1jqC3pH; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id l15si4482025ilv.39.2021.06.03.14.55.55 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:55:55 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=B1jqC3pH; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:50472 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovJi-0001B0-Ic for patch@linaro.org; Thu, 03 Jun 2021 17:55:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58508) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6E-0002mB-0e for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:58 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]:43698) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov65-00019x-Dn for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:57 -0400 Received: by mail-pj1-x102d.google.com with SMTP id l10-20020a17090a150ab0290162974722f2so4698503pja.2 for ; Thu, 03 Jun 2021 14:41:48 -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=eDlW17rU8x/GJbEZkz3v/6Nuf9ddIpOuVKL6VdfQvSc=; b=B1jqC3pH0WXJBFPhb9AbXf2X67Cd/mvjZfX7Ir1wV1+ZnKOfLdy/+gu4Jmrj6D8Whg XugecYvY54nL4j6SVaI1Jo+m3jmCSd/UR/I8HkieRhXkQJ04TxrPIPaQACRqN8GCq8BR fuQ1hkzPv6fv4zrl6SdkiEvahMtIpa2hYCX7Y5gzomBTcIdK5aE/T2sq/i4usqciqhds MrLvMe3D/WYim8YOEHiwYld0k83a+TbUxUOHhPHmEg/xePYRmxWABpJ44SEh5pzV9XYo +2qGh+pY201pAgLh+7nHJpUxBXa+Uw0QIsmQt7GpXw4QSt8XShY7OMlkfe4CzO08H9Ae WH0A== 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=eDlW17rU8x/GJbEZkz3v/6Nuf9ddIpOuVKL6VdfQvSc=; b=B0Lc6UvK2yva3mO8oGKBvQNA3E013GLJggxJbYzqjSu0kAGwoj4Fod0V4DGHGn0z93 FHELoTP27qysNjheuTK5H7qIrew+BaAqmsfjsaXFg1/J6LlX+/3dYkWR4RqiFKDoWd+z mWW5VfbPYGINw60H1Z2gH67swvpBFSGXYb05ly35QNormj7y7pcD1Os27SzAGUQRgDF0 hAezcu3hj2uk3aExkquc7l2ny8B07yIafHlYECMoQyy1ypztbZGHHuJC8R4TDhw8/A/X LjApuQlPvN/dYfLEXnE6YehUhddN2SnT73mPJ8HZfonr2w437UinRgwtqhgKvIZvfcnW yTnA== X-Gm-Message-State: AOAM5316TpPkAP6sIG1Bz/L289v+QJdMhnCLY8WGjeiv3P3rke0DNl7i 7+fUh++8HXJ0PZoT+pfdzag1ZA0RkFS00A== X-Received: by 2002:a17:902:d643:b029:ef:62cd:eeed with SMTP id y3-20020a170902d643b02900ef62cdeeedmr1120652plh.42.1622756507220; Thu, 03 Jun 2021 14:41:47 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:46 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 22/29] softfloat: Convert floatx80 to integer to FloatParts Date: Thu, 3 Jun 2021 14:41:24 -0700 Message-Id: <20210603214131.629841-23-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102d.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 336 ++++++------------------------------------------ 1 file changed, 42 insertions(+), 294 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index acaab6a127..5a2a872408 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); } +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); } +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); } +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); @@ -4160,127 +4202,6 @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status) return a; } -/*---------------------------------------------------------------------------- -| 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 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 int32_t roundAndPackInt32(bool zSign, uint64_t absZ, - float_status *status) -{ - int8_t roundingMode; - bool roundNearestEven; - int8_t roundIncrement, roundBits; - int32_t z; - - roundingMode = status->float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - roundIncrement = 0x40; - break; - case float_round_to_zero: - roundIncrement = 0; - break; - case float_round_up: - roundIncrement = zSign ? 0 : 0x7f; - break; - case float_round_down: - roundIncrement = zSign ? 0x7f : 0; - break; - case float_round_to_odd: - roundIncrement = absZ & 0x80 ? 0 : 0x7f; - break; - default: - abort(); - } - roundBits = absZ & 0x7F; - absZ = ( absZ + roundIncrement )>>7; - if (!(roundBits ^ 0x40) && roundNearestEven) { - absZ &= ~1; - } - z = absZ; - if ( zSign ) z = - 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 words), -| and returns the properly rounded 64-bit integer corresponding to the input. -| If `zSign' is 1, the input is negated before being converted to an integer. -| 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 absZ1, - float_status *status) -{ - int8_t roundingMode; - bool roundNearestEven, increment; - int64_t z; - - roundingMode = status->float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - increment = ((int64_t) absZ1 < 0); - break; - case float_round_to_zero: - increment = 0; - break; - case float_round_up: - increment = !zSign && absZ1; - break; - case float_round_down: - increment = zSign && absZ1; - break; - case float_round_to_odd: - increment = !(absZ0 & 1) && absZ1; - break; - default: - abort(); - } - if ( increment ) { - ++absZ0; - if ( absZ0 == 0 ) goto overflow; - if (!(absZ1 << 1) && roundNearestEven) { - absZ0 &= ~1; - } - } - z = absZ0; - if ( zSign ) z = - 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 represented | by the denormalized significand `aSig'. The normalized exponent and @@ -5486,179 +5407,6 @@ float64 float64_log2(float64 a, float_status *status) return normalizeRoundAndPackFloat64(zSign, 0x408, zSig, 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---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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0; - shiftCount = 0x4037 - aExp; - if ( shiftCount <= 0 ) shiftCount = 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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( 0x401E < aExp ) { - if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FFF ) { - if (aExp || aSig) { - float_raise(float_flag_inexact, status); - } - return 0; - } - shiftCount = 0x403E - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = aSig; - if ( aSign ) z = - 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 = - z; - return z; - -} - /*---------------------------------------------------------------------------- | Rounds the extended double-precision floating-point value `a' | to the precision provided by floatx80_rounding_precision and returns the From patchwork Thu Jun 3 21:41:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453330 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp632791jao; Thu, 3 Jun 2021 14:54:18 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxPVJpc1kE+IfZgHhe3kVqPvBpsLfI0OTknH5ruiCk/WAaRyk7HIqirymKWvZyp75W7/37P X-Received: by 2002:a92:cbcc:: with SMTP id s12mr1190122ilq.229.1622757257613; Thu, 03 Jun 2021 14:54:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757257; cv=none; d=google.com; s=arc-20160816; b=OQXTiUmyXK9w78W416PFCqanPKzzvF+IzmMdzBjZ9DZlVMZx+23J1pbHCHLsDg1wOo AOofl4LT3nJBUlTDzzZ6LgfsiQIi5LoAariFXZX3B+eCBlKv5ZE2piB9t+nSikjRwrBH nwVEelFO0KR89IwAemFvCyeaR4SFFhaL5uftcKA3aRozREmJPZ1oKNsapUFiwgHmfilY csmuEXMBeF7YZ0e0GDZr/JS2HsFVKs9XSaktFhOSiSdWATiajazV14IBD4GLabp2uk4j kvmRoZimeFv54OovNjNYSprZQsjGDRigXIcJtntgtc/qDYOW9KNj0rQlvIjAJqr2Sm5R 3hHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=yd4dLoXzc3PD/+c2UeVfTupk0478G5r8aHb9S8Vv7U0=; b=JwP4hIXSqlPtKEl8VwpOB8TUGo9xKlQwg4olo+5hFzrv/b8HUiThTxguHayJXQL1xH o+KMUax54Vog23R95ogXLOz6BbU0f9xsbgnj1cKbyNOwFL30QdEzndVGwSyeKQDjrusl rFfBfzDgfBc5fFC4pi5+kRZ4fgKHLVOoPIZknl4uwe76IxNCPIcXJSN8dNswKI/832Xc ogmh9SS6jzOEfvfSkfz4EUH87vrrU+18uK0eXaIc8BVLEuZ7BwCfQUCpQymbD8TUOg5m c3JTsCl/KLUpPLJ45FZoI7UoxhCEHW2k8cqPK7sNYR9RHVkkla8KGGHu3uTP4H/XRZ2/ +nvg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VOBzVp+d; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id f14si4424220jav.44.2021.06.03.14.54.17 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:54:17 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VOBzVp+d; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:39862 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovI9-0002Zf-0g for patch@linaro.org; Thu, 03 Jun 2021 17:54:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58552) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6G-0002w7-PQ for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:00 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]:41935) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov65-0001A1-GA for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:00 -0400 Received: by mail-pj1-x102d.google.com with SMTP id b15-20020a17090a550fb029015dad75163dso4725539pji.0 for ; Thu, 03 Jun 2021 14:41:48 -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=yd4dLoXzc3PD/+c2UeVfTupk0478G5r8aHb9S8Vv7U0=; b=VOBzVp+d9NYSWRstBYsOl3BRTKMl8Mh5bkXe9gZH8VAg6dAPYLOjKol/tgt6T8Q2W8 gMufoTuZLiH2NlwbGTIji/9EHaMJdkhl7PwvW6UfXUsCbyDJI/fpb0Cphpd7mPyp7Azw VwJa3KynxdlIFNdrqL/WM3gre4MFtnVvljF/X4I82zy3OyccBjx+/TCxr57jEJNDlCpL 2gpyg0MQtlLzRKYBF7xLy8BoGkpzuV2/KRNBQkqFM5MHjdZtukx96PEgmm58RrItQRJm zkIC2975eEkuObacqN6SnpJ0T48cd6MIH7DInOuefe9KgQ8RMwZUN8Ef1O9XBP2ZKvC1 4Lpw== 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=yd4dLoXzc3PD/+c2UeVfTupk0478G5r8aHb9S8Vv7U0=; b=XAqVR7m4K1vITlZ7TnyXJjMkpT6+5cvQiav0glqOB2pq5ULK40wgUum6OKIJlQX9Hy rHXy9TbbgxuPVBVXMGFCloSA40na5t8ircg+y6M2nss5gOOWf+oliSKJXQAqe69r9vwE vC7qKEsBEe1IzQnVFXCxiocB6ffR1Z6MY/LJsoSTQHmkbXWqEg71TCHqMFKI1XTu9G8p sgaD+doWOpcodQWtwIoHWhEc+4l9cixNK4fnA8+rYrozYMaIwAewFjL3WxJOkWOqE5t1 48Ae52lONtHW0ML8QbmBMOwP7DJhycVIyo+AGttEA3/nhRsxWEcVhEwmuF8XP0zdN/qu 9ruw== X-Gm-Message-State: AOAM533Zt/HquJfwAg0m7TiheYxVWftkih4TrJt4Y3+ZJVF2t+Jr5/4+ c18SMrsXhPNZRazm4gcqfefsHSNbTrkG8w== X-Received: by 2002:a17:90a:6285:: with SMTP id d5mr13892385pjj.4.1622756507861; Thu, 03 Jun 2021 14:41:47 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:47 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 23/29] softfloat: Convert floatx80_scalbn to FloatParts Date: Thu, 3 Jun 2021 14:41:25 -0700 Message-Id: <20210603214131.629841-24-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102d.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 50 +++++++++++-------------------------------------- 1 file changed, 11 insertions(+), 39 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 5a2a872408..770badd447 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3911,6 +3911,17 @@ float128 float128_scalbn(float128 a, int n, float_status *status) return float128_round_pack_canonical(&p, status); } +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 */ @@ -5745,45 +5756,6 @@ FloatRelation floatx80_compare_quiet(floatx80 a, floatx80 b, return floatx80_compare_internal(a, b, 1, status); } -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 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - - if ( aExp == 0x7FFF ) { - if ( aSig<<1 ) { - return propagateFloatx80NaN(a, a, status); - } - return a; - } - - if (aExp == 0) { - if (aSig == 0) { - return a; - } - aExp++; - } - - if (n > 0x10000) { - n = 0x10000; - } else if (n < -0x10000) { - n = -0x10000; - } - - aExp += n; - return normalizeRoundAndPackFloatx80(status->floatx80_rounding_precision, - aSign, aExp, aSig, 0, status); -} - static void __attribute__((constructor)) softfloat_init(void) { union_float64 ua, ub, uc, ur; From patchwork Thu Jun 3 21:41:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453327 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp631409jao; Thu, 3 Jun 2021 14:51:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyR22QqqrCujeXFRuEIfDzkarFUuH4fzkayqcGFq3vaK4Wrg6i8lRIE91pQiknx4C9ZBFpz X-Received: by 2002:a92:ad07:: with SMTP id w7mr1180070ilh.98.1622757112650; Thu, 03 Jun 2021 14:51:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757112; cv=none; d=google.com; s=arc-20160816; b=T79euNdLmOS4MGXJ5e3/o0vSd/dpIuysCgFmZNOpn8piOUOw/TYtbPzKpFbYMFpJwa oI1+D7B5p8SR52QB2ksFtxX4BRkN68NjGIkrPqF8K0CuV+KC95wJ7ra2oiIRmt5qOBgf U0KGAKCaR0YbR0seohCr33sYtZZ947sl60f7tD3QcsHinF5+6pW8BylUdrPAS2mxTv8/ E0mo9xwDSrDVAHAt+N60plw0N+CrKJDuir6fXTTyM6k86DKcBicDo9M+PyQKp2aYL0rP aOOjPdOrdCUw+KHZSvqLgtL1Y0exbLDkDbmTuxUG11BvvO/GkWtFIo8oqc5I/rKylbnw 9rQw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=ndVa83SIfMh7/NYhgST6dDyuB+J+HvB1UgKzExjE9v8=; b=vTg7X13JshNm0FCGWnswmAXX4c+grAyEHWt358XQ0EelUTiOL7eNhv4MW2rIZWJibz l2AO/XvO9McjZdgnGAsj/YDoRQ77zD6xTeQhpFi66DLcVn3Tnr2JSFHMEhuSkev0bLwm Ss1sGcGRy+bRjrSYJUCL2VJQe1pawHnl+S9yKbKKS8uqD21z3gQ23Om//FD+2FwovgU2 4AcdDKEdUMgjRcrb1H9ZJ4R521CmkxPcmoq01YoATZS4hRUBM381usWSp+VuyKMFDGnn 3I+SecYFViSRKo6RtXA8dsZBTbMsv/IgdXQn+KH5FDoyUmqiv8x00MGSuD+Fk6/Pm2/B Smuw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=qrpAHubu; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id d18si3931328jam.114.2021.06.03.14.51.52 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:51:52 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=qrpAHubu; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:57530 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovFo-0003y0-4W for patch@linaro.org; Thu, 03 Jun 2021 17:51:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58526) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6F-0002qP-BX for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:59 -0400 Received: from mail-pg1-x52e.google.com ([2607:f8b0:4864:20::52e]:41883) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov65-0001A7-HU for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:41:59 -0400 Received: by mail-pg1-x52e.google.com with SMTP id r1so6165568pgk.8 for ; Thu, 03 Jun 2021 14:41:49 -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=ndVa83SIfMh7/NYhgST6dDyuB+J+HvB1UgKzExjE9v8=; b=qrpAHubuOPfTL1yxgHwgrzkF/fMrBaJzUWnxWaCJnhMUgipGZ8Ibkg/noq4M1T0xpN Zby1WhTVqjaU4uxItGlf7saaleTOtanK8FsUTyCpqUu8WQOOMK4bWTLDIgwGaTzffVeu 19Fj9bHlwMkMZ7uTlnpGDtObqVtLB88XV9MFaOMImA2ZENKcso29oBqsczNU1JWYIlz+ vO7tbxoAK6RyBex/QPXdVlPUPDbEXVjfRniPtyfQbmofFI/jo8fTiag5CXpMS6zetn+0 Sj0jEDPhNZs/QTvrvl14oqHMiUcSOSLAppKMYbvamVFiwD2O22Hv0LBBwVQLNsqZvXva 50CA== 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=ndVa83SIfMh7/NYhgST6dDyuB+J+HvB1UgKzExjE9v8=; b=stcmT1F9r2y7k6vfxGXqDHkIu5st84IKHP36DOS8xdwI/qSjaChvgI6VlG/f1QqVU+ txmW3QxXvetsWYxe7Y6WZd93Nt4FczN8teZpjl+4+WjK69/0Adw0UQYEFlf6FAIhCGHX NPbooXicxfFKI25wvL7iZrdhh2wuRD/gF7wVELdEa8Sj4F+agosLzpK8ZIn2eCwpf4Uc WA2Ppg0LCDluRBeeMBcaDbnXhIbM22xJX75nYndmsDUeVIMJ5SHpoMe6+beUhkMQ4DFv +tpJ3LYqZq7Z9tkViuF+cWo4QAyrfZzjm9gKMtDZx+EnUVbkkkB+a+BaZYkCe0VUP8a+ +r+Q== X-Gm-Message-State: AOAM531D5TwL463QyzO0F79Le1t7dxjuCRxDegNzuq5RVnkRtB8/ZOyk FPb3Djjm+P6oDk2iIUr4rvXpOO7pKVR3cQ== X-Received: by 2002:a05:6a00:10c2:b029:2de:7333:1343 with SMTP id d2-20020a056a0010c2b02902de73331343mr1381577pfu.42.1622756508387; Thu, 03 Jun 2021 14:41:48 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:48 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 24/29] softfloat: Convert floatx80 compare to FloatParts Date: Thu, 3 Jun 2021 14:41:26 -0700 Message-Id: <20210603214131.629841-25-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52e; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52e.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 82 +++++++++++++------------------------------------ 1 file changed, 22 insertions(+), 60 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 770badd447..c32b1c7113 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3862,6 +3862,28 @@ FloatRelation float128_compare_quiet(float128 a, float128 b, float_status *s) return float128_do_compare(a, b, s, true); } +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 */ @@ -5696,66 +5718,6 @@ float128 float128_rem(float128 a, float128 b, float_status *status) return normalizeRoundAndPackFloat128(aSign ^ zSign, bExp - 4, aSig0, aSig1, 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 ) == 0x7fff ) && - ( extractFloatx80Frac( a )<<1 ) ) || - ( ( extractFloatx80Exp( b ) == 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 = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - - if ( ( ( (uint16_t) ( ( a.high | b.high ) << 1 ) ) == 0) && - ( ( a.low | b.low ) == 0 ) ) { - /* zero case */ - return float_relation_equal; - } else { - return 1 - (2 * aSign); - } - } else { - /* Normalize pseudo-denormals before comparison. */ - if ((a.high & 0x7fff) == 0 && a.low & UINT64_C(0x8000000000000000)) { - ++a.high; - } - if ((b.high & 0x7fff) == 0 && b.low & UINT64_C(0x8000000000000000)) { - ++b.high; - } - if (a.low == b.low && a.high == 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 *status) -{ - 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; From patchwork Thu Jun 3 21:41:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453336 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp635027jao; Thu, 3 Jun 2021 14:58:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzIG2WMAkg5c+UlkTGlBCL+r3ZVTRoHhZr/3Ct503WhaXQ5bJs277jghPhrrQb0FoYKhdim X-Received: by 2002:a05:620a:787:: with SMTP id 7mr1386067qka.397.1622757493959; Thu, 03 Jun 2021 14:58:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757493; cv=none; d=google.com; s=arc-20160816; b=locqFEdHA+ldlbtbnvM4EkGpkh+DeqBR+j6gAhVKVM7epwqaVMpjtaXnriYABQXpyB 3nF/6i3hy/zl0F4t2nYWUb8dFxH2PA56wYmGZzAkL0fcOhhVjN0rP7jyOGy63lEBfOOq qkD0taDJ8Ep4G94lTz5Amvys5x+uOVpvo0M7bojzad8MmtMv/3iIQ2CHyhPt3ODSdpg+ 3kXnTU55fcr9TNPgReeyQSwmr5GiS6775FbkkjdawaBWIvfzWnxnHXqK3CUp1NPf5ceB n7amGA5N0uTvdvx4fBldXe0mm8K9YBMjg3hJev4+3KEG9Kfs720DNTQ52qQr3iBI+jBX AQng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=96c6uJZ3c+bY6czT9boE4Qd+QkQsfFNNXC+3KlgI5bI=; b=GGopasHPKssYoUzQx3D0jfyDRDWFlF/3zC55bLL7/k8diaPJ1N4cHuMOkhpXtjlb3e Iha0T94EU7A+0S46NSfaiviL9U6lHjXPyOZ2oB+ueQaX4f2g6s73PCZ33T0nipmJ/fOF wZ+ryoozdmiBtmOkJTl/ZyXjnvwljTSCZcnGEegCobs0rGOtsLqf9KrFfAVVl6B9Q6VW zEGJBhEBdncB49L4n7gBE5yWj8cRcYwsQXc0bYZHjEPf6rgnonpHTunoNG9qs/1cBJC8 kTABpaBWHoZJfpz3yxExifHJMpMcUE0Uymx8ptLV3b6tLkgf6ZK7FKUhyrWSlYR6vmm8 2Rkg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BM6d3PSu; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id g3si2732294qvi.128.2021.06.03.14.58.13 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:58:13 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BM6d3PSu; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:55524 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovLx-0004b2-D1 for patch@linaro.org; Thu, 03 Jun 2021 17:58:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58576) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6J-00038S-RI for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:03 -0400 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]:38650) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov66-0001AC-IB for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:03 -0400 Received: by mail-pj1-x1030.google.com with SMTP id m13-20020a17090b068db02901656cc93a75so6260193pjz.3 for ; Thu, 03 Jun 2021 14:41:49 -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=96c6uJZ3c+bY6czT9boE4Qd+QkQsfFNNXC+3KlgI5bI=; b=BM6d3PSuznr1qtaq+jeJeZCPFmK2oO0q8oIZ4QuuUUuXE0sZaRnfRKc4mnY3QuKNzx XkRNKSdm67CDTE9UabSoIkYX6zkXA2kBCkX+VXBBz5b880mvu2MLuOYCM6z2M7H2FmEx 2GqRcSd9E39VcLqTMi/eHaCoskHB/6tdoppD7hHKXUTQ4FoKKutttwI+dQtdv1feBI3M uxCFyTXgaij8a8kqxhZ8iwFkDHz7AqrqvUa01uXrQ5xHwLu7HEn4ThoB0B0gKS5wuzop /+i4SFBr9ibqmORnbS1XrmH94gMovIHE4YpAO10V+ekyJOKBjp2sG6OJsMnRqX/P0u8W AMrQ== 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=96c6uJZ3c+bY6czT9boE4Qd+QkQsfFNNXC+3KlgI5bI=; b=GJG2HM+tRDRBM6kYBfalsWWerwWcn+TL8Pf2KuvOEKYUpG+/+bEmh0NmwFCbb5nJLa 8QcM+rhzZ4tl0d6Tw27rwbsA+AlLjo9jGpWGq5ekcS7lP0bBnFuYwHbeY//VH9dIaEOW b6nViB0/EtQnxH6WFQnr+P1fkKOMIEXB+WgkQbwlrWmE17QsDYUDeQ1gf1qfG10cbqwT 9b5CGRvkpM2UFe32QpWpH7A2/UnsM03QaRTxvz3Jn80Zpng1yzfXRiCcak6tBp2INIr8 VeQl9aYbUiwMeAlC6LHGZaOIu3ECDXidBWmCVJWDf3gLeZwuY+EWKC+vOI/1CVUa4Hph 11BQ== X-Gm-Message-State: AOAM533BBOeZTcqdIN3eGSAH4Ok7XbmbxqjLXHIC33U9Xoge6Eu3a7v6 OpbU1tiASF4cyuhQzuXVwOrOGc116+c98A== X-Received: by 2002:a17:90a:b782:: with SMTP id m2mr5154492pjr.147.1622756509057; Thu, 03 Jun 2021 14:41:49 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:48 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 25/29] softfloat: Convert float32_exp2 to FloatParts Date: Thu, 3 Jun 2021 14:41:27 -0700 Message-Id: <20210603214131.629841-26-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1030; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1030.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Keep the intermediate results in FloatParts instead of converting back and forth between float64. Use muladd instead of separate mul+add. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 53 +++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index c32b1c7113..27306d6a93 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -5210,47 +5210,40 @@ static const float64 float32_exp2_coefficients[15] = 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 = float32_squash_input_denormal(a, status); - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - - if ( aExp == 0xFF) { - if (aSig) { - return propagateFloat32NaN(a, float32_zero, status); + float32_unpack_canonical(&xp, a, status); + if (unlikely(xp.cls != 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 == 0) { - if (aSig == 0) return float32_one; + g_assert_not_reached(); } float_raise(float_flag_inexact, status); - /* ******************************* */ - /* using float64 for approximation */ - /* ******************************* */ - x = float32_to_float64(a, status); - x = float64_mul(x, float64_ln2, status); + float64_unpack_canonical(&xnp, float64_ln2, status); + xp = *parts_mul(&xp, &tp, status); + xnp = xp; - xn = x; - r = float64_one; + float64_unpack_canonical(&rp, float64_one, status); for (i = 0 ; i < 15 ; i++) { - float64 f; - - f = float64_mul(xn, float32_exp2_coefficients[i], status); - r = float64_add(r, f, status); - - xn = float64_mul(xn, x, status); + float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status); + rp = *parts_muladd(&tp, &xp, &rp, 0, status); + xnp = *parts_mul(&xnp, &xp, status); } - return float64_to_float32(r, status); + return float32_round_pack_canonical(&rp, status); } /*---------------------------------------------------------------------------- From patchwork Thu Jun 3 21:41:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453332 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp633085jao; Thu, 3 Jun 2021 14:54:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwM/8sog/uT4VIQO7G0SyyV5ZoY1BKAWwY0fl6rp7Q+mjuyMRgzj0iJe8T9uSGB0WR4RlnI X-Received: by 2002:a05:6e02:1a01:: with SMTP id s1mr1175059ild.307.1622757292754; Thu, 03 Jun 2021 14:54:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757292; cv=none; d=google.com; s=arc-20160816; b=GAjYdR12+7DmXcVasgNFO0zLG6y1KD6fHXwoSEXZzgdN3TW+sHJn+9DPlxjc/DuN+B L6s4gRSv9iI5MSGofU62E64+9ZkqH962F+Fcl610NGA8QHGJG3U6Oje7uFcsc1SANusE pY+KSJFctSt8ECp5IU41+AwOefjCd7oOx4LN9i/bjL8oeo0JsVq98L1mgDLmelXnvmF9 Tv5auVamkHeIT0YZYhML6RpsglV+htXYDHSpCB5UuhVUqwxMcclnIXjDxN5JzI4LK30q vXjmcF0za2KM5M1gt0DzFyc8z7iBCmEH/6Xu+odVIyfEOQotjCZRGQwUwTSMuR/v//Hj z9Zg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=9oe7TH/FOyKvHqZI98/sVuSYHE/+p3BdMoPYUl0hOx4=; b=B+1OPWsXmRGhAHAFTj7xFDuLr3Og8/KKdhod50QIKqmIcIa4KGA6d+TZxDa2X7smMg otDNcDDjB0OK74j6RHzVF5p5g9jw8WeaEdVGdDgm5HyICodoltUrRbd16KTWgwh0sXPo 0wKcD7GVduRtS6557pA2dCfqIDDvczF77eG7X17kYGtiNh/kMF8pGFFHUVEmG90GOobZ OfLG9pRj7fZODX0ak/Z/FIrwePi/eXXiL4oLdCABQNku8DgW78GPz1gRTwmkhWDAVGle BJFGRODJMW6b/2Y4gMmQstxmfQwIpM96X6++KKndxpdUI3rx7DoteW4YCleyXm+uwcHf yz7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ccZCkOfr; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id o14si4488433iow.26.2021.06.03.14.54.52 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:54:52 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ccZCkOfr; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:46088 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovIi-0006fG-5n for patch@linaro.org; Thu, 03 Jun 2021 17:54:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58570) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6J-000353-1H for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:03 -0400 Received: from mail-pg1-x52f.google.com ([2607:f8b0:4864:20::52f]:43756) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov67-0001Ar-51 for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:02 -0400 Received: by mail-pg1-x52f.google.com with SMTP id e22so6157262pgv.10 for ; Thu, 03 Jun 2021 14:41:50 -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=9oe7TH/FOyKvHqZI98/sVuSYHE/+p3BdMoPYUl0hOx4=; b=ccZCkOfruGcESAEyA9y5KbZnxJHg53XbzSsFf0LtTCGjrwrfJ8CxKwFc1zDHLGLrhJ l7UugNqSIe9prc/MmT6PLJYhJLKaDu+aKqWWFLBM/BbBJlLXoIVW/YRKqpPSEAXKKGVH vA6LtGu2TQwXXHvG7E+me9F61hLc1PZepQK3MO0Q58H4xN1yaA7Q++1fUeR8xe3jTJ+x vxOmaTjtW19bXCHxw4+lAndwnJ/TrClAWOafhVOLQESkJ1L+AR3waIi6bUFvLhxLR+IL 7n6gg7hoXio3zavvrG1qDpidJyc8EbxeeQf6ha/lXUlN8w3Mt1x2SegWB/EE833r0sj5 U2cA== 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=9oe7TH/FOyKvHqZI98/sVuSYHE/+p3BdMoPYUl0hOx4=; b=qYiTOaX7FvGtM9o880lwJYaSCmw1FOGRovjW0flOTzKfNdLApDmWlcWdPpE5iSYtUd QoW+2Hmob6/gzJK9eb5XvUw1QRWrHWhb2p2w8cf7igcc5qkXH1HxruoKF6iJa/NKZ888 dJiTbn3hz9KrXxf72LJgmtML75wKAYFHfvq3EF4O7E1ac2BA4dBwp2sZWh7xjTS67GGe FGkKKH5PZQJO6i/B9b6Q4HYFHCN5ChYH9n6s1wTsuyNoPK1GCHdCbdZl6UZ0cEsNFK4k jxCNY/4UEHyDR+Y7jt4o7Wi5ZqL/n3yad8HpcRPBsrLZeSe3kkZESaMquXCQIoCVCQ1R MC5A== X-Gm-Message-State: AOAM533DSuKtBpgE8HozOQzIbpu1XJUyTPSK7NmfAjFvFxF13P67J5vq GaRjLgh+FMm3hTN2wvYdyCg7PIy7X7D4YQ== X-Received: by 2002:a62:2944:0:b029:2e9:8ce5:b044 with SMTP id p65-20020a6229440000b02902e98ce5b044mr1344822pfp.3.1622756509674; Thu, 03 Jun 2021 14:41:49 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:49 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 26/29] softfloat: Move floatN_log2 to softfloat-parts.c.inc Date: Thu, 3 Jun 2021 14:41:28 -0700 Message-Id: <20210603214131.629841-27-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52f; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52f.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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 Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- 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 -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 27306d6a93..c0fe191f4d 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -927,6 +927,12 @@ 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) +static void parts64_log2(FloatParts64 *a, float_status *s, const FloatFmt *f); +static void parts128_log2(FloatParts128 *a, float_status *s, const FloatFmt *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. */ @@ -4060,6 +4066,27 @@ floatx80 floatx80_sqrt(floatx80 a, float_status *s) return floatx80_round_pack_canonical(&p, s); } +/* + * 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. *----------------------------------------------------------------------------*/ @@ -5246,56 +5273,6 @@ float32 float32_exp2(float32 a, float_status *status) return float32_round_pack_canonical(&rp, status); } -/*---------------------------------------------------------------------------- -| 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 = float32_squash_input_denormal(a, status); - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - - if ( aExp == 0 ) { - if ( aSig == 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 == 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, float32_zero, status); - } - return a; - } - - aExp -= 0x7F; - aSig |= 0x00800000; - zSign = aExp < 0; - zSig = aExp << 23; - - for (i = 1 << 22; i > 0; i >>= 1) { - aSig = ( (uint64_t)aSig * aSig ) >> 23; - if ( aSig & 0x01000000 ) { - aSig >>= 1; - zSig |= i; - } - } - - if ( zSign ) - zSig = -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 @@ -5384,55 +5361,6 @@ float64 float64_rem(float64 a, float64 b, float_status *status) } -/*---------------------------------------------------------------------------- -| 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 = float64_squash_input_denormal(a, status); - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - - if ( aExp == 0 ) { - if ( aSig == 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 == 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, float64_zero, status); - } - return a; - } - - aExp -= 0x3FF; - aSig |= UINT64_C(0x0010000000000000); - zSign = aExp < 0; - zSig = (uint64_t)aExp << 52; - for (i = 1LL << 51; i > 0; i >>= 1) { - mul64To128( aSig, aSig, &aSig0, &aSig1 ); - aSig = ( aSig0 << 12 ) | ( aSig1 >> 52 ); - if ( aSig & UINT64_C(0x0020000000000000) ) { - aSig >>= 1; - zSig |= i; - } - } - - if ( zSign ) - zSig = -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..4eae93eb7c --- /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 exact) +{ + int msb; + uint64_t ulp = UINT64_MAX; + + if (real.i == soft.i) { + return; + } + msb = 63 - __builtin_clzll(real.i ^ soft.i); + + if (msb < 52) { + if (real.i > soft.i) { + ulp = real.i - soft.i; + } else { + ulp = soft.i - real.i; + } + } + + /* glibc allows 3 ulp error in its libm-test-ulps; allow 4 here */ + if (!exact && ulp <= 4) { + return; + } + + 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 == 63) { + printf("Error in sign!\n\n"); + } else if (msb >= 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 == 20) { + exit(1); + } +} + +int main(int ac, char **av) +{ + ufloat64 test, real, soft; + float_status qsf = {0}; + int i; + + set_float_rounding_mode(float_round_nearest_even, &qsf); + + test.d = 0.0; + real.d = -__builtin_inf(); + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d = 1.0; + real.d = 0.0; + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d = 2.0; + real.d = 1.0; + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d = 4.0; + real.d = 2.0; + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d = 0x1p64; + real.d = 64.0; + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + test.d = __builtin_inf(); + real.d = __builtin_inf(); + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, true); + + for (i = 0; i < 10000; ++i) { + test.d = drand48() + 1.0; /* [1.0, 2.0) */ + real.d = log2(test.d); + soft.i = float64_log2(test.i, &qsf); + compare(test, real, soft, false); + + test.d = drand48() * 100; /* [0.0, 100) */ + real.d = log2(test.d); + soft.i = 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 efb81bbebe..d1bd5c6edf 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, float_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 != 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) = -inf */ + a->cls = float_class_inf; + a->sign = 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 == 64); + + a_exp = a->exp; + f_exp = -1; + + r = 0; + t = DECOMPOSED_IMPLICIT_BIT; + a0 = a->frac_hi; + a1 = 0; + + n = fmt->frac_size + 2; + if (unlikely(a_exp == -1)) { + /* + * When a_exp == -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 precision, + * as 0x800..000 - 0x7ff..ffx becomes 0x000..00y, leaving only the + * bits of y in the final result. To minimize this, compute as many + * digits as we can. + * ??? This case needs another algorithm to avoid this. + */ + n = fmt->frac_size * 2 + 2; + /* Don't compute a value overlapping the sticky bit */ + n = MIN(n, 62); + } + + for (i = 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 >>= 32; + a0 *= a0; + } else { + goto exact; + } + + if (a0 & DECOMPOSED_IMPLICIT_BIT) { + if (unlikely(a_exp == 0 && r == 0)) { + /* + * When a_exp == 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 -= i; + t = r = DECOMPOSED_IMPLICIT_BIT; + i = 0; + } else { + r |= t; + } + } else { + add128(a0, a1, a0, a1, &a0, &a1); + } + t >>= 1; + } + + /* Set sticky for inexact. */ + r |= (a1 || a0 & ~DECOMPOSED_IMPLICIT_BIT); + + exact: + parts_sint_to_float(a, a_exp, 0, s); + if (r == 0) { + return; + } + + memset(&f, 0, sizeof(f)); + f.cls = float_class_normal; + f.frac_hi = r; + f.exp = 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 = 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 = executable( include_directories: [sfinc, include_directories(tfdir)], c_args: fpcflags, ) + +fptestlog2 = 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']) From patchwork Thu Jun 3 21:41:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453325 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp630662jao; Thu, 3 Jun 2021 14:50:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzbceQdfN+47EefW9GUHphG9rAURBqCaZ0vXhqiN8KJUwkXtVGMMA0rUpxmLD/epXdInISG X-Received: by 2002:a92:cd4b:: with SMTP id v11mr1199856ilq.80.1622757036185; Thu, 03 Jun 2021 14:50:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757036; cv=none; d=google.com; s=arc-20160816; b=HAhgODJ6XmyGVlgo3MHh2qzkxm1yQjKl+F5YWwmz4rdZnXF7VPkhbYW4gAb15XDAzD /P4eiZgMBvMhHdxhcFBWOx1kytASsD35u0KNXUawbdpbmdTkfNgKi5PajMxr9C43eIWK ZPvK0I+YrTU6CT/yFDwJAn677FUWjLXatgEJp6npOkpqxcXgaHO6xbfAUavO+aKsaCTv 4EonpyFq/R3pSJnbn4zE7Xa2Q4vjSqRcMOWpFjDoGlBPdmWpsIQYbtuw5Cpks4zBju4p 5zDQ7nuOq92kIFNDn5ZgdtqaiL0I8c8dq1dxTBBPfiI4EMufmFOBIteeL35DFU8/kXX4 Nf/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=PYPaf/j9AHT9fcW+1JhpwV4TzbljbGsjiwi3XwcqOTc=; b=izC0tg5sK73x2dTZa6jOihHk55g5loYW/9FcA/1DwvBzdsoZVneRVqclWgMuOnf3dt n2fJZHCXLC/YCTNVRmPs6rTOujvFCbb5dCR2fOg/JION4d3GlBUyF1C7ekVCgt/Q0QBL VBESuOje8maYKoV0OFCIIxwTawIAIU+5UPf4PgSkoFRZagY/YoNHXn28wHc+HpIpLlV+ Z75GkpEm6cbV8n4WTLEr3Glw80Vh9BiXRMi44QBoe4LsXuhjpSi8Lq2rWbmJ2TBiXwPm R3WN2PDVwnmYBm7ZARSFvVjwjg8AWZqP2kpYHreH9V467WzTMDeLe/iWyqJDsEtS+cwt FSGg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ewFf7mWY; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id h5si5124248iol.44.2021.06.03.14.50.35 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:50:36 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ewFf7mWY; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:54728 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovEZ-00021n-DB for patch@linaro.org; Thu, 03 Jun 2021 17:50:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58582) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6L-0003EO-5h for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:05 -0400 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]:44845) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov68-0001BF-Se for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:04 -0400 Received: by mail-pj1-x1033.google.com with SMTP id h12-20020a17090aa88cb029016400fd8ad8so4683039pjq.3 for ; Thu, 03 Jun 2021 14:41:52 -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=PYPaf/j9AHT9fcW+1JhpwV4TzbljbGsjiwi3XwcqOTc=; b=ewFf7mWYNjU2Dbd5H05g+3/Wzxj6M6YmXqmCSDu15ym+wtOJPMvZs4ltepZFo2PKAM o2HxZJK6c09NSX6UXvDj8maJpjfA7PK0dhTwGFhuPgYwyPL/n1BSJvApWQJ6krF8/nCy 5N/ap885CSxv0kDPAQmHY6Ek1AIZ8jA8cl2qIYufubQpWc/5HH8mXBgPp3E3LMQp7S/K zqaBdwF4wv3e8rOgD+Xu5g6tnKQSTo93v9vNPQPP4EEsdKBFq2VCL8XoE+fjUUiJ8HV0 pElK5W2xabDxL9fBmXSGSrWp0OgdfbEHmiyS1T4clxqQqHu1q11FTk2EgRlsD7uciEQX ESwQ== 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=PYPaf/j9AHT9fcW+1JhpwV4TzbljbGsjiwi3XwcqOTc=; b=DKN3EX0YfY4bgH62206+H4yKbaoG26Iy8IRyy4Q7pMM4ZRKTd7fsUdmVZR6+LOWW8i dl8fGu8gmy7Lxqy0NkKOIQHKJ9UJrwImxop2ClOOU2WTILbQzSsFtzu+NxJ3xogCFxfo Q1wr26fFzYPZ9wH/d2S92FUThzn1rwOWR72B4ezbKgUtIHvSaGALAcakbTaxogp1CWPc mOJsH5eUeLDteZnFzG4SIkYU2nI4/j0p1hkuc9rxfgqDMkJd4Vl6u1oFXAG9q0/WVc2V CmrTIVtEgO8YTi9IH2Kwde7buRVNPG4CVVh/b2COaEeJ842a1utH/3y7qBnc7sOwG/Um sM1g== X-Gm-Message-State: AOAM533qqkPKMacYOlhrPyCFROiK/jCXNAj1IqmFhO942QUxl+R8JKHR 7pkC2J0X+uU8h2tGGGep+BhlZQiswOoSLw== X-Received: by 2002:a17:90a:8d82:: with SMTP id d2mr13359307pjo.106.1622756510446; Thu, 03 Jun 2021 14:41:50 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:50 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 27/29] softfloat: Convert modrem operations to FloatParts Date: Thu, 3 Jun 2021 14:41:29 -0700 Message-Id: <20210603214131.629841-28-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1033; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1033.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Rename to parts$N_modrem. This was the last use of a lot of the legacy infrastructure, so remove it as required. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- 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(-) -- 2.25.1 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, uint64_t b0, uint64_t b1) return a0 != b0 || a1 != b1; } +/* + * 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)) == 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 != b0) { + return a0 < b0; + } + if (a1 != b1) { + return a1 < b1; + } + return a2 <= 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 != b0) { + return a0 < b0; + } + if (a1 != b1) { + return a1 < b1; + } + return a2 < b2; +} + #endif diff --git a/fpu/softfloat.c b/fpu/softfloat.c index c0fe191f4d..5026f518b0 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); } -/*---------------------------------------------------------------------------- -| 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 >= float_class_qnan is any NaN. @@ -845,6 +791,14 @@ static FloatParts128 *parts128_div(FloatParts128 *a, FloatParts128 *b, #define parts_div(A, B, S) \ PARTS_GENERIC_64_128(div, A)(A, B, S) +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 FloatFmt *f); @@ -1229,6 +1183,186 @@ static int frac256_normalize(FloatParts256 *a) #define frac_normalize(A) FRAC_GENERIC_64_128_256(normalize, A)(A) +static void frac64_modrem(FloatParts64 *a, FloatParts64 *b, uint64_t *mod_quot) +{ + uint64_t a0, a1, b0, t0, t1, q, quot; + int exp_diff = a->exp - b->exp; + int shift; + + a0 = a->frac; + a1 = 0; + + if (exp_diff < -1) { + if (mod_quot) { + *mod_quot = 0; + } + return; + } + if (exp_diff == -1) { + a0 >>= 1; + exp_diff = 0; + } + + b0 = b->frac; + quot = q = b0 <= a0; + if (q) { + a0 -= b0; + } + + exp_diff -= 64; + while (exp_diff > 0) { + q = estimateDiv128To64(a0, a1, b0); + q = 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 -= 62; + quot = (quot << 62) + q; + } + + exp_diff += 64; + if (exp_diff > 0) { + q = estimateDiv128To64(a0, a1, b0); + q = 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 = (exp_diff < 64 ? quot << exp_diff : 0) + q; + } else { + t0 = b0; + t1 = 0; + } + + if (mod_quot) { + *mod_quot = quot; + } else { + sub128(t0, t1, a0, a1, &t0, &t1); + if (lt128(t0, t1, a0, a1) || + (eq128(t0, t1, a0, a1) && (q & 1))) { + a0 = t0; + a1 = t1; + a->sign = !a->sign; + } + } + + if (likely(a0)) { + shift = clz64(a0); + shortShift128Left(a0, a1, shift, &a0, &a1); + } else if (likely(a1)) { + shift = clz64(a1); + a0 = a1 << shift; + a1 = 0; + shift += 64; + } else { + a->cls = float_class_zero; + return; + } + + a->exp = b->exp + exp_diff - shift; + a->frac = a0 | (a1 != 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 = a->exp - b->exp; + int shift; + + a0 = a->frac_hi; + a1 = a->frac_lo; + a2 = 0; + + if (exp_diff < -1) { + if (mod_quot) { + *mod_quot = 0; + } + return; + } + if (exp_diff == -1) { + shift128Right(a0, a1, 1, &a0, &a1); + exp_diff = 0; + } + + b0 = b->frac_hi; + b1 = b->frac_lo; + + quot = q = le128(b0, b1, a0, a1); + if (q) { + sub128(a0, a1, b0, b1, &a0, &a1); + } + + exp_diff -= 64; + while (exp_diff > 0) { + q = estimateDiv128To64(a0, a1, b0); + q = 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 -= 61; + quot = (quot << 61) + q; + } + + exp_diff += 64; + if (exp_diff > 0) { + q = estimateDiv128To64(a0, a1, b0); + q = 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 = (exp_diff < 64 ? quot << exp_diff : 0) + q; + } else { + t0 = b0; + t1 = b1; + t2 = 0; + } + + if (mod_quot) { + *mod_quot = 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 = t0; + a1 = t1; + a2 = t2; + a->sign = !a->sign; + } + } + + if (likely(a0)) { + shift = clz64(a0); + shortShift192Left(a0, a1, a2, shift, &a0, &a1, &a2); + } else if (likely(a1)) { + shift = clz64(a1); + shortShift128Left(a1, a2, shift, &a0, &a1); + a2 = 0; + shift += 64; + } else if (likely(a2)) { + shift = clz64(a2); + a0 = a2 << shift; + a1 = a2 = 0; + shift += 128; + } else { + a->cls = float_class_zero; + return; + } + + a->exp = b->exp + exp_diff - shift; + a->frac_hi = a0; + a->frac_lo = a1 | (a2 != 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 <<= c; @@ -2313,6 +2447,79 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status) return floatx80_round_pack_canonical(pr, status); } +/* + * 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 = 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 = 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 = parts_modrem(&pa, &pb, NULL, status); + + return float128_round_pack_canonical(pr, status); +} + +/* + * Returns the remainder of the extended double-precision floating-point value + * `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 = 0; + if (!floatx80_unpack_canonical(&pa, a, status) || + !floatx80_unpack_canonical(&pb, b, status)) { + return floatx80_default_nan(status); + } + pr = 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 * @@ -4262,300 +4469,6 @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status) return a; } -/*---------------------------------------------------------------------------- -| Normalizes the subnormal single-precision floating-point value represented -| 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 = clz32(aSig) - 8; - *zSigPtr = aSig<float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - roundIncrement = 0x40; - break; - case float_round_to_zero: - roundIncrement = 0; - break; - case float_round_up: - roundIncrement = zSign ? 0 : 0x7f; - break; - case float_round_down: - roundIncrement = zSign ? 0x7f : 0; - break; - case float_round_to_odd: - roundIncrement = zSig & 0x80 ? 0 : 0x7f; - break; - default: - abort(); - break; - } - roundBits = zSig & 0x7F; - if ( 0xFD <= (uint16_t) zExp ) { - if ( ( 0xFD < zExp ) - || ( ( zExp == 0xFD ) - && ( (int32_t) ( zSig + roundIncrement ) < 0 ) ) - ) { - bool overflow_to_inf = roundingMode != float_round_to_odd && - roundIncrement != 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 = status->tininess_before_rounding - || (zExp < -1) - || (zSig + roundIncrement < 0x80000000); - shift32RightJamming( zSig, - zExp, &zSig ); - zExp = 0; - roundBits = zSig & 0x7F; - if (isTiny && roundBits) { - float_raise(float_flag_underflow, status); - } - if (roundingMode == float_round_to_odd) { - /* - * For round-to-odd case, the roundIncrement depends on - * zSig which just changed. - */ - roundIncrement = zSig & 0x80 ? 0 : 0x7f; - } - } - } - if (roundBits) { - float_raise(float_flag_inexact, status); - } - zSig = ( zSig + roundIncrement )>>7; - if (!(roundBits ^ 0x40) && roundNearestEven) { - zSig &= ~1; - } - if ( zSig == 0 ) zExp = 0; - return packFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `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 = clz32(zSig) - 1; - return roundAndPackFloat32(zSign, zExp - shiftCount, zSig<float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - roundIncrement = 0x200; - break; - case float_round_to_zero: - roundIncrement = 0; - break; - case float_round_up: - roundIncrement = zSign ? 0 : 0x3ff; - break; - case float_round_down: - roundIncrement = zSign ? 0x3ff : 0; - break; - case float_round_to_odd: - roundIncrement = (zSig & 0x400) ? 0 : 0x3ff; - break; - default: - abort(); - } - roundBits = zSig & 0x3FF; - if ( 0x7FD <= (uint16_t) zExp ) { - if ( ( 0x7FD < zExp ) - || ( ( zExp == 0x7FD ) - && ( (int64_t) ( zSig + roundIncrement ) < 0 ) ) - ) { - bool overflow_to_inf = roundingMode != float_round_to_odd && - roundIncrement != 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 = status->tininess_before_rounding - || (zExp < -1) - || (zSig + roundIncrement < UINT64_C(0x8000000000000000)); - shift64RightJamming( zSig, - zExp, &zSig ); - zExp = 0; - roundBits = zSig & 0x3FF; - if (isTiny && roundBits) { - float_raise(float_flag_underflow, status); - } - if (roundingMode == float_round_to_odd) { - /* - * For round-to-odd case, the roundIncrement depends on - * zSig which just changed. - */ - roundIncrement = (zSig & 0x400) ? 0 : 0x3ff; - } - } - } - if (roundBits) { - float_raise(float_flag_inexact, status); - } - zSig = ( zSig + roundIncrement )>>10; - if (!(roundBits ^ 0x200) && roundNearestEven) { - zSig &= ~1; - } - if ( zSig == 0 ) zExp = 0; - return packFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `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 = 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 == 0 ) { - shiftCount = clz64(aSig1) - 15; - if ( shiftCount < 0 ) { - *zSig0Ptr = aSig1>>( - shiftCount ); - *zSig1Ptr = aSig1<<( shiftCount & 63 ); - } - else { - *zSig0Ptr = aSig1<float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - increment = ((int64_t)zSig2 < 0); - break; - case float_round_to_zero: - increment = 0; - break; - case float_round_up: - increment = !zSign && zSig2; - break; - case float_round_down: - increment = zSign && zSig2; - break; - case float_round_to_odd: - increment = !(zSig1 & 0x1) && zSig2; - break; - default: - abort(); - } - if ( 0x7FFD <= (uint32_t) zExp ) { - if ( ( 0x7FFD < zExp ) - || ( ( zExp == 0x7FFD ) - && eq128( - UINT64_C(0x0001FFFFFFFFFFFF), - UINT64_C(0xFFFFFFFFFFFFFFFF), - zSig0, - zSig1 - ) - && increment - ) - ) { - float_raise(float_flag_overflow | float_flag_inexact, status); - if ( ( roundingMode == float_round_to_zero ) - || ( zSign && ( roundingMode == float_round_up ) ) - || ( ! zSign && ( roundingMode == float_round_down ) ) - || (roundingMode == 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 = 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 = 0; - if (isTiny && zSig2) { - float_raise(float_flag_underflow, status); - } - switch (roundingMode) { - case float_round_nearest_even: - case float_round_ties_away: - increment = ((int64_t)zSig2 < 0); - break; - case float_round_to_zero: - increment = 0; - break; - case float_round_up: - increment = !zSign && zSig2; - break; - case float_round_down: - increment = zSign && zSig2; - break; - case float_round_to_odd: - increment = !(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 == 0) && roundNearestEven) { - zSig1 &= ~1; - } - } - else { - if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0; - } - return packFloat128( zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| 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'' floating- -| point exponent. -*----------------------------------------------------------------------------*/ - -static float128 normalizeRoundAndPackFloat128(bool zSign, int32_t zExp, - uint64_t zSig0, uint64_t zSig1, - float_status *status) -{ - int8_t shiftCount; - uint64_t zSig2; - - if ( zSig0 == 0 ) { - zSig0 = zSig1; - zSig1 = 0; - zExp -= 64; - } - shiftCount = clz64(zSig0) - 15; - if ( 0 <= shiftCount ) { - zSig2 = 0; - shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); - } - else { - shift128ExtraRightJamming( - zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 ); - } - zExp -= 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 = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - if ( aExp == 0xFF ) { - if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { - return propagateFloat32NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - if ( bExp == 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return a; - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - expDiff = aExp - bExp; - aSig |= 0x00800000; - bSig |= 0x00800000; - if ( expDiff < 32 ) { - aSig <<= 8; - bSig <<= 8; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - aSig >>= 1; - } - q = ( bSig <= aSig ); - if ( q ) aSig -= bSig; - if ( 0 < expDiff ) { - q = ( ( (uint64_t) aSig )<<32 ) / bSig; - q >>= 32 - expDiff; - bSig >>= 2; - aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; - } - else { - aSig >>= 2; - bSig >>= 2; - } - } - else { - if ( bSig <= aSig ) aSig -= bSig; - aSig64 = ( (uint64_t) aSig )<<40; - bSig64 = ( (uint64_t) bSig )<<40; - expDiff -= 64; - while ( 0 < expDiff ) { - q64 = estimateDiv128To64( aSig64, 0, bSig64 ); - q64 = ( 2 < q64 ) ? q64 - 2 : 0; - aSig64 = - ( ( bSig * q64 )<<38 ); - expDiff -= 62; - } - expDiff += 64; - q64 = estimateDiv128To64( aSig64, 0, bSig64 ); - q64 = ( 2 < q64 ) ? q64 - 2 : 0; - q = q64>>( 64 - expDiff ); - bSig <<= 6; - aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q; - } - do { - alternateASig = aSig; - ++q; - aSig -= bSig; - } while ( 0 <= (int32_t) aSig ); - sigMean = aSig + alternateASig; - if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { - aSig = alternateASig; - } - zSign = ( (int32_t) aSig < 0 ); - if ( zSign ) aSig = - aSig; - return normalizeRoundAndPackFloat32(aSign ^ zSign, bExp, aSig, status); -} - - - /*---------------------------------------------------------------------------- | Returns the binary exponential of the single-precision floating-point value | `a'. The operation is performed according to the IEC/IEEE Standard for @@ -5273,94 +4804,6 @@ float32 float32_exp2(float32 a, float_status *status) return float32_round_pack_canonical(&rp, status); } -/*---------------------------------------------------------------------------- -| 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 = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - if ( aExp == 0x7FF ) { - if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { - return propagateFloat64NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - if ( bExp == 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return a; - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - expDiff = aExp - bExp; - aSig = (aSig | UINT64_C(0x0010000000000000)) << 11; - bSig = (bSig | UINT64_C(0x0010000000000000)) << 11; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - aSig >>= 1; - } - q = ( bSig <= aSig ); - if ( q ) aSig -= bSig; - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig, 0, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - aSig = - ( ( bSig>>2 ) * q ); - expDiff -= 62; - } - expDiff += 64; - if ( 0 < expDiff ) { - q = estimateDiv128To64( aSig, 0, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - q >>= 64 - expDiff; - bSig >>= 2; - aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; - } - else { - aSig >>= 2; - bSig >>= 2; - } - do { - alternateASig = aSig; - ++q; - aSig -= bSig; - } while ( 0 <= (int64_t) aSig ); - sigMean = aSig + alternateASig; - if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { - aSig = alternateASig; - } - zSign = ( (int64_t) aSig < 0 ); - if ( zSign ) aSig = - 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 @@ -5379,266 +4822,6 @@ floatx80 floatx80_round(floatx80 a, float_status *status) return floatx80_round_pack_canonical(&p, status); } -/*---------------------------------------------------------------------------- -| Returns the remainder of the extended 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, -| if 'mod' is false; if 'mod' is true, return the remainder based on truncating -| 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 *quotient, - 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 = 0; - if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) { - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - aSig0 = extractFloatx80Frac( a ); - aExpOrig = aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - if ( aExp == 0x7FFF ) { - if ( (uint64_t) ( aSig0<<1 ) - || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) { - return propagateFloatx80NaN(a, b, status); - } - goto invalid; - } - if ( bExp == 0x7FFF ) { - if ((uint64_t)(bSig << 1)) { - return propagateFloatx80NaN(a, b, status); - } - if (aExp == 0 && aSig0 >> 63) { - /* - * Pseudo-denormal argument must be returned in normalized - * form. - */ - return packFloatx80(aSign, 1, aSig0); - } - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - invalid: - float_raise(float_flag_invalid, status); - return floatx80_default_nan(status); - } - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig0 == 0 ) return a; - normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); - } - zSign = aSign; - expDiff = aExp - bExp; - aSig1 = 0; - if ( expDiff < 0 ) { - if ( mod || expDiff < -1 ) { - if (aExp == 1 && aExpOrig == 0) { - /* - * Pseudo-denormal argument must be returned in - * normalized form. - */ - return packFloatx80(aSign, aExp, aSig0); - } - return a; - } - shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); - expDiff = 0; - } - *quotient = q = ( bSig <= aSig0 ); - if ( q ) aSig0 -= bSig; - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - mul64To128( bSig, q, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 ); - expDiff -= 62; - *quotient <<= 62; - *quotient += q; - } - expDiff += 64; - if ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - q >>= 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 <<= expDiff; - } else { - *quotient = 0; - } - *quotient += q; - } - else { - term1 = 0; - term0 = bSig; - } - if (!mod) { - sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 ); - if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) - || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 ) - && ( q & 1 ) ) - ) { - aSig0 = alternateASig0; - aSig1 = alternateASig1; - zSign = ! zSign; - ++*quotient; - } - } - return - normalizeRoundAndPackFloatx80( - floatx80_precision_x, zSign, bExp + expDiff, aSig0, aSig1, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the extended 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. -*----------------------------------------------------------------------------*/ - -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 value -| `a' with respect to the corresponding value `b', with the quotient truncated -| 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 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - if ( aExp == 0x7FFF ) { - if ( ( aSig0 | aSig1 ) - || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { - return propagateFloat128NaN(a, b, status); - } - goto invalid; - } - if ( bExp == 0x7FFF ) { - if (bSig0 | bSig1) { - return propagateFloat128NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - if ( ( bSig0 | bSig1 ) == 0 ) { - invalid: - float_raise(float_flag_invalid, status); - return float128_default_nan(status); - } - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return a; - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - expDiff = 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 = le128( bSig0, bSig1, aSig0, aSig1 ); - if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig0 ); - q = ( 4 < q ) ? q - 4 : 0; - mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); - shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero ); - shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero ); - sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 ); - expDiff -= 61; - } - if ( -64 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig0 ); - q = ( 4 < q ) ? q - 4 : 0; - q >>= - expDiff; - shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); - expDiff += 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 = aSig0; - alternateASig1 = aSig1; - ++q; - sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - } while ( 0 <= (int64_t) aSig0 ); - add128( - aSig0, aSig1, alternateASig0, alternateASig1, (uint64_t *)&sigMean0, &sigMean1 ); - if ( ( sigMean0 < 0 ) - || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { - aSig0 = alternateASig0; - aSig1 = alternateASig1; - } - zSign = ( (int64_t) aSig0 < 0 ); - if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); - return normalizeRoundAndPackFloat128(aSign ^ zSign, bExp - 4, 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 d1bd5c6edf..dddee92d6e 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -626,6 +626,40 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatPartsN *b, return a; } +/* + * 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 = float_cmask(a->cls) | float_cmask(b->cls); + + if (likely(ab_mask == float_cmask_normal)) { + frac_modrem(a, b, mod_quot); + return a; + } + + if (mod_quot) { + *mod_quot = 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 == float_class_inf || b->cls == float_class_zero) { + float_raise(float_flag_invalid, s); + parts_default_nan(a, s); + return a; + } + + /* N % Inf; 0 % N */ + g_assert(b->cls == float_class_inf || a->cls == float_class_zero); + 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 } -/*---------------------------------------------------------------------------- -| Takes two single-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 float32 propagateFloat32NaN(float32 a, float32 b, float_status *status) -{ - bool aIsLargerSignificand; - uint32_t av, bv; - FloatClass a_cls, b_cls; - - /* This is not complete, but is good enough for pickNaN. */ - a_cls = (!float32_is_any_nan(a) - ? float_class_normal - : float32_is_signaling_nan(a, status) - ? float_class_snan - : float_class_qnan); - b_cls = (!float32_is_any_nan(b) - ? float_class_normal - : float32_is_signaling_nan(b, status) - ? float_class_snan - : float_class_qnan); - - av = float32_val(a); - bv = 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 = 0; - } else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) { - aIsLargerSignificand = 1; - } else { - aIsLargerSignificand = (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) } } -/*---------------------------------------------------------------------------- -| Takes two double-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 float64 propagateFloat64NaN(float64 a, float64 b, float_status *status) -{ - bool aIsLargerSignificand; - uint64_t av, bv; - FloatClass a_cls, b_cls; - - /* This is not complete, but is good enough for pickNaN. */ - a_cls = (!float64_is_any_nan(a) - ? float_class_normal - : float64_is_signaling_nan(a, status) - ? float_class_snan - : float_class_qnan); - b_cls = (!float64_is_any_nan(b) - ? float_class_normal - : float64_is_signaling_nan(b, status) - ? float_class_snan - : float_class_qnan); - - av = float64_val(a); - bv = 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 = 0; - } else if ((uint64_t)(bv << 1) < (uint64_t)(av << 1)) { - aIsLargerSignificand = 1; - } else { - aIsLargerSignificand = (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_status *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 = (!float128_is_any_nan(a) - ? float_class_normal - : float128_is_signaling_nan(a, status) - ? float_class_snan - : float_class_qnan); - b_cls = (!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 = 0; - } else if (lt128(b.high << 1, b.low, a.high << 1, a.low)) { - aIsLargerSignificand = 1; - } else { - aIsLargerSignificand = (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; - } -} From patchwork Thu Jun 3 21:41:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453329 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp632296jao; Thu, 3 Jun 2021 14:53:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwFMR1MlgHk37qFtOZddv6es5VxBLkDr0CCMu4EzJic0Rs2WN1i5/3meggJaMUaTI20zEdb X-Received: by 2002:a05:6602:8c1:: with SMTP id h1mr1103125ioz.33.1622757201825; Thu, 03 Jun 2021 14:53:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757201; cv=none; d=google.com; s=arc-20160816; b=IjpyLUKoJFjiCo2SG62vT8ws4OJDXWltlbTWwGX6WZDpcuV5Dr6FzbKO6LHyMQy3Rx EUqP1nbw7jqhUHtZ29TEHiNzSzcSYFnKL+pXrtK984iK0mgijdxHUtO9vubVlPpMB0G6 D2H9aIepQAO2PCG8IvU/ZNa3DQc7kbDyar7SXHTMCC9wkjOGok+UT5EAVxhut6zTcuU3 WeSNVHE/M+w/XTwIP38bSI7+Omxqnjt+YjTJiOWFM+iDuNDnsPKLONz33ZkSKhyIArYv l2iaB6imjZxrZ4mJ3WzxUsG3U5ltqpmR1KYVgrgwpktos/RvGUyGEeLgnE5o5FAeIFtA agGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=0sbWGfdi+vZU0+T2mHM/iN4YQ8XRnXrlumJZuqrhiwA=; b=XY8ghzWwTQN2nxBJwxJpoKNp83QFfNtX5ZQkXxU/gUQcTKzFirAb2EYyl4IbMEWSLq S5xpxKv0Lnw+M3FayVVUu2Mk/4YZK54EKmV5JMKdOpwKiuogh2ITvRKP41gWsp7N0UIO tmqX8CUYVf+tERhSkMvmAM5LU2u2sM2gZoTMHpaABnpqGfURzvU1ktE8dpkGSuQX2VlF bCLgWpJGXK9dG0bbmzC/4l3LBuG72/xUrlq86jKGmkO9hJDD5OW7SwouGf9YvV01KDes vxtt+bb/pEUjQe1pCLDmNpflvWm+A4amQVZnCuRj4S0UHWn075i8uMp/GohxGujZ/k0+ Sl1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=HDrhq4+v; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id q7si5373756iow.93.2021.06.03.14.53.21 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:53:21 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=HDrhq4+v; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:37626 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovHF-00014s-8r for patch@linaro.org; Thu, 03 Jun 2021 17:53:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58558) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6H-0002xL-2G for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:01 -0400 Received: from mail-pg1-x52e.google.com ([2607:f8b0:4864:20::52e]:34473) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov68-0001BB-Rm for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:00 -0400 Received: by mail-pg1-x52e.google.com with SMTP id l1so6188282pgm.1 for ; Thu, 03 Jun 2021 14:41:51 -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=HDrhq4+vlG3C5GOmc5mI2ax4oOXMXjxNVVGWj4BVRttcXz6RsZ4Uh3eQirI28jZjrC mAvjckDWm6Q9yPj95Rpuikvth498KEbizIAbukspe5m7UkMur+fMnox6qQHRG9eTpIDz C/p0+3H4aXpDP30YtBZFkxE+O2kfrD26y3A94qf9W0l0GpxVE1LyPG3hY+fFc4L0SPdv mQbGFB2q6be1NI8VBEyfwtguDYIm+sUKMNELFU5psAInh7qxblGxwfuem/Dbs5OHgL1q 3qWeHDmvjSdZw2hVhX1u2jhpa+7aiQUuTZ6sPB4w/kP5cO+qYlD7ZN9rPEz5168MEKAi EWmw== 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=cw0Ev0sR9eci6LjrV1SotVbs2Vbhji+p2+ZFL4INJ+ab2s5zMY3B2YcwmKXieouoLN w6CKBWonSJcmu5ysv3hcmankubyzMe3PhplV9bUCo370uZYZHWi31hxPFP0BlFWG0/Vi AKfylOUM2+KKI5pljGR2ysd1YKa/yLJ0gGYSVNloRdWhT46v4S17+RxsqiSrIVIDH/Av ItwI/ogcp66rYRmBp7SzDHo6hI+1GdmZsnXjQjB5+2ey+KVwvWzfKNarDDL6eV2uqdGA 8sborcvxIjeYje/Q8Klfg5B5B2bVbeJEVIayBwELOmkLAZTIvdU+tV8+ic9SW0u1+/Bx 8a/g== X-Gm-Message-State: AOAM530tb1q2UfU+AMfVHpKh1pDiJuAhTSSI0RsPUQHXu6vZQTD25YLT y6syyrAe6h/Y3+BnF/sZmFOnMKRY9F79Qw== X-Received: by 2002:a63:8f4a:: with SMTP id r10mr1494928pgn.242.1622756511005; Thu, 03 Jun 2021 14:41:51 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:50 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 28/29] tests/fp: Enable more tests Date: Thu, 3 Jun 2021 14:41:30 -0700 Message-Id: <20210603214131.629841-29-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52e; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52e.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée 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ée 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(-) -- 2.25.1 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 #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 = { '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 = { '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 = { 'eq_signaling' : 'compare', @@ -602,24 +604,20 @@ fptest_args = ['-s', '-l', '1'] fptest_rounding_args = ['-r', 'all'] # 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 -# FIXME: extF80_{lt_quiet, rem} (broken), -# extF80_{mulAdd} (missing) foreach k, v : softfloat_tests - extF80_broken = ['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 + From patchwork Thu Jun 3 21:41:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 453333 Delivered-To: patch@linaro.org Received: by 2002:a02:c735:0:0:0:0:0 with SMTP id h21csp633639jao; Thu, 3 Jun 2021 14:55:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxMhRSdS7CoaO9EOHCryY6oMSrw4mLj6cYxj1kV1xtui8hDUKwTAiVkl54U5I+b0Az1gRNV X-Received: by 2002:a92:d944:: with SMTP id l4mr1305099ilq.244.1622757350254; Thu, 03 Jun 2021 14:55:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622757350; cv=none; d=google.com; s=arc-20160816; b=erJvtAKrgxG0SylmlY8dFlxDY3sAH9CTqr7IHhwpUrnTIUlTfFMtX0Ifh9fAXp5Xk5 qM/1HmzYCF6ahRWavgCK5f3K47l4KcSll0woCEHUYdHW1eW0L6vRbVdPzTsAxw5SMqn0 cLkHZNT/aQ+vfsBS1jbPcNOqmbl+yIxQkVqyH84EHOY+2Mqf+v73/VY+98GKvu4IWZ1I 6SAuv4m7Qsl+45nCKVH+9KogwcDgy3b64YW/7dCYKrYxRTTBIK8VzuJWVJ8B+sNYjfMo qYyXkQhDlkeu6s5C62yYD/mM14+7LySMb8aqnUpxL20L3SulpLDAl6Pb1/jeGc47iLep lloA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=ori3kQInJnhP2zXvcphOploFKdQaCYd2KPPI3jAHsoY=; b=mIXmnsMMb39x9XhpxjRaxEGIryp8LWUOfn+KdfoGFqmCwfs47OT70JF0nkTlDCDREc BU5j2Vt9EXOGwWEQvPQ4Kfde8rXS9yUtLoBlYR9PbYhuOgh/zmQcygwiFb1FBVQmcFVS 5nT9I6xGT5m84hgWKRstiK0nOKVaykhNQjQpQEzhRylgfo2vT5lqReodhrTxKynEjTUV hBolfZtT/FuiZXd3eGpFJ06zZYg0IO7sxfiFCIPhYgNkO+xWLyoSNBRmEDBjcHcurgkK HDqwpTOuND/tBilTRj5ZfM2QHYA6fqaS6XjUrM3c2UqA9XQTUqy2JiU4LHzMXWGE478b Cljg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=boTVXF1O; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id j15si6165379jak.25.2021.06.03.14.55.50 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jun 2021 14:55:50 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=boTVXF1O; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:50060 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lovJd-0000tR-OH for patch@linaro.org; Thu, 03 Jun 2021 17:55:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58564) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lov6I-00031Q-0E for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:02 -0400 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]:51717) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lov68-0001BK-SU for qemu-devel@nongnu.org; Thu, 03 Jun 2021 17:42:01 -0400 Received: by mail-pj1-x1032.google.com with SMTP id k5so4450753pjj.1 for ; Thu, 03 Jun 2021 14:41:52 -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=ori3kQInJnhP2zXvcphOploFKdQaCYd2KPPI3jAHsoY=; b=boTVXF1OxYGm20ZWUQdw9ZBqE2YGnoJKqBela9vUfdP4AYOsE9cY88A5iCOH3Fnk2M jWbQILkygqIMezBp+y5BSlIOT/11JUrd9Ureos/H1mAodpYk6CRctGsgVb6pLK6lGmgk 2Cy7bnaEKAwqWsXDKpsQdh2SSNS3Vk3ll/CYE6rcKFZtP20EYBJPIPQ/Of+smOzzPpsD g++gC6JTD79V2cXM8Fmf39Di4sGfwioFZGyu8fHBaZcE9koC+t+3l3AwcN58hF12s9qE 5A1L1FYjrpFsL0QlJ76OdbW6oQcXA5gewI6BnljBP6aTLjfcsaW40m6AFM/GFhIJJ5/q WsYw== 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=ori3kQInJnhP2zXvcphOploFKdQaCYd2KPPI3jAHsoY=; b=JcdkqNKDs3iyAe3LK7dryiSE+tRCw683MWakRw/MRHSbxzQSjZ7sj2Zvhcjq8rZLRl KkPwOcQ8Sw0162ylDT7s7BTs3X1zaL6XhujwVesJ76nWyfG3Sce2KIKT+iYvH/YE4+CI 6yzuCE+eX4KNb+FdTMt2XzD1Cj54xj7IAkzYLYnlspeYK/eBDb66F04Fomhsx3VgiCS8 Iau0osdBshx8P8+TkvU1hPjRXw/7wlUz3U6182Va4cwRBotUdVcOrjYvEudVcP9GNv6R KjbcTtdVP9IWItbVtbswIc+9/rOAf42XNKYZm5TT3sy3q7WvORpZor2c+JJxKWgTvVeU PX1g== X-Gm-Message-State: AOAM532X7ik+5TEE1PUrLbdq6giudb0e2ZewHxX5OSmOdG4DfgTkQXpf ZcsoICeapHKiRujgrJaWq2YItnqyJSmMaw== X-Received: by 2002:a17:90a:b885:: with SMTP id o5mr13366707pjr.91.1622756511533; Thu, 03 Jun 2021 14:41:51 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id p65sm40115pfb.62.2021.06.03.14.41.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 14:41:51 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PULL 29/29] softfloat: Use hard-float for {u}int64_to_float{32, 64} Date: Thu, 3 Jun 2021 14:41:31 -0700 Message-Id: <20210603214131.629841-30-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210603214131.629841-1-richard.henderson@linaro.org> References: <20210603214131.629841-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1032; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1032.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: =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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 Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) -- 2.25.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 5026f518b0..1cb162882b 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; + /* Without scaling, there are no overflow concerns. */ + if (likely(scale == 0) && can_use_fpu(status)) { + union_float32 ur; + ur.h = 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; + /* Without scaling, there are no overflow concerns. */ + if (likely(scale == 0) && can_use_fpu(status)) { + union_float64 ur; + ur.h = 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 scale, float_status *status) { FloatParts64 p; + /* Without scaling, there are no overflow concerns. */ + if (likely(scale == 0) && can_use_fpu(status)) { + union_float32 ur; + ur.h = 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 scale, float_status *status) { FloatParts64 p; + /* Without scaling, there are no overflow concerns. */ + if (likely(scale == 0) && can_use_fpu(status)) { + union_float64 ur; + ur.h = a; + return ur.s; + } + parts_uint_to_float(&p, a, scale, status); return float64_round_pack_canonical(&p, status); }