From patchwork Tue May 25 15:06:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447285 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4409644jac; Tue, 25 May 2021 09:07:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz2j9knOroldKBgWATCgBuUlEbUYTRMK5T7sTMrWtmYBDxqnyq+pmPOxBxyGeOj2eynl6rM X-Received: by 2002:aa7:ca4d:: with SMTP id j13mr32250184edt.158.1621958850784; Tue, 25 May 2021 09:07:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621958850; cv=none; d=google.com; s=arc-20160816; b=0KUXs1d8L0oWlUWbV8vHrbXAZ2T8htN+Ikxqhir1EWNlVJ1vR3P47AkBSw2UgveoAW WRf4ffoMaVOWBxd9AoQhEklOFWoRERj7MOf19XYnSO0I9bj3dlcYAqau+QDI/0jLEQQq 7u54U1hSwGlwJWn2VFAoYUpccowpsJLiCJRxs7wDDwlbfyMvJNYoU5qhRFOTT1cPGSbp py29Yv64dsw/P5B397ZNQKVxzyi4JLc8n1f8gEeV5KQ9SXxOWIjP9ASBokKqDR5zEHLa JsKSEAHOTVpF+4GaeEYzTqC6qq7ivRCAe9zQFpuvHC3JiCIcE9VUQrW6ii3ant4tvh+B VXxg== 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=/ttITD/09WEgyyZYjSew5EYoec5er/8eI+cVyDIB5nE=; b=jQmOekpNB7/qnsPnRRfY64MPbl9lTBw1+sUm7MixHcKZSuJ79/cKzhPYt1VjThs0No /6BJsde6GNvYtsRg7klD7R6jqlbHcysP+5tXhPugxHZ8Tu13O7f9I1ECqcOjKkY4i853 vCZ5g7YH+t5u7/VfCHtCoA+CWRIUx0WyJF7iN8wxQE16uGKlapVmTPYSxq6l5VkNnHwC fhyZHQL8nh3PyEXfp2c23lnhQFQueW8yeXMu4hbFi8qDCfaUi58XzTxepE1DtXylP35F 5FmWTb0gAp01enRAb+j4kB2Yzzm8CEU0QWHpYNT02ZXlbVeRJH9eLEUEKJi1G+M3QoEw glOg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=daKKFRRc; 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 ga4si13488151ejc.497.2021.05.25.09.07.30 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:07:30 -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=daKKFRRc; 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]:51948 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZab-0003i8-N6 for patch@linaro.org; Tue, 25 May 2021 12:07:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60250) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeK-0001Po-B7 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:16 -0400 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]:38547) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeE-0006cx-91 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:16 -0400 Received: by mail-pl1-x629.google.com with SMTP id 69so16501246plc.5 for ; Tue, 25 May 2021 08:07:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/ttITD/09WEgyyZYjSew5EYoec5er/8eI+cVyDIB5nE=; b=daKKFRRcLaywZWL15AeJKoX+ew8njV0BnP1TXxDXjfrXUCu6nD4LcEOy/AuqsFNeGl WzZt/F+92LNsh95QeW818mV+6FxyRRA/xBkcOPyhDtPBid2IHch04WWaPFBCtJOCNkfi jmThx12PkJBXhyXyIL98JnFGG3hE/nOdLioNyDvZoqaldaUVTb2hTtLxXGYsl6EIorAI OMO/o3bOR/6+PP4lfFtikIE+iE0tNVTLs7dTEUtJs/AEZTuG8TBIyu4PNlVa8F5OyPq3 Ol3xm7wTDScwmUWfTmtoBtZFVOhXV5A6S2bN2KU/PiQkMdji4xnBtQv32AtU7FgnO6Lw zwdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/ttITD/09WEgyyZYjSew5EYoec5er/8eI+cVyDIB5nE=; b=kgDPRhgmaeEHuO4R61d5M1mbNSTZmHFSc4YubMULTaJrzDHbh4HqAV3Ug5ASH8yKCD NAZ+aIshBJxV9hFwSOWqqR3usDHyJUlgVjldmDLJAUo2vqd7aVKqStajm0eT5acQRLtG qeifIs5/xD8IrCi26rqixJtiipkp2usHxb51MrivSvJDdCsvGH3acJztaxWm6wfL51CW zpE84N9kFZOPMRKSvZQ4hzJfZTcX/2FHBOaXT2CBsGu0lmCDWNMuUv548+4p+xQgU5cT e+sAzjNge6i+Q53J+C3+SmgZctXL42cecRSzmQobtkwgEl8rtlkkD+551WRCSJo0skL8 qhmw== X-Gm-Message-State: AOAM532dTzvbuKRXJgCNoWYswktN1ZY6fv0Jcu5mLUDqJPZdjK4rhJti pYPhFl7vYxp9XPqcMPQrpkONblEfiyWVSg== X-Received: by 2002:a17:902:a3c3:b029:f0:b297:7778 with SMTP id q3-20020a170902a3c3b02900f0b2977778mr31233860plb.16.1621955228305; Tue, 25 May 2021 08:07:08 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:07 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 01/28] softfloat: Move round_to_uint_and_pack to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:39 -0700 Message-Id: <20210525150706.294968-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::629; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x629.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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. 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 Reviewed-by: Alex Bennée 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 a897a5a743..c6e327547f 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -761,7 +761,7 @@ static void partsN(round_to_int)(FloatPartsN *a, 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) @@ -815,3 +815,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 Tue May 25 15:06:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447306 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4423927jac; Tue, 25 May 2021 09:23:24 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw46hIj3pwZABVlJJ94pbWeAn7qZPccEIrrL4tpAsnX6RCFwYuOeSJ8ro1C60WxbNPDCC10 X-Received: by 2002:a17:906:680d:: with SMTP id k13mr29806882ejr.371.1621959804159; Tue, 25 May 2021 09:23:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959804; cv=none; d=google.com; s=arc-20160816; b=iZyynWZrxBd2YBHGt4pnaf/ZdwhF1cSTAHY5r9EPXoFPoNfmtFG6e6ANTesZWLRNk4 L2uiBGVzKFG+Q31An5IEMrqDza6vCtcszBkvYzS3EoslEjNnMwqV7fjOHDHAMUK+F0bR zhKLHNKu03Kb01CNfmoaCKp2HTmaq/RTzHA5ta3xOHmg9VSu/eLlKtT+/rGSXs5hCSqz FxfTWut2sCFe5VI++87vD79JXZyx9p0dh2XO4TxUmoC+zu4V1E4u17O7kOqMD7aPTJgm IOx3uV5mSmhjD8Y+EOW1Ra4TsKsNpYUJb/oyz4ZPpOEIr9aYfhusmgpkrmavrghXlgpn c2iw== 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=rGDd4IrgxvYUwN/P21Hl5FXEtH+AR/o/zuzvqPcST80=; b=OR5rNYuKZIYMKIMD9YBX+CoGoG8YhrNs/qnSQS8N4pOCDk94QKUjQ33bVLIzT0aR39 6z1J1XXs8HLF5HrhWiwef0+0yAeBbIlu0BEjmBDMhUuJV9ZKUyHyPFxf8FsrKeZg0biN /SVxkYKTpDWy5lR+SD27KXIRySrrolCLRiNEhWsYxuGzE8Mo/ysvbxKx93ONGfEGV2oK 2fAxASTTxEyhQqzpenYFTl+c7Ur8XFrple6ueQH2wT/Awe/AXpCbJmvW0WKmRxchpUtV 2veMgpAwXJHcSl1ZnNISfVlKzKRMHT0smlkSXgLgRNsQ4i1JBtQVCZziXi1NJKCrtEsQ TmWg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=I8yzv1wq; 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 l18si16160564edt.366.2021.05.25.09.23.23 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:23:24 -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=I8yzv1wq; 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]:43384 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZpz-00044c-03 for patch@linaro.org; Tue, 25 May 2021 12:23:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60288) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeO-0001Uw-4d for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:20 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]:52803) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeE-0006d1-CZ for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:19 -0400 Received: by mail-pj1-x102c.google.com with SMTP id q6so17013435pjj.2 for ; Tue, 25 May 2021 08:07:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rGDd4IrgxvYUwN/P21Hl5FXEtH+AR/o/zuzvqPcST80=; b=I8yzv1wq757NIPDwnMio/+AxYdSBxOvyRi1A8SdCyrBIRMzofpJIH4jJznULi6Vsbo JSCpuFSpOVbkXQRD9XKOTAdEJua12Em2CBdESEVs9eQZfa5Z6k7ddAwl1mcenODuApIm njL+AdBgLEI45MeW1HRKOGbX1XVAivEpf4WqUhTnHLVs23yCVt039Rf/2LLWJTGX3Gwc TRbqYLo7p1FexSRvzhHUEW+9DhrpiN9mFGp87dC6BEaY0ZtyWxeqfDRYonl75wz44srm Ea9JVgWOrTpIqQlEABpCKHFb649z1JsPZBvj2PgVSBd+DGd3eXvR3IlPnwLP02ON9/SJ 41eQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rGDd4IrgxvYUwN/P21Hl5FXEtH+AR/o/zuzvqPcST80=; b=iSbX3XBdVmfuG+jR5X1M5BhEfcLc+ZFKzZ+j/Z+LOAAFA7YbrNhrio+/ECJ8r3ZWf1 KWXQwmTdwzCotpnmm3c0XOKRf152xYYFUTNdTGkymLDhCndExvgBuRQZE7XjVaFjD0nt LvGzQbfVpgBG/2DDK8Lly4I1KjKg4CTl3i8hpaOhoiDV8ulfqm1rRO+FGLkkSbLedvYn giuIBmTXuIS+NLLluDFvY7GPy+UQJPyzF3VjvpMRNsk/0y7e960rIfNMZaHp1lyC3ZOR XTSfE0nXNoc4wtKsqNRlbTAX9h9R36pUCEnvIAXduV1ID85uM99XPOJlCaMsCd+rzEzb qCQw== X-Gm-Message-State: AOAM531Im/MJBazkfN9MVf53nEy0Lj6CvdNvH6I31gV8XdbCW9hUieDq 6zxDaUbmSELi2sQVVA0rYhSWB7vb1CUHvQ== X-Received: by 2002:a17:90a:9d88:: with SMTP id k8mr5235831pjp.64.1621955229060; Tue, 25 May 2021 08:07:09 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:08 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 02/28] softfloat: Move int_to_float to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:40 -0700 Message-Id: <20210525150706.294968-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Rename to parts$N_sint_to_float. Reimplement int{32,64}_to_float128 with FloatParts128. 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 Reviewed-by: David Hildenbrand Reviewed-by: Alex Bennée 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 Tue May 25 15:06:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447302 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4422155jac; Tue, 25 May 2021 09:21:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyJh98pVkE+il24gthdjLzJ/Ayd9TFPN9XjuLDUI5ksEZpLyTCnOgdxtK5WoSgaGp4Rw4Nl X-Received: by 2002:aa7:c718:: with SMTP id i24mr32534013edq.43.1621959676620; Tue, 25 May 2021 09:21:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959676; cv=none; d=google.com; s=arc-20160816; b=wxCoa7/3a2Gza8ucCujhL6oDZrY+JduNuRHlZus4xiTzzFm/WywkDmtwZ1XZtCiz/u dE7FYrKnW5xdgCLI3B2NvMsZRHmI0f9bX8MxdP2huYkrRfdjH+/j0+xxhjBlVhAwHrk5 Wb+gB2GN+3oGuVZEV8AWKd1GFeRnN/PyIOvvk4EK7SxOH4qEY3T9YX1Uo9QF0TtdzmGh b6kBYaEH5jPRDDKWuOCCTV7hEdGVD1CU8ZHuOgED/GygZFrrZ+wnVDqQLaCjK3mrAi2k 7KM6FXPRUUCZ80cFtPxVb1/ifz/jzRnSVW4Qy/HgEPkjlogIAtBL2AJ5fl5a61JW0S1t FAPQ== 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=uI7SP4Waz/iN5MUyXkTADhvd6hV2rHFBbWY60pbiMEg=; b=xNh/h3zKTJj1Lp55eYmJiBLg+jr3FSuxcF7kSB5jRrPT04M6gDAXFLBGz8gzs4u7Yi j6CzuSzkT7LZ3R7yHElcZyQkhqPh4H4fIWVt3jeZum2f7bLPcdAOqhSr1mkSHXMXdsk5 oPT+XpLPV10bSHu267MZrS/6EL9qY5I9YEBqa+ciBXE9QvZ1nmUtG16hriOOyJVE0GLK jzCfEVD+n+OVMEm7K9fAGOM05MA/cvus2uTA9Tz5mO/unN2GOW4IDGelGA7wNX3KZoZp 3cPl/yYMceUiGjKH9b09XrDQGfmVJyd0Qv22xptZYMRPrWgr5Bv75+MVeeUZMkTviDc0 DGMg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DqwIV3hV; 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 k13si16554133eja.2.2021.05.25.09.21.16 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:21: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=DqwIV3hV; 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]:37364 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZnv-0008VD-Ff for patch@linaro.org; Tue, 25 May 2021 12:21:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60274) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeN-0001TU-J4 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:19 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]:46670) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeG-0006d6-9p for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:18 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d20so2211826pls.13 for ; Tue, 25 May 2021 08:07:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uI7SP4Waz/iN5MUyXkTADhvd6hV2rHFBbWY60pbiMEg=; b=DqwIV3hV80PE6LktFCa/zxeQDADQnrHgykJdYu4ZGqWQxmyLgctJJJoxUx+U4OYUgS VqBM/1fNz478sKGdYktPrJ86j5BP2NC1KrlsGKALyLZDHju3AJddPZPUekrbRfymQPzI 9QgxXT33g2WSuLTZEyXSXBNpFcPKuUscliYmrD3a25KC9vV1p0njREkbkn54HUGuYHDt Yhe0kG4sijOJ/uITsHkZa7fc3YQm3gT6/DmfJMvHxB4tugLcJKldYcHtRmlJSYNm15Gd hXtLJSjUsnHyni/ETEUAe75SEoRwgjzEBPx6ZTlUNfuj/BbSOez/9llZs54dHKAKMa5t hqTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uI7SP4Waz/iN5MUyXkTADhvd6hV2rHFBbWY60pbiMEg=; b=MMewIE1IZaR7p51MjfpqF2XU86oc9OqcoWqczbivjG3T51s40OWsocOJWq+2rXZxez TtWOfRNUW/6YN2mLqMEfijDvtFqdiFcUFBF7rfcjQKWyOEFRXyo6JSyzvw9fcOhIj2oI KFj0T/R18bn+yNMWftcN9o6ku7kDg15NnLPObOftSA2ggaaUj4C8Jf0BYg//sJtCTIsA fRpmEOHxcId+cw0GSwgv2dp+ksyf8EgmQ4yZjgLCh3lPNtIqdfe31Rg6fEeBV+RiKW+P 2DHYM0vDOlDv0GbvFARfa7WqlWFr6f4Lvpk4Pq6w2yu2ReH12j/Gakf3M+NWkVa44hbI w1/g== X-Gm-Message-State: AOAM531+IJBk6acL5geZiDPVw2DahXgKVcegspNMslyA3qUm4pQO3NFX 12M8gHeM0RTXzi2vA57gevfEye4kacYubg== X-Received: by 2002:a17:902:b78a:b029:fc:f326:7de0 with SMTP id e10-20020a170902b78ab02900fcf3267de0mr318833pls.28.1621955229528; Tue, 25 May 2021 08:07:09 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:09 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 03/28] softfloat: Move uint_to_float to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:41 -0700 Message-Id: <20210525150706.294968-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Rename to parts$N_uint_to_float. Reimplement uint64_to_float128 with FloatParts128. 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 Reviewed-by: David Hildenbrand Reviewed-by: Alex Bennée 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 8102de1307..f3c4f8c8d2 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -913,3 +913,26 @@ static void partsN(sint_to_float)(FloatPartsN *p, 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 Tue May 25 15:06:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447299 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4420017jac; Tue, 25 May 2021 09:18:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx4vpyPvKri9yPCSLJ5iVGJotWoDQke0fOWO93u6G+7RpJvXd6xiEPpgLub4ZbiCm8GKm6B X-Received: by 2002:a17:906:f2ca:: with SMTP id gz10mr30400913ejb.317.1621959532150; Tue, 25 May 2021 09:18:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959532; cv=none; d=google.com; s=arc-20160816; b=jKri3U37Hi8BuNBu8aDK1R2hSDW5/OdSLiW9Yat0FPH9kSVwO+S243WShXcDdo2bm1 85FmCvh2bUQxEcAB5HSZiyQeMTkBPaCmcL/8heCIAyON47enP03j1QApUWnMncwCI6qH Oesl3k+oK7JdTuq/CxD7czA6K03e0DKJEx6i4P7xgbmBlPvJuH8eoCfYjMh9u3W80qPY OUX6M07WvITHZufwZpz2GIS88iSK9ypWaRzBujEIkTWchG4kRIy5/N5IxYRzR6qGrfEM fwwLbYIoVMPhhhfXYDONpSQkptmJVb/PCIKEu11kEW83SwL07dwky88/mViAYP5rXQls aq7Q== 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=cwk6k6WelU2y/W9DtVCo3TZQRRzAyY6JxxIHIEVoyWE=; b=GhjZejA5TSkBpE0iu0iUOMu6kQVghLe41DrW9JALmIMfelRVuGSexz3dD5w1TzABDN hVqCe/S61KO4YE4ojKGCZekuOi+AHRH9RrEFs32OcQ5ShU1rUTENF3WuILvTRSNVDftf EjIXr8s9quFOKEB4UCXyeQTAtYFXFKNq4gArOJu8KOGQVlExRw2WBOkio8nvBUGl5LES yGYNytij+l1Gq8V6KJhTiKr5S3MGDOmjpuo7PJQsPtRNNqNozskZxYGEVM/Wj7+oTlMd tPA09NhSyweegl9NCvP8ElRaxa1LyVGwZqg1wCc9i08AUJTKQvcimqKWhQtpAznsDQm3 Py3g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=xSdbYx+E; 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 h18si15968328eje.170.2021.05.25.09.18.51 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:18: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=xSdbYx+E; 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]:56556 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZlb-0002Nb-2M for patch@linaro.org; Tue, 25 May 2021 12:18:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60282) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeN-0001UD-7e for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:19 -0400 Received: from mail-pg1-x530.google.com ([2607:f8b0:4864:20::530]:45875) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeG-0006dG-9o for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:18 -0400 Received: by mail-pg1-x530.google.com with SMTP id q15so22958499pgg.12 for ; Tue, 25 May 2021 08:07:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cwk6k6WelU2y/W9DtVCo3TZQRRzAyY6JxxIHIEVoyWE=; b=xSdbYx+ETf7JwnmVhAOcOOb5/3vAL77+h7Jx8b6ClmhsANtk6Do+pXyecWXdjupRuB XRGqCPccLuURyiTc8A7ex9buqaZrOqyM5UIKU2bZylIaBHWQGCKRkDDpNg3Cpb48+hFQ bn8oXPWGi2Fa40Mkkehqgw+IAvYuzi8B5nuaqau7B5H6zGdTWY4jejAxpDpIujEzhCLc mqth0HOtTHkDzv4Z5/HQeKKz3pKFW4AMcydrTZnfPSHQeb7KKA8OHMcjDMxl2u1C80U4 VxcJ1MS09IlhoiTYsNLM2ocnYTTOd9U4Rh9sz1TFT/uynZRyA8CX5T7Fl1Rpqhw/7zWD f5kA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cwk6k6WelU2y/W9DtVCo3TZQRRzAyY6JxxIHIEVoyWE=; b=jTtCMaGm1/nmIjeFMD85NcG5K3Qs7MAZgoBlZsWMazd/LjpTf7vacbqdIQDb1kQT8I l3Xhh/RDcoPKyGXDVXys75TIjAgJhGzbbevOelfnOnYZSIIMWxXpVoiToDL219qOkjb7 0VZAe8YKjeYZcTUpxe7Rmt1pKYP8qhGH19Mhf4Wa4SpNeUw1JPjrdEQEPp+VdLAEfFfR z8HSd8fM8q2/sikxOr5C67/DWvdL0Gm897hbd9IN8mMjhC2uH1z672kShLLpcgZfIqHN LLAVk2QRCzNziCth9pO7/W/jsoSX7Q78P3I8F3a4pE1xMxrcvZ2rLT3K64xRrritKkLf HETw== X-Gm-Message-State: AOAM531+nVMOdgfNgAC9Edq5epu4SneEpUsmZI+LwBnZyRfB+TpFglyp cGd3b64LR7Ldi8yJzHgzPVbEVgLIwzD2pQ== X-Received: by 2002:a62:8810:0:b029:2db:1af8:fa81 with SMTP id l16-20020a6288100000b02902db1af8fa81mr30649805pfd.46.1621955230086; Tue, 25 May 2021 08:07:10 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:09 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 04/28] softfloat: Move minmax_flags to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:42 -0700 Message-Id: <20210525150706.294968-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::530; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x530.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Rename to parts$N_minmax. Combine 3 bool arguments to a bitmask, return a tri-state value to indicate nan vs unchanged operand. Introduce ftype_minmax functions as a common optimization point. Fold bfloat16 expansions into the same macro as the other types. Signed-off-by: Richard Henderson --- fpu/softfloat.c | 216 ++++++++++++++++---------------------- fpu/softfloat-parts.c.inc | 81 ++++++++++++++ 2 files changed, 170 insertions(+), 127 deletions(-) -- 2.25.1 Reviewed-by: David Hildenbrand diff --git a/fpu/softfloat.c b/fpu/softfloat.c index db14bd09aa..2dadded0b5 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -482,6 +482,15 @@ enum { float_cmask_anynan = 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 int parts64_minmax(FloatParts64 *a, FloatParts64 *b, + float_status *s, int flags, const FloatFmt *fmt); +static int parts128_minmax(FloatParts128 *a, FloatParts128 *b, + float_status *s, int flags, const FloatFmt *fmt); + +#define parts_minmax(A, B, S, Z, F) \ + PARTS_GENERIC_64_128(minmax, A)(A, B, S, Z, F) + /* * Helper functions for softfloat-parts.c.inc, per-size operations. */ @@ -3258,145 +3275,90 @@ float128 uint64_to_float128(uint64_t a, float_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; + int which; - 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; - } - - 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; - } + float16_unpack_canonical(&pa, a, s); + float16_unpack_canonical(&pb, b, s); + which = parts_minmax(&pa, &pb, s, flags, &float16_params); + if (unlikely(which < 0)) { + /* Some sort of nan, need to repack default and silenced nans. */ + return float16_round_pack_canonical(&pa, s); } + return which ? b : a; } -#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; + int which; + + bfloat16_unpack_canonical(&pa, a, s); + bfloat16_unpack_canonical(&pb, b, s); + which = parts_minmax(&pa, &pb, s, flags, &float16_params); + if (unlikely(which < 0)) { + /* Some sort of nan, need to repack default and silenced nans. */ + return bfloat16_round_pack_canonical(&pa, s); + } + return which ? b : a; } -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; + int which; -MINMAX(32, min, true, false, false) -MINMAX(32, minnum, true, true, false) -MINMAX(32, minnummag, true, true, true) -MINMAX(32, max, false, false, false) -MINMAX(32, maxnum, false, true, false) -MINMAX(32, maxnummag, false, true, true) - -MINMAX(64, min, true, false, false) -MINMAX(64, minnum, true, true, false) -MINMAX(64, minnummag, true, true, true) -MINMAX(64, max, false, false, false) -MINMAX(64, maxnum, false, true, false) -MINMAX(64, maxnummag, false, true, true) - -#undef MINMAX - -#define BF16_MINMAX(name, ismin, isiee, ismag) \ -bfloat16 bfloat16_ ## name(bfloat16 a, bfloat16 b, float_status *s) \ -{ \ - FloatParts64 pa, pb, pr; \ - bfloat16_unpack_canonical(&pa, a, s); \ - bfloat16_unpack_canonical(&pb, b, s); \ - pr = minmax_floats(pa, pb, ismin, isiee, ismag, s); \ - return bfloat16_round_pack_canonical(&pr, s); \ + float32_unpack_canonical(&pa, a, s); + float32_unpack_canonical(&pb, b, s); + which = parts_minmax(&pa, &pb, s, flags, &float32_params); + if (unlikely(which < 0)) { + /* Some sort of nan, need to repack default and silenced nans. */ + return float32_round_pack_canonical(&pa, s); + } + return which ? b : a; } -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; + int which; -#undef BF16_MINMAX + float64_unpack_canonical(&pa, a, s); + float64_unpack_canonical(&pb, b, s); + which = parts_minmax(&pa, &pb, s, flags, &float64_params); + if (unlikely(which < 0)) { + /* Some sort of nan, need to repack default and silenced nans. */ + return float64_round_pack_canonical(&pa, s); + } + return which ? b : a; +} + +#define MINMAX_1(type, name, flags) \ + type type##_##name(type a, type b, float_status *s) \ + { return type##_minmax(a, b, s, flags); } + +#define MINMAX_2(type) \ + MINMAX_1(type, max, 0) \ + MINMAX_1(type, maxnum, minmax_isnum) \ + MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \ + MINMAX_1(type, min, minmax_ismin) \ + MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \ + MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag) + +MINMAX_2(float16) +MINMAX_2(bfloat16) +MINMAX_2(float32) +MINMAX_2(float64) + +#undef MINMAX_1 +#undef MINMAX_2 /* 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 f3c4f8c8d2..d68ab8fee0 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -936,3 +936,84 @@ static void partsN(uint_to_float)(FloatPartsN *p, uint64_t a, p->frac_hi = a << shift; } } + +/* + * Float min/max. + * + * Return -1 to return the chosen nan in *a; + * return 0 to use the a input unchanged; 1 to use the b input unchanged. + */ +static int partsN(minmax)(FloatPartsN *a, FloatPartsN *b, + float_status *s, int flags, const FloatFmt *fmt) +{ + int ab_mask = float_cmask(a->cls) | float_cmask(b->cls); + int a_exp, b_exp, cmp; + + if (unlikely(ab_mask & float_cmask_anynan)) { + /* + * For minnum/maxnum, if one operand is a QNaN, and the other + * operand is numerical, then return numerical argument. + */ + if ((flags & minmax_isnum) + && !(ab_mask & float_cmask_snan) + && (ab_mask & ~float_cmask_qnan)) { + return is_nan(a->cls); + } + *a = *parts_pick_nan(a, b, s); + return -1; + } + + 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; + } + } + + return (cmp < 0) ^ !!(flags & minmax_ismin); +} From patchwork Tue May 25 15:06:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447308 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4424625jac; Tue, 25 May 2021 09:24:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzpNVUpaf6CxJ4Mj6EmkLBad+fLH9e36PmbzMfIfBpN9lLp6lPmILIQzIK+ec0XiCQXgMPH X-Received: by 2002:a17:906:2a16:: with SMTP id j22mr29438493eje.397.1621959851144; Tue, 25 May 2021 09:24:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959851; cv=none; d=google.com; s=arc-20160816; b=VRicxDGZ5QyVoPGqna2zIyQRDVhQhrUXG1yHpGypCwbYlj9dkqjKcr+f6MxE7kbRFQ QWzC+7iu77sBSz8IB9LUl73JiF6I5ii2acL5s9S75070bT2oShamsRJn5dAJTlrgE7TY /vW1ctPZpQK9+aLzXgjERs/txxCuiqx3kRfq8BfAWgoeW9GiNluNPzHM7PvwJv+7WS0E zh3irg3Y2XKlDEtolF07tJVMw9VwnM3xKSaIU58f7c78KhIMGl2N+QRmeEw7v/xDYNAk JQUBO2+E5TlkHxo/aezLdF7TnnWEjB4ErNdur535K6npxV+awOG1VR9X/sIQ9IbElWfp 3IYA== 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=xT+gSFFP0Pvgx6/sc6D9cAa4M58V2yFxoT6V+q8WC7g=; b=xHxrIqNY9HX7Z3Jajb2WfF34N5SCrP34ErvN1VfRCf09GyQElDrAmPPmKzDGzofw1r GgdG0v3IE3CIpCFipfGQ+kznPdlcuCVIJDny7RSV/ez0pgh/TMLsgtMm0W6FtI+VIviA bpnHKO5Ezmg2hQcHMLJcy1cPNk4yjvWkSe6ad7GaPCwJMvTbiI+WakjgFRo3PqRut6YM 5mB4ZHbcb5r5520qcedhU6CwKWR0eY6te3KsW8C1H3Et+QeabODNJDZSTl/obM+DVtu2 sz8oQSxLeKYiXpLDg7mB+9BfBvDg9tSGj75skpfBJ8rzm+3xfgCsNuH2vNXZWlcv3v9j ETAg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=v2ywlVES; 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 mp10si11265887ejc.617.2021.05.25.09.24.10 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:24: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=v2ywlVES; 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]:46166 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZqk-0005uF-3E for patch@linaro.org; Tue, 25 May 2021 12:24:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60322) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0001ZR-0a for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:22 -0400 Received: from mail-pg1-x52d.google.com ([2607:f8b0:4864:20::52d]:33475) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeG-0006dd-Dt for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:21 -0400 Received: by mail-pg1-x52d.google.com with SMTP id i5so23003718pgm.0 for ; Tue, 25 May 2021 08:07:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xT+gSFFP0Pvgx6/sc6D9cAa4M58V2yFxoT6V+q8WC7g=; b=v2ywlVESGuw0X0HiWixI4/bkksvmXtCANsoC43fR6EhTJmog+ey8HK7WH+VW8eKkwE hjfeupTmNkMiUH+QwCV2l2BIAGJG21sUm6CItqLTvgC7LNnU0nbLt9dDMFPZzXAmgu3x hOZ3gkO+Xnq8+cOPvOmfCPtXTrj3QZanQ8RPfdOxyExYAdleQMXhUsixfmdys0TxydHZ eCw7n6SJ3kIwCc2tSgrxYFlkDWzUGpKXRymNgNovIjrO6ee6CYQ8Omo4gPzC11DUvLiV 0brfd+h18knJanlOzYGMzSIvdp4phVNzsVee9HygWFRtFjUnyhDOuGuUtbZSE5LNfUdo Kv/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xT+gSFFP0Pvgx6/sc6D9cAa4M58V2yFxoT6V+q8WC7g=; b=W95HrnM4hiSx18emZ7Wif7vGr53j83XniW38KTvN9zJzeAFelsAS33+SPZlT8lJnUU IixUy7/8N7sFgaXczDmjzx2k+9uiANapRkRK83sbGkPMaFCRKyy068dlCsurTuIh8ajN qMbUqsJJinmkN083TqZ5n1v4Tn1JJKEFkJWyyDUWj1k2X5UYO92tzWXzdnJD+80Z0Gaz AoOB3O/EAgR7iSLuLn8SHCm/CmO9IkNvXv1ElTihdZ/z7ePSy3bs83MG5FfPOLgPgmfB lhOSwDbhkfqf1t2AO3fJls8163KC5V51VGq5uoMbzO/JRKxwGEsgILYb04sYKm0YLN90 8+9A== X-Gm-Message-State: AOAM533PW+3vy7uHZoLIVA7pjxtuQjoyzq4ZKk+VS+rs6+C2GxHWHFaQ AMzwttA60qpZ7c1Hq1wtM2sCBznS7OLT9A== X-Received: by 2002:aa7:9216:0:b029:2e5:6989:4f1a with SMTP id 22-20020aa792160000b02902e569894f1amr21153138pfo.50.1621955230734; Tue, 25 May 2021 08:07:10 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:10 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 05/28] softfloat: Move compare_floats to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:43 -0700 Message-Id: <20210525150706.294968-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52d; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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. 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 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 2dadded0b5..3c2c3ec8f8 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -882,6 +882,14 @@ static int parts128_minmax(FloatParts128 *a, FloatParts128 *b, #define parts_minmax(A, B, S, Z, F) \ PARTS_GENERIC_64_128(minmax, A)(A, B, S, Z, 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. */ @@ -3360,92 +3368,42 @@ MINMAX_2(float64) #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; @@ -3466,25 +3424,36 @@ f32_compare(float32 xa, float32 xb, bool is_quiet, float_status *s) if (likely(isless(ua.h, ub.h))) { return float_relation_less; } - /* The only condition remaining is unordered. + /* + * The only condition remaining is unordered. * Fall through to set flags. */ soft: - return soft_f32_compare(ua.s, ub.s, is_quiet, s); + return float32_do_compare(ua.s, ub.s, s, is_quiet); } 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; @@ -3505,41 +3474,62 @@ f64_compare(float64 xa, float64 xb, bool is_quiet, float_status *s) if (likely(isless(ua.h, ub.h))) { return float_relation_less; } - /* The only condition remaining is unordered. + /* + * The only condition remaining is unordered. * Fall through to set flags. */ soft: - return soft_f64_compare(ua.s, ub.s, is_quiet, s); + return float64_do_compare(ua.s, ub.s, s, is_quiet); } 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. */ @@ -6612,52 +6602,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 d68ab8fee0..6f9ae7f887 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1017,3 +1017,60 @@ static int partsN(minmax)(FloatPartsN *a, FloatPartsN *b, return (cmp < 0) ^ !!(flags & minmax_ismin); } + +/* + * Floating point compare + */ +static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b, + float_status *s, bool is_quiet) +{ + int ab_mask = 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 Tue May 25 15:06:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447310 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4425974jac; Tue, 25 May 2021 09:25:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxL18VWhTcHTAjvPcFwq2epNOEewLpdRSR0YBwF8Kqn8xmu3NIjhbunCVfJEVZ3xye2i3IQ X-Received: by 2002:a17:906:a255:: with SMTP id bi21mr13654957ejb.323.1621959954849; Tue, 25 May 2021 09:25:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959954; cv=none; d=google.com; s=arc-20160816; b=BYYmS1JLKb5JcEQcB3Hl5ni+q3uzaCJNp1/D4Mht1zsaTktJB8CaIctpvPtNJZU7lF sDRUFlifwPLnI7ZUiAxQreK62zvU1z689GQJlsmK1XYVcDsEvYu6ccFmMiXJTyJtXK1B iSHl3gOvlRlLqkrUR+m1XGbfsUKqu59rg3EfIQOtX7wDOwEfARpW+Th0D0CWHWEBkr9m 9vcK7A0qyGiKROl8c2srb57uxdOOWeg9saECQGOWTJmWeIan2hKSvW9PMqkMSCDt5sZS UfHuFVQxe94tExhYfIabM5/AbfEpUca9oTzNgjNihv+zSOZvTFmIysnNbVRMtxl7y+O3 mT4w== 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=UZW48CzleAWs3EEYVj0CQeurJ7gxS/XtjXLc9QsEbJM=; b=NjbkP60u5CaRUWo4EDouMTo20I435zZz2hmv33PhBe5q57AdN5AmHCQ4tHBkuF/sax LIy16RkTzsQtKCpZNnyMwwGWVGcf1SE9j8nPgV3l72AECCuNsGMsN3W6nPI787awIXdQ oqvPyXujfRG6Ag7bKQJA73vDT0v2l4y4tExWvn9YwznPwozFV1Z08jMVf4jleAttyFyh tkXckBfbFWjv+U32fPKaU+N8QxHzQvexB9olZpciTK4o4wXhDdIHMPX8OTtw9PbUrkSl o8IQibWTt5ga56qT/uq0/WZmHrKDlTWAHqz9WqVqIuqHeBH1nCrFgZKk48fMuLR/uvrU DEPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=hHvEcnXE; 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 ds10si9281277ejc.355.2021.05.25.09.25.54 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:25:54 -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=hHvEcnXE; 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]:52312 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZsP-0001Za-QV for patch@linaro.org; Tue, 25 May 2021 12:25:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60368) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeR-0001eP-4Y for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:23 -0400 Received: from mail-pj1-x1034.google.com ([2607:f8b0:4864:20::1034]:51054) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeH-0006dy-Fh for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:22 -0400 Received: by mail-pj1-x1034.google.com with SMTP id t11so17029864pjm.0 for ; Tue, 25 May 2021 08:07:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UZW48CzleAWs3EEYVj0CQeurJ7gxS/XtjXLc9QsEbJM=; b=hHvEcnXEF89YB+M/st1LxzueXdcmbdKouEWdTTBU/yTuI+fNECFsNM8rSmane6HNVy NADDYe7eNC41RY2ZA/Wwnaw4SK5rHPA9/Nm7HGmEPHVeZpD8kPE/edsYBqImOLsRRSgM Jz+DSMDnTZXBqmpulREDABArK3wu4xPqnDPwizv+4uN9Kw82HWYNwdOukozAQTtH09qS ROhmXXk6PURv7th90fyF9K4wcXz5lHsi5EejmCtskY/0ddtsVfU04Oxf4HKHuOReT1iT tHaWctONIRgnijp63J/SGI8RgXFRfs/0JOxeAhFYgDTFbdv+jsu17M0YAUJ+VKWyKkzg kUfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UZW48CzleAWs3EEYVj0CQeurJ7gxS/XtjXLc9QsEbJM=; b=eAbJw2dW4vgjKmcgZWm+jCdgb5aAUlS2idGpKErBLAIu7gWRdH4jvphBYAZ3wnG+of 94u+gf6lS5jH/CDVjQTxCNZ+e917poNPufgeRCKmTsPwq4OzTy1rUvQKZqx/hTzDDPYI 1hMOcdcM2Atuw9V7c17rVaj3TtvrksDW0wjs2miGGeYmGzCOjPzYO20dE71PFyUxNUDg c8dyZiWEA8fWPTNqNDN59X78mWaP6/hnJmda3JYO+poFMlI32zeqKWOw4i8CwC2S2IVG n9Txx2x8/1AlbhOLZ7/wy6L0aPVif5PrL3g5iPCw4dLFmeoWsNWWUqccq2VmeQgun9h5 tsRg== X-Gm-Message-State: AOAM532dDXvv6rkEsXOqieOHMhB9Ph9rTOVzAxAJDYK2YxKtUfMFyQAZ oIGT6FXL8FdZA5XpSBFL4plelVRwcP28DQ== X-Received: by 2002:a17:903:3106:b029:ee:fa93:9546 with SMTP id w6-20020a1709033106b02900eefa939546mr31070909plc.23.1621955231425; Tue, 25 May 2021 08:07:11 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:11 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 06/28] softfloat: Move scalbn_decomposed to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:44 -0700 Message-Id: <20210525150706.294968-7-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1034; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1034.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Rename to parts$N_scalbn. Reimplement float128_scalbn with FloatParts128. 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 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3c2c3ec8f8..45194f5d14 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -890,6 +890,12 @@ static int parts128_compare(FloatParts128 *a, 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. */ @@ -3532,58 +3538,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); } /* @@ -6641,42 +6642,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 6f9ae7f887..6b553c70a5 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1074,3 +1074,24 @@ static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b, b_sign: return b->sign ? float_relation_greater : float_relation_less; } + +/* + * Multiply A by 2 raised to the power N. + */ +static void partsN(scalbn)(FloatPartsN *a, int n, float_status *s) +{ + switch (a->cls) { + case float_class_snan: + case float_class_qnan: + parts_return_nan(a, s); + break; + case float_class_zero: + case float_class_inf: + break; + case float_class_normal: + a->exp += MIN(MAX(n, -0x10000), 0x10000); + break; + default: + g_assert_not_reached(); + } +} From patchwork Tue May 25 15:06:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447286 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4410439jac; Tue, 25 May 2021 09:08:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzfezEgEsEANn6ups8idDBM9ER9BvOHDUpWaLB5uF6mJ7h+y7oHCFS/XhhVm4C4OLJ/rQhc X-Received: by 2002:a05:6402:2044:: with SMTP id bc4mr33637978edb.282.1621958906450; Tue, 25 May 2021 09:08:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621958906; cv=none; d=google.com; s=arc-20160816; b=TkZ5sOuQ4RgAE9XIKf0whcJ8KvFYDjNRgGgtbKqbn+1DViw/lIW4CrXiv5lyzsqZUq /zgGbxU/vwAGEOD6z/Nifzs6TMnVs47pGvR7+6/g7EGMMsOvL6bEzotrAqih8WQZyxPd KRFVwM54CgoHfEfQKLeymVItHAdgodcymkXD0k6LmFEUBPzoLYSr0+Xpag0uyCovsKZ5 K+JEk3e5YoIx16rY4Gwuecy8mlzKOCt7ow9XUxoq5huWhBbD1aH0ru0pU2j2915MZ/Rz BS2yfIiz3A0ee9rHexXjv1MVIXIhF2S2v+z76YUvKx+tPGGM/D2melxjiHY+E6DRqhUJ N7sA== 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=fdULbYDtSQ0qO12yTrczqlpVqQdGOokmp8V6XGHT0DA=; b=vlI8i/qSUCUgvNW/nbaIRYU/nnRKrdmKNn99IPOKvQEjMAhvnj+KEhWquL0LGzs4Zh dWhibHdGNTRk5zCdeQVqagj5596qFaBRu0FyVxDGa7MWtQDzXwQDdIpzJpg+/vWeT18h oTjE43Q8RQSBA3+9jGe+T8Ie6vZDK8CGEt1FBC6IAD0T+DPhc2qn8RCdN0DlxOOPljRu DDuUKUkcWL+pfNi9wVZtYeOetc5A585oNKbrYKK2XyZolKaM14rKT5BScjlUdGojySKq crqri5zCWGzcyeS6ATHhv6TeyYz/l6tVAWC1peGLnS+NZObQm5byzse8Yr1nNsv1+ued ox6w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=phzhwqxw; 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 c24si722722eja.751.2021.05.25.09.08.26 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:08:26 -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=phzhwqxw; 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]:52844 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZbV-0004Og-9K for patch@linaro.org; Tue, 25 May 2021 12:08:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60346) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0001b8-B5 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:22 -0400 Received: from mail-pf1-x432.google.com ([2607:f8b0:4864:20::432]:36702) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeH-0006e5-Fw for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:21 -0400 Received: by mail-pf1-x432.google.com with SMTP id c12so12247284pfl.3 for ; Tue, 25 May 2021 08:07:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fdULbYDtSQ0qO12yTrczqlpVqQdGOokmp8V6XGHT0DA=; b=phzhwqxwRMH2S7DNfV8VkX/iUNxJAmI6Xzdd6VoRKQBcIHbNw1ZTdpXAIHCddS1RzI 6dzd4PAIT9BPmPSjOti22EGqM/8zgfos6fzbcVXiEK+MR9o7C1unlL/srgUReq7Qt73K qQejz7st+e6FkK7eUpZm2AoZ2jnJZ917ADNR69lQHEyFRRNegj5637KsBaPl1I2l+mdo HXDIS887GMFJ93scYX3Gj7/rLXiXTZJGtXImq3ts8Ar7TXgA8W5xOEUrMBXyTiwKkWat ElfQ145GPruH3FAHno/9G1O/boBCU2eZEseubRPVhmvZKNY+TadceWcEps/pzlb5niRM i1Ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fdULbYDtSQ0qO12yTrczqlpVqQdGOokmp8V6XGHT0DA=; b=k4E4KeZpfQx4NJRJHAy52o3K8KvI5ogu4eZERUYzLBZ9IMvrmwOfccqMJWserPW6c5 0LkLmYY4C/WeWgZv19umXSIgHnnKs6Xwlyo6V9wKCMe1JzWtfn24fJVYmsjSBtDcd2K0 y2okYBNOr/DnvZ7q4prUiqNefsF5UoR9pEZJj8zmP6O3sZFIR3jsCIWvOQt0pxVQ21wI 9HqQ9mTVxVG7Ay4hP9kJRu9ZCEN+HGQXcwjW/qiRUkc8LRgGgWKHsVyoQAejqxwFYZgW kUkC/bjuml8BX7FJocFwTjrY4geC7hqnxVJgFW7PzvWkv7KYNV67EwjQsj3kZskiNAka YJiw== X-Gm-Message-State: AOAM532ecwtjIQAqNqoc+nF8czcMoQ54YfGUaytmWetBf0rlswjdlN0a rmh9HAzeqB1TbI1J/HYyvbYgyBSjiyI/Zg== X-Received: by 2002:aa7:921a:0:b029:2cf:b55b:9d52 with SMTP id 26-20020aa7921a0000b02902cfb55b9d52mr29673144pfo.35.1621955232022; Tue, 25 May 2021 08:07:12 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:11 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 07/28] softfloat: Move sqrt_float to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:06:45 -0700 Message-Id: <20210525150706.294968-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::432; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x432.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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. 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 Tested-by: Alex Bennée Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 45194f5d14..50af8e4e09 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -820,6 +820,12 @@ static FloatParts128 *parts128_div(FloatParts128 *a, 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) @@ -3589,103 +3619,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) @@ -3744,11 +3706,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); } /*---------------------------------------------------------------------------- @@ -6476,74 +6447,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 6b553c70a5..840ccfdf20 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -595,6 +595,212 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, 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 Tue May 25 15:06:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447311 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4427653jac; Tue, 25 May 2021 09:27:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwjy8zO1dT7SltZWKASjvVaiLnj69KDnbSfNB4dw5mu09xeDeNAk7VOWzGBbDRmVz5gmF+L X-Received: by 2002:a17:906:3c1a:: with SMTP id h26mr29267866ejg.22.1621960078629; Tue, 25 May 2021 09:27:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621960078; cv=none; d=google.com; s=arc-20160816; b=VAjt59Ys8zODBP5PnK+4LEHFmBOild/Jn5CWGEpQSIo6u9qyVlnFUcjpjeYjRJCOJx WhMioU+Lrih9oQUlJlwKMoGBuV8t2TnXvbPCmrf8PAjsWKawIP0f5f6aO02AFuM+Kq+Q MkJwvJ5pthxZAkSCtzXXjlfvkHYcwNnXV5jR/mNNDN3lBCozK3xUrWxGisfJ4sYsXinx b8RMDphT7jWI8XaasraJ1TbmTo/79oRb4soJwXoBMLolGlHxqH9q5BgI+7VgkTZJ0LKD qFvym8YkpoccjYbfZNEYAcTOpZVbd55Maoa9t2su12g0boHnEIRMNXHqiWvh3AQqChZ0 G/7A== 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=zLpvJW2BRkZR5YJ9c51EUMDgKNW3YnVi2U2Lfv7yp2o=; b=kg92bmQ0czjX00dfu/RQ7Hy9LBcFzOUTfG9XHNVIMWL070Zaq2BsJU/4YABdFiYLYE eyslUi+F+NHrlHJxJOkZVN2zo6dy+IaJ1V4DIpvUbePwnSWAyz2HmJqOW11M4mFZO1Yb +OSIolZYf8c+QBNb4zYht43feolfW3ZCrUZFbTzUtk64LiAs9mjwS29HfEp45zpydAl2 sn457wJYET/qYmxme7HSd1NTS01cnX2nOD0DQsXqTPUxkzqcWIwInvC12ph3Ee126j0B 3PhIFWdU4RztLLP4o7a3DUoIzhIjWCxHlgtspFdJWn8+bKdg+7xro0qScu5qnZKfDgGO nFhQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=hQajEDCY; 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 w6si13818206edd.217.2021.05.25.09.27.58 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:27: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=hQajEDCY; 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]:55100 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZuP-0003WA-IY for patch@linaro.org; Tue, 25 May 2021 12:27:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60420) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeT-0001mG-7j for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:25 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]:51045) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeI-0006ei-9H for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:24 -0400 Received: by mail-pj1-x102a.google.com with SMTP id t11so17029923pjm.0 for ; Tue, 25 May 2021 08:07:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zLpvJW2BRkZR5YJ9c51EUMDgKNW3YnVi2U2Lfv7yp2o=; b=hQajEDCYCjOC6Ay9h42E0EQZ6Y9uX031Qfk6Ih+VdYGd+CsCyVjsftuJ8qIYEtVZbS gSnSt8uH4Ul5mNN4x6ns1iLVknbY11erwgestkj1ESwJBOegJuNusB7+bm12Y975TbS6 JDPorFjBHopQSdXRbUFp6zH4q36ItyRAQqGM/+aOUgEDhxVLM197sw24mL0syKvPFkWO mSrjySfkNyQiqLaHLZotYdxgtbiJFwhkeVINBjCwsHP+CqtU1XWWUFJA2B84Rsc1U57W 2dCkAMbtWQfWfcOl5HLk5TprcNuU1UOY+/1zb0VoTHITnFdIkxWnhNBbz7YO6kG5LTCa cnsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zLpvJW2BRkZR5YJ9c51EUMDgKNW3YnVi2U2Lfv7yp2o=; b=d/c3qtrAwQ3duJyepo5gePh8Xo5yFp/XG9YjTZchG/eoamuJazKm2BY/9jSH+SUc/O J65LTk6CbsqxG95IiFPR90w9/df9gIqORvaMa6OaITXU5n+du2pjTacxyWhY+Zu33a2H zjs4kEk8EWjXbQ0pXIlxUGc4Rt0iBI9LdO2jL6qw6gAh2YDIRAv4LLUEN61oog3FFDk3 fuPwdfoIs+EgxbSJaNn8ijDhi3VxwZRjv1yDkYEjncwSraSfS4dEPDV1BojhTtQeu8zF QkSRhY3LA6AU/y1r52TSGN72xJ0t8HYGFncDPqxR2PE+o8VTzWs6uCVrrpJ/ugZ3UIrL puoQ== X-Gm-Message-State: AOAM532rk4TogULJ/aUTHJuNeRAYhQGxyDphrLoS4tDcVYDGXciD6neB 34cPhJR+6Jz0H+oMYc1NaW0ykYTCSBpr1Q== X-Received: by 2002:a17:90a:ba07:: with SMTP id s7mr31054163pjr.129.1621955232557; Tue, 25 May 2021 08:07:12 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:12 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 08/28] softfloat: Split out parts_uncanon_normal Date: Tue, 25 May 2021 08:06:46 -0700 Message-Id: <20210525150706.294968-9-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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. Signed-off-by: Richard Henderson --- fpu/softfloat.c | 8 ++++++ fpu/softfloat-parts.c.inc | 56 ++++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 25 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 50af8e4e09..2f2bea84da 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -764,6 +764,14 @@ static void parts128_canonicalize(FloatParts128 *p, 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 840ccfdf20..d72fe3ab08 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -140,8 +140,8 @@ static void partsN(canonicalize)(FloatPartsN *p, float_status *status, * fraction; these bits will be removed. The exponent will be biased * by EXP_BIAS and must be bounded by [EXP_MAX-1, 0]. */ -static void partsN(uncanon)(FloatPartsN *p, float_status *s, - const FloatFmt *fmt) +static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s, + const FloatFmt *fmt) { const int exp_max = fmt->exp_max; const int frac_shift = fmt->frac_shift; @@ -153,29 +153,6 @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s, bool overflow_norm; 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(); - } - switch (s->float_rounding_mode) { case float_round_nearest_even: overflow_norm = false; @@ -282,6 +259,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 Tue May 25 15:06:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447289 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4412964jac; Tue, 25 May 2021 09:11:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyq72nQbNqvpwhoFtJYQhOrJZzyP91BUOI7N87g7tcw5c0IYtFWgNCQT4YkXmQOgh/lTqxe X-Received: by 2002:ac2:5304:: with SMTP id c4mr14960306lfh.634.1621959064297; Tue, 25 May 2021 09:11:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959064; cv=none; d=google.com; s=arc-20160816; b=yihJyki41K2+R+TVslvySJX6hP2BFVk+iHMkpAE2avhN4h19OeKgD+M6sJ9qqZkPRM RN2ywpLBYXobOqmhzqolJGt5bIlKazc0C5tweOiIgcwySevKjJpitQHUcH0yUb3nJUAG d7uq+atouzlQVTejMAtpb5b7tWqX+1AHA9MGvYzWBRIhXjeKT+/zn0cHzdg/7lJJvejL BVukFykY9bVnGaZSYk48igwKtVUSPvSSmb/WLQDCo7LoiPcj6IYIuywfuNs3B16xJ64u fHxHr95vMEEBhhfqajY6aDWtGW9kpCAE+NGkO8rNvaTUhuGMwLYeyQuKS9r3YlIJU8tr ZxgA== 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=o+y2XL8VpmUirN1zSziSG8ebnfy7nnAzZqTrnTQJTMM=; b=U0ahS72d4aFSgRbUuBsZzWqh0DSAl09IDOlN6qgg04BTx9qOQ9ttShfl9z1lMKc+Br u0MUxW2/ZuulK+DHD6PVY/iSleueCjyThdeD0kN2HK5v72tX+2TLK/HKox+yZ78/yGnl EQL2FQlv5qQqCqPsw2mINS8eAgwr93eLfXM4ohydqkl2InWQ7UK2D0xClb1o6LrF7WVv 6TsB1tRYHIcFLrDGFsv7vhsqx+96zEOF7IAdDzk4KPADNtENm6UcNETHsH6a7Btv1sFw zGZ9TLiOHA0MxQq4R7AqqZdaNwCdrBDwtHbYNcXPH2hkoKrZ4kIrlUieqYg8i70V0uiQ 0Fng== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ApVgzULS; 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 o3si20451062lfd.540.2021.05.25.09.11.04 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:11:04 -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=ApVgzULS; 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]:60494 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZe3-0001Uu-4i for patch@linaro.org; Tue, 25 May 2021 12:11:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60374) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeR-0001fF-C6 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:23 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]:42684) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeK-0006g6-3F for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:23 -0400 Received: by mail-pj1-x102e.google.com with SMTP id j6-20020a17090adc86b02900cbfe6f2c96so13344498pjv.1 for ; Tue, 25 May 2021 08:07:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=o+y2XL8VpmUirN1zSziSG8ebnfy7nnAzZqTrnTQJTMM=; b=ApVgzULSBQZRvZLCXwLwEz5nCLWO9rqyRm17cxKYJLkDT9hAzlZ/bnozPOpvLN1H0p +zAm0kXBjKe1DKbbAlcdQqOFaLUp6Y/xIYM8ewKOhglf0qNoRn2lDRsja/i0lMuXUxo9 4TZMtjPVHd0K7SMI3+x2hHUwkUEEugGB4R5J7udjVuUs0mOTr1RpKaXaJ6kJ5Rm9L0+V htFS9jyJecVssCXQgi4k2YpwFjyjzhmpQjloeMFuCWlnznK44WbL81422Bq628kpS9w3 W0CS1C3NhEfGoHABfrqGHNnzg/0DJxoBDQmrmjCUNaKJafQuY45qvMfD7JjoztsQaJmf 9kQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=o+y2XL8VpmUirN1zSziSG8ebnfy7nnAzZqTrnTQJTMM=; b=kseec/MCzw0kwWSShTd2PvIFFmizTgYPlfFvU30+s0HlpIBifzaTf0lntPLtDjH4Ne RKqPLJoqgvmozFlqLmvrUFIj62zivuSjBbKb+bxGBTCS+wzZn/v6NMhkdFnxruHh9iIc KeNoCluSGXC9Ihs0aOmlJ8iIV6K65xnPFR7qN43bebT0zDPbU30mmQv0JI7VKxMdjQse d0EelyHvsRO2xJVMXBIZXyDAfYWfhgB5p7WXvY5zOZv65kg8TX60dQRcNJAB7lit3hjJ noGki55o4WDqjVEVJxFIPSpCkJ4ivWVttV2SC8NmNdVCv+bRLhLc4zKhIHF1Z8LTKp8u DJsA== X-Gm-Message-State: AOAM5315JtZceJ9AllhNhuCy4+SEh3bhnTcPcbD9Cga2QvfQYzYkmp3W 6eQHh8HfWovB7FDD2h3A2Pw84EoIh6NHdA== X-Received: by 2002:a17:90a:6ace:: with SMTP id b14mr5321259pjm.142.1621955233362; Tue, 25 May 2021 08:07:13 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:12 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 09/28] softfloat: Reduce FloatFmt Date: Tue, 25 May 2021 08:06:47 -0700 Message-Id: <20210525150706.294968-10-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102e; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102e.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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. 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 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 2f2bea84da..f6adc2c5ec 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -563,9 +563,7 @@ typedef struct { * frac_size: the size of the fraction field * frac_shift: shift to normalise the fraction with DECOMPOSED_BINARY_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 d72fe3ab08..b456c1c30c 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -145,10 +145,10 @@ static void partsN(uncanon_normal)(FloatPartsN *p, 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; int exp, flags = 0; From patchwork Tue May 25 15:06:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447314 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4429460jac; Tue, 25 May 2021 09:30:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxyCBTcNh443Y7EyhSL3j+QaBAbi2QUZ4EnIEoWz8R6Cm2kD1VOkgLaOgfV0cfxpkDDz+6f X-Received: by 2002:a50:fd13:: with SMTP id i19mr32931978eds.386.1621960213985; Tue, 25 May 2021 09:30:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621960213; cv=none; d=google.com; s=arc-20160816; b=gJSfZazvHw9tM4zOSgbycJKQGGlScw2n+w4S4utFMokTY2q3ybhCfGku8H/JWTOxlu shzOmy57v7WH73fG+MnnDGR9Qi9n2RSfAdccE8Umx5sv9OwDx8wBk+3T2O08ZUjeJQgO cOvvO5jRaBEBI1j+vWN9eIK6NjDNgoR5FrbioEVqY16toZrKRO34x53HqgT2UvNBSQKU jSPs4/awBSzYpf3h6abD5CDKeLA8DRnooQQjiYvRm5sljuvp/Nnm12T09BqFJVuLyEHf juV/Mw02agBbeyCbP0dFTUC0ndQkj+7zf8CxD2516v+NIT8kyVTobrYumB+B5XrxwgIH jtig== 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=wY8IKnf1330G4VebCabYJygcdJcSuxRpeosyc8jlfgA=; b=EdAJE2nZMROA9lVd92lCCjyrdz5rX9kKeNRqzajPKHLReO4SeqwFfR4ZhjYrdKzPwY 7fpESzqDCWB+Cd845mEPfoZn7DksfjUCBOLYhxA0EunkbNtDyQDXAsqx1bkIBWcZXiCc ZPtY5SenDiNhnB2kTOOBf3jLSrRKFkDFCrZM2BeJlZX/zRf9vLaTn1u659yHFgTXmoGG +kD5Sf65gjf/yqqCfDJXH6AAALDLk80uBm+ONSi6SV+kYw0xIjnva4LJkha4XwjTNyA/ Dm4QUDFaHnXoF8uO9Ans5OtnEAY/+QIHUfxd3ZWZ82zfTWNPSSfcashPQ4PpzPjZOwso hVGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=zA0CNSY7; 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 i14si19708997eje.207.2021.05.25.09.30.13 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:30: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=zA0CNSY7; 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]:60996 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZwa-0007YU-DL for patch@linaro.org; Tue, 25 May 2021 12:30:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60452) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeU-0001pb-DP for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:26 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]:51047) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeK-0006gk-3m for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:25 -0400 Received: by mail-pj1-x102c.google.com with SMTP id t11so17030002pjm.0 for ; Tue, 25 May 2021 08:07:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wY8IKnf1330G4VebCabYJygcdJcSuxRpeosyc8jlfgA=; b=zA0CNSY7dQDsokSLX3egJSPk0Azntzu0p/ErqcNgGeNHaEKgHltX4FLF1Arhj+0Ifj b5sgfpZyilkTl0ZV/sBTYAewk6KA1aKmrKD06E7obyHutGMQdOrp0CQSY/zfD2mvPB4i 4fcovbyMts/wVih8ux5ucAUweVVwiLoFf68hYGwhtNSMHFMNlYjFIlo47K06QIUCBl7A iH1naC9/rt6VoifYyuMMPpxExSQT1ywk46HP/ed/5pahOClrNPt3YfCGjEX9oHBjPncB qwZQ5J7o45IKDvCaZJNzO8wMd/h4Lo5DwMdOYpSQbpTSe13OzrcDgqDJty0CvCJf9yrU 9E0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wY8IKnf1330G4VebCabYJygcdJcSuxRpeosyc8jlfgA=; b=E2FN94+DOD6V4omqtWpKwJk6BhM5aAQsi5DkXGPn+VNYShskFJVIADcLAQfLyvRge8 rtvy6k+gjCa/kw90SzSdmPf6bcaGH3utdddeWI+qLEBZKNDsssMIrLPuRA4xSYsf2qQg kkHOwPn8Dtkrt2Fe1CrV+Fpg2CrpwgMkPgRcgULWHQsGS47PaFpeuz1J7vYL1rxNdtrF 0eGze7rmOah+odaFlM/HUamSUA39rO4U/aI2NZeQjSOA/LYKPB12rGJDldGIMK9S1gWx 1DaddstBtgjJl55ZM0FgLYFONhJXr4RqEPo2A80nFAHLLOJKZ1pHfg5fVGuxmJK3A8/G xSaQ== X-Gm-Message-State: AOAM5305rIQnPGcC4KuRIfV7NfVwm0BnaVeP0tC6k2CK2vFDvaQuowv0 olDSnqah+BclNAyGC/FgO2CtPuCqcPSLoQ== X-Received: by 2002:a17:90a:6285:: with SMTP id d5mr31343831pjj.3.1621955234291; Tue, 25 May 2021 08:07:14 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:13 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 10/28] softfloat: Introduce Floatx80RoundPrec Date: Tue, 25 May 2021 08:06:48 -0700 Message-Id: <20210525150706.294968-11-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Use an enumeration instead of raw 32/64/80 values. 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 Reviewed-by: Alex Bennée 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 8a3f20fae9..1f83378c20 100644 --- a/include/fpu/softfloat-types.h +++ b/include/fpu/softfloat-types.h @@ -152,6 +152,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 @@ -163,7 +171,7 @@ enum { typedef struct float_status { FloatRoundMode float_rounding_mode; uint8_t float_exception_flags; - signed char floatx80_rounding_precision; + FloatX80RoundPrec floatx80_rounding_precision; bool tininess_before_rounding; /* should denormalised results go to zero and set the inexact flag? */ bool flush_to_zero; diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 53f2c2ea3c..94f7841b9f 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -1152,7 +1152,7 @@ floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status); | Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -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 f6adc2c5ec..d7477212be 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -4345,10 +4345,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 @@ -4356,27 +4356,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) { @@ -4553,7 +4555,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) @@ -6206,7 +6208,7 @@ floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod, uint64_t *quotient, } return normalizeRoundAndPackFloatx80( - 80, zSign, bExp + expDiff, aSig0, aSig1, status); + floatx80_precision_x, zSign, bExp + expDiff, aSig0, aSig1, 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 Tue May 25 15:06:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447290 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4413259jac; Tue, 25 May 2021 09:11:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwE5Ip1Ijljuc3H2Mh/lu8sBSZV4VWh8/c7jS8Iq4cwzjNWMSv7g9QEihzBsRYRYiIk6xPH X-Received: by 2002:a7b:c3d4:: with SMTP id t20mr24001579wmj.13.1621959085091; Tue, 25 May 2021 09:11:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959085; cv=none; d=google.com; s=arc-20160816; b=UjKquE4MZOLYLAYrbxGIIBbIWBr8cJFGE2hnjSe4zJX7H/6pIHYEfEelS8/oLmKukz lyoOBc5jH1SajmuDKsVBQyUTnmXFeIDYEyGsasRPPk8D88j2ZFDqdJ8nk8Oks0vtwPlC y46t0D1BHVb7U31QAdKBPenakRo3LStsdCjpVnFsNcNNz6HhwIE5uwHkfh53TE5T/Oo1 QcPFsBH+FDStAX639ugWN+JD4iPOLepTzzCITJ20kGqRVsAn6JKCZiGKXQfwQybQtBGX jldACRxIaTynNSe6A9ech9ukikzwX4tgh0PqPz3ib64W8DJSGyWNo/E4biJtGOKaUUtm JihQ== 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=hRoARebbIM30+5QjLTpQyHKZOtTassCJ5Yf1wssASeE=; b=M9XFDxnXe0YWFUf3898Q90NLu9HrxQTh5QfcvK1UpOpm3ftff1cTv0yyinMzH4nVSu nrXoDkFBkANb2MwVt1Z9fLHaoVA3p2/aTabKQQBR5y4RAWZrBYZfl886ORYIjcNND3bM bNcNZOujNZaEKjFtOHoc+DmWHH2Q9P12KxsnRBtCg/KSR4Ljut+gNZ/47IbeTJTkDKkA s521xFJCup+3oPoz7hw1nWjnXh3drg7uSSiaaN/ev+r3sfwP9y8KUGGBDL/X1I2yzPPp 9qOr3gLIQBWoi+x5i0mghnlMKPyUKkpmTLnGj5QE+f8NXak9B5uS61TZ4Pwdj76CZreE H4MQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="bAAI/GPx"; 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 y15si14086223ejw.484.2021.05.25.09.11.24 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:11:25 -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="bAAI/GPx"; 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]:33180 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZeN-00028E-Tr for patch@linaro.org; Tue, 25 May 2021 12:11:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60384) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeR-0001go-Mj for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:23 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]:42880) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeK-0006go-3m for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:23 -0400 Received: by mail-pl1-x62c.google.com with SMTP id v13so16483479ple.9 for ; Tue, 25 May 2021 08:07:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=hRoARebbIM30+5QjLTpQyHKZOtTassCJ5Yf1wssASeE=; b=bAAI/GPx7i7Cv+CE5CxC9LxUX8N/E9378LDG81oB7pd0dn6kFP9IgLTvbi4s07JwSj vsPsfGa2d6M4jK8m03e/rp9DqUeeMGD8houhXP7CEzFiSi0yJWx0CNVyGnZS7R9tyWhG ITxNpt98GmxRLuHw7yHjXWtqnh5Q+pchncHNl9MkMWDEaGJApXbbwdzyQOV97h+v1Qx3 +TTU0IAqxFeMxxZvT92zD5cpeLY7eajYxMSvZrtBkizxjrCq4bBLeHLlj+o0v9QneW5n iSXJ6ogjIKQuxn+pp+Qmp5wA0jC1K0J+iTvVEP958vul+g88/L3+yJ9vwkwOSNPhPwRG pdDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hRoARebbIM30+5QjLTpQyHKZOtTassCJ5Yf1wssASeE=; b=EF6M0D/IgvNpJhoSgZG/Efwtm/S5YuOt0x5OB65gk9WEGZxPjWJlIfZh47PBpp9OLF C0U/tUDdU8N/lQZ63iGneb1nduHsy8iEaI7SQvsvQsCTTDDAWFKfG309BSqQRHgUuMJ0 PNzAOOuE/KwyxBX2N80kA477VLnXJ6uQ5b0/BhKJ228flm2Nyrkk9su9KTVS/1W4Z5rL cRKdgljfcL2qFoBcTM6/KM7+12EKYCGLN2xKuN9hztMmfqc5lmn0kIefEduFO55gXKuW jUI9Akqvl4S2WMytb80qxtV2g+VEHxg/mqy07JcWVJ1sSe1megZQQwTC6lEU57BZelih UE3Q== X-Gm-Message-State: AOAM533RmKfrBd0yvYugfS/eR+umS3YNrGTFHlewqrfYOlGZSvMVe4VJ R9JpWqVJ7NMtC7hZPJnPWM+5BGF+sepkoQ== X-Received: by 2002:a17:90a:4a89:: with SMTP id f9mr5324280pjh.50.1621955234822; Tue, 25 May 2021 08:07:14 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:14 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 11/28] softfloat: Adjust parts_uncanon_normal for floatx80 Date: Tue, 25 May 2021 08:06:49 -0700 Message-Id: <20210525150706.294968-12-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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]. Signed-off-by: Richard Henderson --- fpu/softfloat-parts.c.inc | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index b456c1c30c..8a7f22d6b5 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -156,7 +156,13 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s, switch (s->float_rounding_mode) { case float_round_nearest_even: overflow_norm = false; - 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: overflow_norm = false; @@ -176,7 +182,11 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s, break; case float_round_to_odd: overflow_norm = true; - 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,17 +245,28 @@ 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: - 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 Tue May 25 15:06:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447293 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4415030jac; Tue, 25 May 2021 09:13:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxmpKn880x9CQQEtPNzDJLHusN20GOmFRsThfAdAt7ABLoiIF70iFDWxd9dcme4u6hvtlym X-Received: by 2002:a5d:64c6:: with SMTP id f6mr28837578wri.18.1621959205333; Tue, 25 May 2021 09:13:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959205; cv=none; d=google.com; s=arc-20160816; b=EfYUtm5OPBuYb/4D8AkLC8FlB4gd5UytBpnjwcCUybnFlo2nt8gDNjlzAdKi04IDTE KoSpQoEzEhTV0aKmDlNtqmQjwcLPE3Xliz0mBG+RCvSfy8NbGv+UUbTh91ast3WJZ0sR Eqt0s439IxY0fOAzV4I4OA8Djfwe9AKuVDnsyveXHNoz/bCRrV8x7N7MgshlMhsmNszi nWyXAtH0X9+EMg/w3jB4iBSZGwfZzXJ5P46g2nN0VcSs6zCWgyshKqcbsn4N05RVzh39 Yljhk6HJqKlfR8wRo0a5H7LrhL2QpBKTP9rIIdMQdbKBB4Hm15omHTubs7o55mnDFrmn j1jQ== 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=ma7J2JzDDgw2A3t2ou4QLW8Q8w/So6U3gFWteudjDctS72EypA7Zv2iAO1hPEzRX0K sKAb4Cp2TgATJvre/3tv3ta75dyKeQzrNQE51VEbGzoIDZYFYhvAXfpfTJfo6XIX28pC DuD6C4CUbJhD+ksCCJ48XxzT16xO0e2I9OxwMzQXl93yeJqzzVGrUeYNaajnJ5lgQDz2 DS5/GA5LE5hYnZZE8pVkemCk+hkV7ljiu71xfZyh8WCQPKANlQByFirOeQLHkClozCS3 N4nlPU1jPd3DJ+NIKBluou9dT0D+7ruC6rNNulItePkB8Kqcm4dIrUK4LcZ4zVDNC2Dl q68Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZflE1+L1; 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 f16si17022172edy.138.2021.05.25.09.13.25 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:13:25 -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=ZflE1+L1; 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]:41590 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZgK-0008Er-B5 for patch@linaro.org; Tue, 25 May 2021 12:13:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60416) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeS-0001kt-Sr for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:24 -0400 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]:34502) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeK-0006hT-Uy for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:24 -0400 Received: by mail-pf1-x429.google.com with SMTP id q25so5791953pfn.1 for ; Tue, 25 May 2021 08:07:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=v63kiMKs6E/Jl628TTWBVtvYw6v1ob0t2PY/usIP/Gs=; b=ZflE1+L1NNcpkfLFYw75f5nGBlGPIqN/rWJsGBF/2F9WoZsPZQ/EWGyaq1udZ8uCQe B4eMUSQu0n1hctcfBsUNt4FA5tHQadUplVsI15M1ejCgD2Tue+Zzj1/U95IsbQavWFGo Ut/xyi+vCGPshD8aQ1Rpl6D6eOobX1fYIiJ8JXEfK03L/S/DotD5goiuIgAiTNriIIal rmF4Pak2Vf/Ee+ajPsVKFEA03UBsQeJxd0ZO965whYA9HOCaQS3VIB11GY9p3OUQ3goN c/f1klnAjaVA9LoKUFpnftCL8etqfDaUkMNamBggUmZesVDOiDMCS8l0V6iPt4elYxz8 Z4dg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=v63kiMKs6E/Jl628TTWBVtvYw6v1ob0t2PY/usIP/Gs=; b=pRm3IkIvX7wu1FheAJf/7Drg8IFBIkbIJ28loR9EDiL7JTQO5SYHbV62bBk7adE26Z 6c/iQW9ZYKLv5YZXOn435ityuWtJx9nEC8CS2/NQ1gHQncGtanh2e8UGI8Vex43PLVzT CHJBwBd1hHxol2RwynTMjLNd/UYmbRBCnefjS2SbANV95y73Q+M7mTUWjD40vKMYw5bg 38iI9ibxlNC7U/35KBJtsOaJ9HuhLyjrJrtHhrDAEmtFNgewr1o3gsNCX0gErHDvQids jgmqlko8CMbgi410gPZyOo78hdJT1Y+bnlqgdTLye98UN/fQoMysX6xzNcbcBEZ/d5HJ wV+w== X-Gm-Message-State: AOAM5303lXx/ztjIiKlE+0OQ32RehfDp+kksyXuutmbx5VAz7+8i7hMT 4v96MO6M4NpQ65czZy/uH8dWZgJoc+Fsjw== X-Received: by 2002:a05:6a00:1c43:b029:2e4:d188:fe38 with SMTP id s3-20020a056a001c43b02902e4d188fe38mr23056270pfw.20.1621955235337; Tue, 25 May 2021 08:07:15 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:15 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 12/28] tests/fp/fp-test: Reverse order of floatx80 precision tests Date: Tue, 25 May 2021 08:06:50 -0700 Message-Id: <20210525150706.294968-13-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::429; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x429.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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 Tue May 25 15:06:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447297 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4417435jac; Tue, 25 May 2021 09:16:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwdJ+/0S2C5rINn6Dk9PmSwNWA/wok9F/AwYoVrf2tLhSk49gRfCFY5GPHddlgA1Wl3rhGY X-Received: by 2002:a17:906:2749:: with SMTP id a9mr9241990ejd.498.1621959374180; Tue, 25 May 2021 09:16:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959374; cv=none; d=google.com; s=arc-20160816; b=AnlxifmKiKHXMTJB0rjwk21Smrm7HxGFAs/XkBKA7Ej+RimI+/7Y7Khmrb0fe0SXRn SS/uSDzO9nRc5Y05iVxH9ah3zItn+NtRmTMaJAL3nJsKEV6T8IgZeYVLPOeZpMmA+WwB O6qWw5wqZc3jiiZ5v7TwpB6Gu9vwiTujPmFwszy4+h6yEiVD0GCdhhHKPMLH/T1+k/mg 9GDQwssaTubw68I18+OISvTc9j9qBloRGIHhZXY70FWrdQf+J+1yKFumewUce0fW0+VP Zo7SZUpTBfoiOPa48PNdGLfrQTmwVSftm3K8iBI3/6klgx8rWUTs1ZTEQUsFO+r01Y8z Y51w== 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=rm4zByqo3GfUyLZhPuxawqIm/WAD7fG88RsiMrmqesc=; b=YEkh356W0ArzHKfbVmNhSaepxVfQEh0LijqSOkuSvh/oU1Pe8JfppLsolpVncK7Rtb 4o3y3TJN9oRnCtyTKuL5/2i5e8kAv3fncYFk4bPotnxx81JSXdyEy3YRGvB/h2SINkIi ehk6mrD8Dw+sppA2KWV3HrbJbCxHgMIAyx0pCVk7HCCQvbud4nA42zTu8hrAJ128FJG2 /X/3N0FN+1lW7eWZE5YH9jhkBRSJQMftcPvZRHpbsFFlBRJn/t8ekCtOM83iO/x6XthL /IxxZS2Xv1F8QwtQyZ5K4//xSb6XPbQbAeEhsoTBYJvFnrAIGKQYFdat0NNYvbYrk+xM N83A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=f98KlvBa; 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 bd21si15467314edb.261.2021.05.25.09.16.13 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:16:14 -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=f98KlvBa; 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]:50370 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZj1-00069X-DR for patch@linaro.org; Tue, 25 May 2021 12:16:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60456) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeU-0001qd-Mz for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:26 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]:51049) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeM-0006hg-2R for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:26 -0400 Received: by mail-pj1-x102e.google.com with SMTP id t11so17030062pjm.0 for ; Tue, 25 May 2021 08:07:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rm4zByqo3GfUyLZhPuxawqIm/WAD7fG88RsiMrmqesc=; b=f98KlvBarWe4dX2K3N/EPfKeRzGtYR9/RIOVlcySco35XEplYDJ3Dg5syIoozbWmf3 UBe9uVpKDkz3IkYs0cd3uJnHvSfw3+ZYY3u+JcZDoP+zV98c2N0TROdmKFsbKZUM8shd rEHD5ZQt+zxJ4KY1pSPh7osf3ctur/qz/EERUI/bNk230XK5GAhZv4R7CLzBGy0QVWFA 7s7h6PRvoLn2Lzs9xlNSKAPXHgottrGIrJz0XXyuaW0MQ5wyIIabN13I0vKlpgV/s767 nquRghC31KAqOZQin+qqPX3R0b/KUG0vkELButv3lspWyrIuO5Pq4bQhBP91c7RGtOb5 cFTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rm4zByqo3GfUyLZhPuxawqIm/WAD7fG88RsiMrmqesc=; b=jrHomvQntdfXMl9uXQqQ4CwwOjLpjxG2ly5c5/SoO+bcuI24kjSojzh12lJ44WwN8N nn0X3y9xNMuMONlYRgUrSRK/GXCx9mUKi6UEzLF7rDoAeBTWLb0hawAn/o4sZWycXhpT rNIiokbFsCZEX6SZ7vH1foHchTQCHB7QmxpCz9V8bEuvulyVTCwKbfWW3+svQggjsOCB HBExtS4QJzHlZq0DeMVypNUE1/tzplBp5nMOhQk6ZrYr9FxitsTzjCNtpdXqRWo50baj UwKnyS8u6KDTFNMWtQ3adLhQyS7UUOhz8iaSLcX9Mr1g3Pmyc7XvHHWJ9KT3uTaXV6xh hnHw== X-Gm-Message-State: AOAM5322XBsNoFq+kO8KTd4gOlYHGlwr9q03YhGqC1GX73BFDFYceEZe ai5gFLEaMLeHdFk7DwFu/VDw232ewVl75w== X-Received: by 2002:a17:90b:14cc:: with SMTP id jz12mr31527281pjb.210.1621955236036; Tue, 25 May 2021 08:07:16 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:15 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 13/28] softfloat: Convert floatx80_add/sub to FloatParts Date: Tue, 25 May 2021 08:06:51 -0700 Message-Id: <20210525150706.294968-14-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102e; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102e.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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. Signed-off-by: Richard Henderson --- fpu/softfloat.c | 339 +++++++++++++++++++----------------------------- 1 file changed, 136 insertions(+), 203 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index d7477212be..073b0440eb 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -578,14 +578,14 @@ typedef struct { } FloatFmt; /* 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 */ @@ -5734,205 +5866,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 Tue May 25 15:06:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447320 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4435169jac; Tue, 25 May 2021 09:36:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwNLmogReIBw6lbd+TiHQevzMucq9L2/j4gLSxX83ubvDAguv5u5sgXOnaUW6/7op8fPvuI X-Received: by 2002:a17:906:bc98:: with SMTP id lv24mr13001140ejb.297.1621960606170; Tue, 25 May 2021 09:36:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621960606; cv=none; d=google.com; s=arc-20160816; b=G2jsrfUY/pznf+a4LlhxceHf8naqewWGfRckG+rI859D91aRFN38LFi/7FkuhA2n69 /mQe6pGWQRAI891d/n6OnemSQYgg74fmGif9pjnDnkhmRbIH+IawjMQtm1Jf2JU2bc8p 3/NjFFjtuwNzIvevImpA7hOSWWMsOrvZV4EQ0q7KsgQPpHUgmaMZQICpZ2N1h2JD3lDB rTNf0NQe4BZjD1KBICuOyvMFg8LjEJt1Wp4hUDMPTBeh70Cgek9I723dvlF1dKV8IFmb Q9bm+aVef+XfZEStfiPBdKuVDFj13tsIvi+B2Iy6MzxtDRFyB8keWQIcHu0NtNkWWmzh 7ovg== 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=2BYof1ybjsIxHUNZfvumVsH9xGhAIK1VpElG81z2ZqA=; b=cy2so44MJt7SzNNnPY+UHqzKuPyInEQNceQmM9VKl1gU3Zis1T8cLvu/oe9NXAvsBQ Jkb1YVkut0s4r84Ms133FfwqmNa3Tm4KF+BrjdC89nwNAnniP54uTEXpcvyrS1H722He P4Mb6jX1qDKUVHxq3EgTw+/EiiYD8CvD3ykMdgqyaEqZ4EU306nerDaFjy2e2cqZQsgu R9GCcmd0mgy86Oh/mkA6lIwecT9JE0dE93mzYG9vs4mPEWuA17ymRoPAddPcpIIsN2pR QvIegt5VfvaL4Qgoees8zTDCzUvJfDzHJC2NgnutPHKmfVAi449iij15BAeVMIa1HJ+e APYQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=mfKKUqZv; 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 kl25si16295693ejc.370.2021.05.25.09.36.45 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:36:46 -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=mfKKUqZv; 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]:50144 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla2v-000307-3t for patch@linaro.org; Tue, 25 May 2021 12:36:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60524) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYed-0001y8-Cp for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:37 -0400 Received: from mail-pf1-x42c.google.com ([2607:f8b0:4864:20::42c]:34505) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeN-0006iK-DE for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:33 -0400 Received: by mail-pf1-x42c.google.com with SMTP id q25so5792020pfn.1 for ; Tue, 25 May 2021 08:07:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2BYof1ybjsIxHUNZfvumVsH9xGhAIK1VpElG81z2ZqA=; b=mfKKUqZv3XHLRQVOUm9AhbVg/jlijc0xkOEXg5xQfsHfXtTqIZ3sY/uydRS0jvtjiD T2b0pdzwrSiY1av82z2pAI+bqRvPEC+if+DuUIrjLWSZhyAhnsUGM6XqpM9lXJa3dQTW vYksNrPyzqrKGK+rJA6lUjwAOMj9yiPDWjayPADvBrq1xnUEGNrNvF1XcIyRukWFM0Yq eJzNtLjm+BPuhkEpx3JnuJdMHPECCdOuujTR5+LRvjigVKDs2yfx3FqomfUBQ6HdX9OQ WagZWz8P3LJOrCFzrxA61n+Fs94GgvXTsNL5FcBJyZ7ig0nGZS19mAGfuOd5VwhuqvbQ J7XQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2BYof1ybjsIxHUNZfvumVsH9xGhAIK1VpElG81z2ZqA=; b=VcdZ9Fp+VWpQ/sdu0CHkG6O2h1hyGfbV1G3ckXtLr/srzQjk7GGYc749f9ZYhlmLPq swWlWh6uxWxjTcWTJmULk5PRQXobb9YZuaLGkXDUr4ZoEwAUQlS+e81+FzagPnNblt72 cIuKEEVQPseqvpUfG7axREvkjNr67TIzOc7amdQqSfm2ugYemge44WQRhC2ovsZVRvZG UkdxDhq+qAunfuemNCbOpXPtuql4wwuM7DN9w6omYspEujouSKwTZbH5tH0zwq0xAJSk GRjLkllq0HHLEF621yxH7b+yHfClwMjwYoounEJt61qOf2qsW2+5UpC3Ih5mNF3az150 uu4Q== X-Gm-Message-State: AOAM531XJRtLLo70sv6lRfAS+WWCgoHFUcUIoWZO0Gxc/MUWUXnsm3n3 9keXwdxme4wT/KGRqWZLZ09u8GtyRtCRzw== X-Received: by 2002:a62:148e:0:b029:2e4:e5a5:7e33 with SMTP id 136-20020a62148e0000b02902e4e5a57e33mr22350849pfu.9.1621955236880; Tue, 25 May 2021 08:07:16 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:16 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 14/28] softfloat: Convert floatx80_mul to FloatParts Date: Tue, 25 May 2021 08:06:52 -0700 Message-Id: <20210525150706.294968-15-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42c; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- fpu/softfloat.c | 76 +++++++++---------------------------------------- 1 file changed, 14 insertions(+), 62 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 073b0440eb..2f2d1e50f7 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1944,6 +1944,20 @@ float128_mul(float128 a, float128 b, float_status *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 */ @@ -5866,68 +5880,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 Tue May 25 15:06:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447315 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4430679jac; Tue, 25 May 2021 09:31:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxfk9cgcdzXiqyMiC/gdmuGFkllPTjZEdmO9N2GJ1VCHzV3q6ORRZJlS3fq61IPxAfBJzQZ X-Received: by 2002:a05:6402:684:: with SMTP id f4mr33834973edy.25.1621960291020; Tue, 25 May 2021 09:31:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621960291; cv=none; d=google.com; s=arc-20160816; b=NlxUHA/e3vLInJb/m899LY7eJwKCnOEjIj9WFDAjsKh+M+cygSmbzonA4rlGn6BcMG whC9D6T9/e6YnQIfwUeQAg3O0hQ/fSVu8eEgie4WWHtgy7gZOMVY3vw4sJl1EB0HPjs1 ytJjSt/KpVC3W6ixZnB6wLkhBYg4KL3ALCfQayWJ1Q0hgUJeM2DeXiMCSgjeYnnDIokq HZqBbmjggW6ylBXzxjIcUxl+E4SiLQt1mYfIXx8N2sgztykY9v6hTbkyDW0b99+B2+Kh yNxy5xtYSnGAo8WHgadGXKRz6d2peC4GrdG1pse80L7Gv5tz2wY0JxajD7UVfqthZehl EOjQ== 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=17lWOhgcl+ZVqAbMQv1xvpusA/TYAXuediZfiyj2D18=; b=WFhNl1AmsCenBRursrbG98nSg5pWfWsgEiglkd/Zpyz8NhQUvomGHcRu9o5UBysiYm UN5+IEf2Cz3pxNjZgi5g8wtvzHt8MDmb2X3RZZyBfjMoR5wpIFQbUE+M1jxGwP//ULHj 2CgbURoaEVyAkjYkHmf1qK8d8zH63Tfp+4t+2b5Boii6+YYUg3I5g2AhMSGoHVf+74+d tH6morAtd97eKFsvwQc1/48Be7y4qXVGZ+OqUjO30cXellu7Qx/aF1E3u4RpLy22PuJX AWKRNNhdpvFKgMr+dCTksURdf9tyEP1H8rl6CZFm5Jrhhc2pe9YwkNzAHAE78N0A0HHX dXPw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=EVauJhgg; 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 bz25si16395302ejc.295.2021.05.25.09.31.30 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:31:31 -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=EVauJhgg; 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]:35288 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZxp-0000tX-Tf for patch@linaro.org; Tue, 25 May 2021 12:31:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60424) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeT-0001n6-I0 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:25 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]:51050) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeM-0006iN-SB for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:25 -0400 Received: by mail-pj1-x102f.google.com with SMTP id t11so17030105pjm.0 for ; Tue, 25 May 2021 08:07:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=17lWOhgcl+ZVqAbMQv1xvpusA/TYAXuediZfiyj2D18=; b=EVauJhgg+KIZPk17DqgyB874sQrsACp2mMAxtsnfz5bLU++Qg26t+GfSdue4aGaSnH RL5D0gZITXCrHzgOdFljXnxE356OTXqXL/UFtEQpyQtL+656P7zVh+/J9bMlY4rGXiou UyFGiN1Sn6CyPFpgVrl2oBpuIFfxk+WazG/aowMpcqQNHKF3KzlkXL659QAUUSMRZ/nM UynMX7J1/K4JkGfSHGGRECIVsBepjd5rSrvLOMQQbxFeI1Iv+kLBB5Of8P0Ji6q3vYmc y+WoUkCuvYKSzSux1LZlfI8MjWmSYJ+mdDL0ypmgsaXVS9rOsAsRXxh6T1KISGnyRA/8 JXIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=17lWOhgcl+ZVqAbMQv1xvpusA/TYAXuediZfiyj2D18=; b=nseNqc5MxH8tocLPmKv7FzEoNL0GY/IFCuzMGcgdMifkhEoqDbxvLPcJ4xYdyOdkmH tMh9pXj0JXFrgDnd9Vx2tP7W8aVA5t2IVbThHOEh2Pd6yCYlC1DWYn5JteXeR9TTStMf 5gHPgaK29NC9tccJaaMi9VSVoYZF9Ue6VftsL0kJv1UrAW4G+SBNr/SSPRoAo3N8gPKZ PpyP094Yfk/1r+4CNNgb5ftq9u351Jzw1ApdO737mE4YQJJoBk8SHEPamRmjeJxh3K2V 1XBAIfxHLGOtUc+/JQVjq1UFuwWRyEGLczqjt+hplLC5ppVWT4fKVU3B/SN5vkzpFFfI wRpw== X-Gm-Message-State: AOAM533+fplAfM1si9k1wbWEGS2Q8zbXvobl6+8F+JMCiC3K/ZAj7p9c DpBeQpnchnyI3YfibBcK6QxpsQaROPW+jw== X-Received: by 2002:a17:90b:100f:: with SMTP id gm15mr31364738pjb.197.1621955237454; Tue, 25 May 2021 08:07:17 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:17 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 15/28] softfloat: Convert floatx80_div to FloatParts Date: Tue, 25 May 2021 08:06:53 -0700 Message-Id: <20210525150706.294968-16-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- fpu/softfloat.c | 100 +++++++----------------------------------------- 1 file changed, 13 insertions(+), 87 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 2f2d1e50f7..7b9ae29285 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2294,6 +2294,19 @@ float128_div(float128 a, float128 b, float_status *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 * @@ -5880,93 +5893,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 Tue May 25 15:06:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447301 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4421240jac; Tue, 25 May 2021 09:20:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxC2pnJRxikzof+zUOzoGVD8cixK882xSoFOVAEK52KyTZyn6TBOq/hotOTcmbLS39Vrhwj X-Received: by 2002:aa7:cb02:: with SMTP id s2mr9196066edt.67.1621959615656; Tue, 25 May 2021 09:20:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959615; cv=none; d=google.com; s=arc-20160816; b=0kdpUPcpu1R7AU0RWaOVJ4RJr49j55wF5Xz36THvz8NPN1Bi+QaYAnQW/mpjuibIEB quyU5rhLohFjnAAR/s3OApuIA1kByVyuy/X2ZiSgoIbReAoO0kbU5EptpZZz7L5a7x31 cT8diGTW3HsziEWkxPcVaxqW9trygRZe9VH9F1RqPAVwoGeEUNAZD5BNWzdPquMWemtg gCHE4y2X6HQ8YckGxkOMUwtNK2VNLJjNdzdtJx6YxV8DRwQv2bXoS+I3pbP5sx1ZdcSs F5Wr1ZVJ1tn4HW8/A731xuWdgVu9bPgnFdMRqSQJ5EvjqqkEZEXQzGeOiU2sFSZ4D5+f ih9Q== 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=ADKnkvRZV41OR8FpRzBFVdThnPU71bizMrztN5c22yI=; b=pDRZxaEfT96eMxr4xREB4QJDASSHYyZ6yYcn0PanpzwNDYFUGC9Xmk4SpgluWeB7rl KSlhwbE1Jn60Bf+PYq3dyMDW2MDsAHjBhzKSyKUhVWf6dVIsurW/rhCcZ4j1lyw5cK4j wDmiR3/I7UO369b3XqzNqIxDkV4YwwlBT9FzxuOZmcMwWCKUWrZOWwSnBzNUY6bkeNm9 1/tj8Wdm5Kboor84pNY3XpiMht+VYAw8w+iAJnbJbIN7LRgu52TFpthDADRsgCiQ4POp i+lZI8JdD1dRCLiY3ojmSCMRXnVIe3D5wO0cfdjOg4AbKLzlu+WSPlAAr9+HKaHtwbun M06g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=fh0nR8T6; 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 d2si16190111ejd.638.2021.05.25.09.20.15 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:20: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=fh0nR8T6; 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]:59244 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZmw-0004C9-KO for patch@linaro.org; Tue, 25 May 2021 12:20:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60574) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYei-00023t-8z for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:40 -0400 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]:46819) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeP-0006iX-Vp for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:40 -0400 Received: by mail-pf1-x435.google.com with SMTP id y15so12439736pfn.13 for ; Tue, 25 May 2021 08:07:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ADKnkvRZV41OR8FpRzBFVdThnPU71bizMrztN5c22yI=; b=fh0nR8T6S04JkovZwdwvwnxn9n/ZTpNHD1LAfhfHxT2YVdKMeC1AFEFUlm0MNxVBtb X/qSuv2Cq9u5sFgJwJmV+dqTYyuPN5Wbfg6pN3+vh5uoG+p8vRLpWdFGTTZcGv6kA8VL V8HkgOv63mNZU1EfJSJV6lpMCrJQHvIAkxgRoB/xz9aA5mJeRCcdls8s38llmH98d/Cu zh1/r3nNSUsSsGekC6Ki23PUTST/M81oZWLercPgtBgA69KlMf8dKQ7gDVZJg7mrGzkl e+q4pVcmEHCdXuhFoFSsQUjPOfAFDkkfH3ECokPJEGlX6KsQATn9npdCkA+mck1w8QYY TA9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ADKnkvRZV41OR8FpRzBFVdThnPU71bizMrztN5c22yI=; b=h72tgeO7yYN72aeHSq+XA7fhWUEQ0jnJLG3D0YbwwjJLyW6pdzrqdEMKR2kJqIwrlV W59r42BatFpXuGIC4q0AOnnTuwXhICIi2c7HtztcJW9kax/9dRJQlouXsrN5TDpm51Zm zKCK0V5UO5CJglm83phv0/3CkeLy40JUsDvOL30fOMmGDPimlBZkjsQy568aIh+NkVot tnC6l5PQUADEn0ocJ/juJOo9K4TdcXJX4+lwxxRrQ9TkrotMbcxYskvbdVpXZrT5NQCr pvSuUtgvoKfobuAiNr1whSyNyOhNsxMV7j/dSgKRZWjPMQvL/0cJ9r1EpTDThSuCCSLf sRkQ== X-Gm-Message-State: AOAM533jlX580VA9/0HUu94hpJkIvvtnEsnMlr/xUQSYFP5b81y7nsJU dUcME/W+IGXAlBwpp/avNHJunAKeOa5oJg== X-Received: by 2002:a63:9316:: with SMTP id b22mr19865846pge.70.1621955237991; Tue, 25 May 2021 08:07:17 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:17 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 16/28] softfloat: Convert floatx80_sqrt to FloatParts Date: Tue, 25 May 2021 08:06:54 -0700 Message-Id: <20210525150706.294968-17-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::435; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x435.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- fpu/softfloat.c | 82 +++++++------------------------------------------ 1 file changed, 11 insertions(+), 71 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 7b9ae29285..d7beb27982 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3884,6 +3884,17 @@ float128 QEMU_FLATTEN float128_sqrt(float128 a, 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. *----------------------------------------------------------------------------*/ @@ -6047,77 +6058,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 Tue May 25 15:06:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447294 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4415313jac; Tue, 25 May 2021 09:13:45 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwDILzZUMJ/bV2Nf8cHDZ6qgpRgdnX0d3w82HgdHtX8U/ZiubJFyf7fPQbobQantwBt+wB5 X-Received: by 2002:aa7:c70d:: with SMTP id i13mr32622524edq.340.1621959224992; Tue, 25 May 2021 09:13:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959224; cv=none; d=google.com; s=arc-20160816; b=hElHXi2WoxDzOq4hZTmgYCkGceHNZ5NTU7HUpV03R0TVVHfS/xvUAvug1KFg6Qon4T TDckxrv7mHF4Xcb8i5NT9l3HCZ6r9KmOx3zKnfcpXocUbXxOAvQwlZRiJdf1BIzM3Wvk gYseOS8p0I7yOf/TnPO7aXUKUj7NxoirokYTb9ik1dSLMSqi5M8K5zFX/gOyVb+x30in xEnlnEvDIPqFZTOlXsF92u/BKZlp5qrg65Et3FIXKJOF7i1cQunaiduFmBFRcUun8XL1 SYN9/Xepb2uBzDL1zSVHxL7yr3bg1Om7qqGwk/kKOPhWqzZfl8mqJixZ2lGeIO8CLY8X 0e/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=eShFDpUU2i7h7h2qJCMIyadlLFYSgvTlWNlSA4tKpjQ=; b=J+vNCseMuozhH5bS7QsXQx7BM4uAP3ijvGaDeHcmA6CNzmV2ldI4yCPYCaYj3/ZEo3 OofoVYx+KcXgl6aU/TW65PX2N1VpMQSDDuGb9uMzn5Efi/2N8CAMGDw+yV6gAn+6sbHP cjzZKYNlzi84lQY011YjXF2AyN2i9wdAjfemqjGYIYtsH8AsctnGp30/18ikUz5lyesb QirjDWfjGFU1C0/GdEru2BKNPqxEGK+htuhr/qXaRu+coQ+fLeKxkYMcTU0Wz/RN4EmJ TtOAWxr65qpT6zNU1y1OMNIo5nuosK0ZCoKHTi/TyJthRsY8azsFWacFBcGRS8Lqd36y uk2A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JD4frM17; 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 f25si10156880ejh.388.2021.05.25.09.13.44 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:13: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=JD4frM17; 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]:40736 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZgd-0007br-V4 for patch@linaro.org; Tue, 25 May 2021 12:13:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60492) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeb-0001vf-0h for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:33 -0400 Received: from mail-pf1-x42d.google.com ([2607:f8b0:4864:20::42d]:40496) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeP-0006iw-M1 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:32 -0400 Received: by mail-pf1-x42d.google.com with SMTP id x188so23833633pfd.7 for ; Tue, 25 May 2021 08:07:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eShFDpUU2i7h7h2qJCMIyadlLFYSgvTlWNlSA4tKpjQ=; b=JD4frM17eA0L6XmHj72nPg82VKQiJe8SOtDPh8Ai3hy+3d+99PiAu2FnbCIOqdEoks 4hZOhBpKeW81ZjYVStZ0MoZAy9ibhF4+AoCxqmP0V4Ao0+ZJ52C+xP27U1x0SmbhTMiV n4GqiUMaCI4tNrsm57NwL1puj8qJ0KXlRu0f4wDPLKVBhBmBRtkBWuH2ibPxvhgANyEL aq5qtkCHDpFH0yZXA+/mJORs/Gs4LizbQkbz7VOER7jYGsCyfnV1M+DauQu0Sp2utQOp f3+yxvUWvU0dLnVYCGhzxcrIX8ZRy2qvnLhqmC2fS/iVbFY8bOV78QLf8tiuUkScyFSl +YUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eShFDpUU2i7h7h2qJCMIyadlLFYSgvTlWNlSA4tKpjQ=; b=H8udtCFSTIUAHX7C9OeSj1lhJUu9iDr3Tb2vJpKU+sMPjYxFgY2b0CjkdWvuIT9gxC JEbCL3iIhEj87QDC65IPNiXy/dnZoiez9QYu0SUJ8KgFxKSZBK7cfvvTI1oxZkZ6ZoB2 FcKgf+A4EAnLe3mAZLyvwi/3goi7SE9b2X5i1w+spPWplg1FJ5bNy92RhfACmEdjIIwm 2DPSP9LxcYVwOJOYZoD59ZGg57H3uGkaR5dSS5VyhOXuIhcM4E/ZZb4sfR2kWJxLjT78 DKTh7mg8rGm9u8UgUvkv2XjlyfI/klk8W+I2oebeBpkaqyNmAd/0dhNj+xbo+TOROEUe 7qxA== X-Gm-Message-State: AOAM532lfd2CHTosFidld6PtlLmLFrR0oWpDkJqMmUV/f5zy1HVs/93G 20P1c3b9vm2aZgYEHUh369jqC6vxf1q7YA== X-Received: by 2002:a63:1559:: with SMTP id 25mr16141721pgv.384.1621955238532; Tue, 25 May 2021 08:07:18 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:18 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 17/28] softfloat: Convert floatx80_round to FloatParts Date: Tue, 25 May 2021 08:06:55 -0700 Message-Id: <20210525150706.294968-18-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42d; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- fpu/softfloat.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index d7beb27982..1f7260caec 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -5795,10 +5795,12 @@ float128 floatx80_to_float128(floatx80 a, float_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 Tue May 25 15:06:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447317 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4431718jac; Tue, 25 May 2021 09:32:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxMBqFtjy7gD6tFza7ejkSh61lnqMuOvEA8Ow/ByaBbLGfmPXWJwfjPSGiYRWEMqrS+6g0K X-Received: by 2002:a05:6402:1158:: with SMTP id g24mr32228649edw.134.1621960364149; Tue, 25 May 2021 09:32:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621960364; cv=none; d=google.com; s=arc-20160816; b=WlBLDC+OMDnwgwuMhhtlXU1b75rwpgjLFuSk02Qra6G1qW8/U7TYHlFR3bZGAKgA1E BDiqrix6iITME1zsf5l2va5J+Z9M4U0yhflU2gg0tdZ+WhmvLJlUvarJpd0FlnVyphOn YMX3/H0hZFT8dn7UwbnVNEA6s4CuZDb3HoYrLB8CnpbgvVklfSYazlHNRQ8KJJevLxPE vx3RAAe3eAe6ojXK+sL8Gp++PGMsEmy0ZWwG/HZYVKRedtCNdD0Dof9Z2B0kHdxW21SW kdhyTJ0jDXwPblnuHbAFTgJchl2fpE/8boSfF0CwUw+2tK4kmid2dSR66/QRpXuy11rY H2vw== 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=jRtuMx867iiF9LnMJh9kaoCKipyhalwdeBb7t+R/rbM=; b=BrNp+HKu5ynBsraIZaeAgQyBAI3BGQwlFlHYl5BPOvExOeGizjdayB2rprrG7LxiS7 dLDdHX7VbByI2+P49sshPS3lwDQ+HcIYkv+ZYPF55/yCPELdH8Z+oPLJ4tn9QIMPTw5T 4EEgn1ZtaazoZvB4rPBXyVkf8Wj1q8I1+uUgndXwDm6tciT149tjZcErTrgFSoIt3g6j Fmd04TX3J1MbnOfanSlHYJDPrshnapIIAEnkhz8+LpusK5pVfX4X4kvUEuTc2JoZ1vQw exlbqb0zOSKWZpxOXnLy0HUlT9BoxmbhVDK1lUUg66MQo4cBZSU+ZmVTJv23vSLi6NPL 89EQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Kmy2FyQh; 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 m11si4872084eje.329.2021.05.25.09.32.43 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:32: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=Kmy2FyQh; 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]:41772 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZz1-0005c5-26 for patch@linaro.org; Tue, 25 May 2021 12:32:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60530) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYee-0001y9-1V for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:37 -0400 Received: from mail-pg1-x531.google.com ([2607:f8b0:4864:20::531]:43812) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0006jM-0P for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:35 -0400 Received: by mail-pg1-x531.google.com with SMTP id e22so7229707pgv.10 for ; Tue, 25 May 2021 08:07:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jRtuMx867iiF9LnMJh9kaoCKipyhalwdeBb7t+R/rbM=; b=Kmy2FyQhJXUlQH1RDfhnjYgU/XNv8JAVpeMeD+l3H+4s647y2BhRIUFXXOZbRS4Evb L0iEGhsI3oBYbLXn2PSECdNqmuyhyDrQR5t4mhYAr9kopa3wp3+jqkMmxP4jQ3nYV2SE dc/Vij28uGnFlaggkyBm2c+JbUE3L5aq3i2mzqc12JemOCOJwIVjn1N9r0gPcuvlVGf+ xow1KadOkSAjBm68P7MNGlJdelbFdtQnqHFhfFiECJUXP3o8qwZw9JqQhMXKcVIQFRHZ e1C9EBf7WCJmv81IXzLygejxCD1gkbiH7dG1L6FCCfDWCpwI9cSatTUQu/MwwKbr1VrK Yucw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jRtuMx867iiF9LnMJh9kaoCKipyhalwdeBb7t+R/rbM=; b=ZjjDBG4fBeTk3jBg28CRbENJYaRW8QvokaKa0V+oVy+4hILbysyox3Ct9qEKb/Lqvq ZbYcZ4D4jcQF5nVZFzmvybF9mEzfMB/EtHaXb9hJ9bkN7wVkKCl85x0rT5jNheFIk1tZ hNARNhDMBejbZSL7MsUCglG832xCK5uFnZ8E1MOlDDn20gXJxTaJyeY1fDER7Ky85js9 Df+bRnC3Dg3D50IwAF6uhNkysTSXFboy11zh69EYo28l6PHtMP7ew0q3d2P666Bux4YT 8jYs/8ZuRck7MBZFyzU3UVWyxnYIYfHoe7E+QNuBCqrYKt3w6kwF21vccoKe+Uy8pLG+ dJVA== X-Gm-Message-State: AOAM532N6nQ0mUZN+5f+zDyXof7ggYS5fiRKYx3URc4+BBl5VhBnEk5n OtjtTtnFQQObyDzZNL8NHw3S9Yn6FUdq+g== X-Received: by 2002:a63:5052:: with SMTP id q18mr19338140pgl.349.1621955239085; Tue, 25 May 2021 08:07:19 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:18 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 18/28] softfloat: Convert floatx80_round_to_int to FloatParts Date: Tue, 25 May 2021 08:06:56 -0700 Message-Id: <20210525150706.294968-19-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::531; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x531.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- fpu/softfloat.c | 116 ++++++------------------------------------------ 1 file changed, 13 insertions(+), 103 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 1f7260caec..5c4a32bcfc 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2610,6 +2610,19 @@ float128 float128_round_to_int(float128 a, float_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 */ @@ -5803,109 +5816,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 Tue May 25 15:06:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447300 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4420508jac; Tue, 25 May 2021 09:19:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyzuX+CdmdAUv8YjCkVsmQZ2MEnzZox2PJ/kV5+BQ/TRsceXF3sAhf+C6PeqwwGz/KgJ6Qu X-Received: by 2002:a17:907:d02:: with SMTP id gn2mr20549247ejc.207.1621959565706; Tue, 25 May 2021 09:19:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959565; cv=none; d=google.com; s=arc-20160816; b=Qw/Lwe/8sVpmLJqfbIUlqQlNoGN4r1c6CxU65L4BIHGRWNHXCV1BscG+mmGGoM4H4k VNrSBcxHHGG4xItXD0ITi0HQq643xnQEYGtRF3s/n+4Kmyn8oiVTUt7Je1OHn52Tt4kg 6jtmSWK04oA4EDZ5WGHO0FGNAeJqUH3ZoWmoCGz5SmCAVdc4+2jpkNATgixQ2nK7Vh09 zCWW1JymIXa8zi2a3N6DtnjsARFVcxqQG6nKyYpVRTjW5uZ7bAc9cJcfOGevUPdZApR+ E68lXE3tLXsSdHTTnGJA9yaNy9dmqg3xKYGkn7Lq6q/QLTyu/ftx1wU/rhFmKVnloizB +guw== 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=8jY2SfyYuHl84ybtoNE2cXZQw+chD95nctKoUYm9stI=; b=lu55oGPobGoLRwkxjrBQU4S2/fWPHEqUXLdIl475K5qV1el6LCF+YH5vM07LvfSOja ggNlFseeMO1OM0XKvuT5M0trM3y37AV9j7CjcPWwMPulhbYlcTqssHVBDZd4WhCtFk1g 5t+V8Z4InwtQKsA3xP2o8xiOrb7B5dLf++1fm4IdrmHZ15VFcA0Nn2xXPorkm/6CowW4 0fQ9l8caLusuBB5RgUBUa6vU1RkJKUawlOEMqMzd8Kwz4lfufx60YqW55kaEWsm/zXfw 63sUQnLAJZv4HI1OCo43bHpagy/BJnzIsja8y9ed33dIV+StOC76fEIMS5UUKGFL3RdZ fxww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bQUqS0vO; 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 hr17si2120930ejc.232.2021.05.25.09.19.25 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:19:25 -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=bQUqS0vO; 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]:58246 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZm8-0003W4-It for patch@linaro.org; Tue, 25 May 2021 12:19:24 -0400 Received: from [2001:470:142:3::10] (port=60600 helo=eggs.gnu.org) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYem-0002Bw-Mm for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:45 -0400 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]:52803) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0006jx-3u for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:40 -0400 Received: by mail-pj1-x102b.google.com with SMTP id q6so17013777pjj.2 for ; Tue, 25 May 2021 08:07:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8jY2SfyYuHl84ybtoNE2cXZQw+chD95nctKoUYm9stI=; b=bQUqS0vOqDw3/LR9evNJ6tnnltvDc3sAkbLafYw8eF1qKCOi15miBhJ+oOj60fUyG2 MM8oiwniIG0jW7PtRMXJ10dsxaepCMyR1XpPYa2JLoD//UJToOrBpMdBdrChGefcE5cw nAIImZXlWbOUKBe42SAOIF9TPQG6o693NFZQjoAUIco/+/czYXTjbKJfYEpjqbAw+Ju+ uUQij3hCQH6UvKemxKTyU4vwfDnulXC/EK6SIPwB6tpLhNTXO3zyrJ2vbRjlOj4tV4Ew uOC2ES+1/XrDrYUDY951Xc7zDz51sqM7MLj+02lfxOS96Z8f9K8fBKETsyt1cedyUHaE rDrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8jY2SfyYuHl84ybtoNE2cXZQw+chD95nctKoUYm9stI=; b=umI2AhSkzloaueW9Ju7f1ASCO2XhsJBtiSxYCSRZnGD606tCISDMAIpqv0cQTwNT09 QHEFC8cmH9HyMCPzYZFFVjyPvxH2sGx5cQffe1fK6nfVsh1hAl3Ble5zLjlmuNpKTsu4 hEf+p1bIF2f3NA1IWK1bd6GchL/2yd+Zh6JpHDU4VMOxIPGAlcaP3LLJ3cl7imaiAMGJ tzYIjeWi3VCtZaKVJ+jWsThXuz4dPzvRJRLuQqLtZUzHBBiSEX8DB2cAaDvDbJxDvRKF MxutN2Osd6d1f+Ka+bY5Wwb7Bdg0DtVIPtyZ3BmLCz7oGlZ945YH6WHQmg36gRLaQg8E xT4g== X-Gm-Message-State: AOAM532zXIeEGWaNAi/2iqLJ4tMewE3EaNUJsApuwf+4lwGIP5Ots6Bh IZSWvB287kSarOALt81g5Yr4KniYDhZUUw== X-Received: by 2002:a17:90b:194b:: with SMTP id nk11mr30006284pjb.42.1621955239684; Tue, 25 May 2021 08:07:19 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:19 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 19/28] softfloat: Convert integer to floatx80 to FloatParts Date: Tue, 25 May 2021 08:06:57 -0700 Message-Id: <20210525150706.294968-20-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102b; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- fpu/softfloat.c | 58 +++++++++++-------------------------------------- 1 file changed, 13 insertions(+), 45 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 5c4a32bcfc..1cccc40db5 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3345,6 +3345,19 @@ float128 int32_to_float128(int32_t a, float_status *status) return int64_to_float128(a, status); } +floatx80 int64_to_floatx80(int64_t a, float_status *status) +{ + FloatParts128 p; + + parts_sint_to_float(&p, a, 0, status); + return floatx80_round_pack_canonical(&p, status); +} + +floatx80 int32_to_floatx80(int32_t a, float_status *status) +{ + return int64_to_floatx80(a, status); +} + /* * Unsigned Integer to floating-point conversions */ @@ -5036,51 +5049,6 @@ static float128 normalizeRoundAndPackFloat128(bool 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: 447321 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4435632jac; Tue, 25 May 2021 09:37:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxpQvwpfmQAhvG70iQdjYFBgfWEZLyuOdrlUGzeVxA6duWCGAcPi7gy2Aug9lRdXUEafzNW X-Received: by 2002:a17:906:24c7:: with SMTP id f7mr28956729ejb.511.1621960640178; Tue, 25 May 2021 09:37:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621960640; cv=none; d=google.com; s=arc-20160816; b=Z4i4iWpILln5I3ooX/g8IpZr80dyG4phwyzYwtW33n6kwQhQg0mByq2rfxs/c7WyjC iCZJfEzi917CfoL3HiIku50/PWhtQMJ2LYZulvuPmmrce4gaP516uyREbCt9x5TQpXJi PwSGprQPGo8aWSyKXDZ952fFbp6Noqk8TesI3Lw2vVkbLR5KvrSqYvWgkBFQ3kXgjxTZ iikvisVLV/xpk2XKoSYPVpHodoN6S6Yn5y84u2NpactpU8iA/K9iwDlrjDjZh5za38LX sZ1hXimJyURXMcW6Vn7jhSqbmLq9Q1BmgX08JP8JlxNF6xLjpWYScpC+xUCyT/Bn/9UU WGzA== 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=yypiJKlNYeqtvvcjyGW3K32R1pv456DwhxaXAo9XzRI=; b=SrDQl99/CTVV8KUtbTbLpRz42yphM3M1E3g8wJT2CEa6T0GTkBRvXPL6lIpER7BiCi bAVVbY7Ur5xYDAjzIRsA35EmbM8YgtlLlg0CSlNdoYqzIr5FoTT4vxAuTNy7Br9LvVKF azmKD454FQ1+weqTX275jESPTFWmhH+9UKh7DEoEAhVsNDG/96jGA1gR1rGANydIfDZy N4NtvZ3HFc9ltpsg0cDKVGm2pJ2eJXdSUce1OAfUWvbXQVnETBhisl8WtwBBj22eeEHX jx4KH6P45UMHXAnT8ErcKxv2GGAxbfZpmjKhxg/US6F/Vqgx1zT/9qo5sYcYmp7MmdlH k10A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AtBXvt5D; 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 z26si16390849ejr.452.2021.05.25.09.37.19 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:37:20 -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=AtBXvt5D; 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]:55356 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla3S-0006be-Vt for patch@linaro.org; Tue, 25 May 2021 12:37:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60564) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeh-00022P-Tz for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:39 -0400 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]:45877) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0006kP-EB for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:39 -0400 Received: by mail-pf1-x429.google.com with SMTP id d16so23817125pfn.12 for ; Tue, 25 May 2021 08:07:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yypiJKlNYeqtvvcjyGW3K32R1pv456DwhxaXAo9XzRI=; b=AtBXvt5DPAnpkqN4NqH48qf61nydZtbEJEGt6CKlT/0Ee1sgF8khEQyDRe9GIQkHVk YinKvandR2K7JG8RHZBloUaTarXI8jNumYT5PKkNujVaLfC/2bU/lBBGkFg80ih5H+32 s2UJO0PZpSIHLxZRSiDYTSnYlmFJ5G5GYMhwPYGshZ2OrPjsE4aPldAkl3WoofGJ2NFi BSkwd5LwP8LlS9TDAPB+9wcpAKDjwmBgJpTxVJYhQLnkEd7RYZOTcrFiWPDYW0OabD1e TGbsv4X+UJEi7Pm7lE+OtGhgf8BrowNIQv5u0YP7WguROJlcCX8JOFkaNg/qifUStPwC h29A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yypiJKlNYeqtvvcjyGW3K32R1pv456DwhxaXAo9XzRI=; b=l3v9mkycos3JF1SNw8/3YgZEjvfeLAE7ByMnwPfkiV2wC+hEg3R3rWrRx/XvRRl6Ui EFx/ZEvveQhn/Cz4uPFybmBlzq99AEQ6AkuyzxMeEN5lUklnQ8cHD0g5QNK7XbpaBCAz A7yt8adBX1oiClM4o7djsWqNpvhZTbRx8sIKeJDDSAWkBwCe93HXpWpRHDtVz7Dv3Ubr WMaahiKPBf1fNvPdEfPmt8WeRakLmLs6mpjJfLa9/cpl4YjYK2mWcEjZDsiFxL+gHpPG qcAEJadLHVK//w32a/VW2h/ldal6h5eqCNonTDHBntBgN2nnMFyXG1ARcU/LrQFOHTPx jATQ== X-Gm-Message-State: AOAM533x/54VMtYNNGYz+TDn8O23XVu1Kb49LpuV927I+qqoFzm9GxHZ dw48UHOcWs4z0mXvakgZXcu5NN6wjUCecA== X-Received: by 2002:a63:ff25:: with SMTP id k37mr19298321pgi.360.1621955240368; Tue, 25 May 2021 08:07:20 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:20 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 20/28] softfloat: Convert floatx80 float conversions to FloatParts Date: Tue, 25 May 2021 08:06:58 -0700 Message-Id: <20210525150706.294968-21-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::429; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x429.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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. 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 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 1cccc40db5..435be2a0bf 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2561,6 +2561,73 @@ float128 float64_to_float128(float64 a, float_status *s) return float128_round_pack_canonical(&p128, s); } +float32 floatx80_to_float32(floatx80 a, float_status *s) +{ + FloatParts64 p64; + FloatParts128 p128; + + if (floatx80_unpack_canonical(&p128, a, s)) { + parts_float_to_float_narrow(&p64, &p128, s); + } else { + parts_default_nan(&p64, s); + } + return float32_round_pack_canonical(&p64, s); +} + +float64 floatx80_to_float64(floatx80 a, float_status *s) +{ + FloatParts64 p64; + FloatParts128 p128; + + if (floatx80_unpack_canonical(&p128, a, s)) { + parts_float_to_float_narrow(&p64, &p128, s); + } else { + parts_default_nan(&p64, s); + } + return float64_round_pack_canonical(&p64, s); +} + +float128 floatx80_to_float128(floatx80 a, float_status *s) +{ + FloatParts128 p; + + if (floatx80_unpack_canonical(&p, a, s)) { + parts_float_to_float(&p, s); + } else { + parts_default_nan(&p, s); + } + return float128_round_pack_canonical(&p, s); +} + +floatx80 float32_to_floatx80(float32 a, float_status *s) +{ + FloatParts64 p64; + FloatParts128 p128; + + float32_unpack_canonical(&p64, a, s); + parts_float_to_float_widen(&p128, &p64, s); + return floatx80_round_pack_canonical(&p128, s); +} + +floatx80 float64_to_floatx80(float64 a, float_status *s) +{ + FloatParts64 p64; + FloatParts128 p128; + + float64_unpack_canonical(&p64, a, s); + parts_float_to_float_widen(&p128, &p64, s); + return floatx80_round_pack_canonical(&p128, s); +} + +floatx80 float128_to_floatx80(float128 a, float_status *s) +{ + FloatParts128 p; + + float128_unpack_canonical(&p, a, s); + parts_float_to_float(&p, s); + return floatx80_round_pack_canonical(&p, s); +} + /* * Round to integral value */ @@ -5049,42 +5116,6 @@ static float128 normalizeRoundAndPackFloat128(bool 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 @@ -5321,43 +5352,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 @@ -5668,104 +5662,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 @@ -5938,44 +5834,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 Tue May 25 15:06:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447318 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4434488jac; Tue, 25 May 2021 09:35:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwGOv4vWsH04fV2D5dvHMvQHBA0g/63VgClZiz/F4PHMpkmZlIyXGerpapibF4Fci6ygL7z X-Received: by 2002:a17:906:1dc5:: with SMTP id v5mr26641438ejh.212.1621960558042; Tue, 25 May 2021 09:35:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621960558; cv=none; d=google.com; s=arc-20160816; b=o5YiFqugp8GNi7Wq86fx2a45tGQZ/lGGaKBt3RiMkbGi9NJjw8KfUclL/bsNL4UJdN BwvTc0mVTbcbhmgvBsFSiqzFqLlDgzXfHwckfpH6MV9v+0IWf3MkHP/9qPhpGlEErdRu t9FD8+eoR095rP2grZZynMxif/quZhA1AKIAPJzW4xN8CiqAFuM/SDRAIRIG8Hi3yJ4C s+zi65TYHchzodYZii6gAGjkPI9qykUhdQI5R1qTHKSWOvbUzkx5gaDMQYbRj8BLCVDe ofhVaIR/eTo9hstyFyrecswnUsoxVby5aCY0PNej7fL5fy77dYn0mndaqMSKtovUkhPR OXnA== 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=CI/R/53O81mXWi9nTuhnEYZUkbwrVqzqCqbujiTaNEg=; b=tnIvn4jlqWFMBcXPfNjwS9AGMcQlrIAbVQGDXbV5wEpc22Va8RFY+0SFR+Atjp6YaA NoCAAidRR6Zig+5Ixk18/+vfjPdZtWDd/TiHE5590+bwrNmQW7f8LxmlC8nY6x9B0iXH iQy92wB+hn6xwPOtaWTPg8VeHQ8jT081Zulk2ydYilBbTtP5jVW8upIiyWAFHOT297QH j2KG4a1fsGozidh2KaC4IkBtHHAI5lPyCCf95G7Nr+WQRF6J5Rt6fKm/XiwaI9jY+w9I v3cLKqfGke+ssAesLN+3u+E0h2ERRWMMVb8oj7VPVTg5i3fIihOtHFLDQyzhfpMtCgdP Z+ng== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wnQiYUJ8; 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 p5si17672776edt.116.2021.05.25.09.35.57 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:35: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=wnQiYUJ8; 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]:46846 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla29-0000jX-0J for patch@linaro.org; Tue, 25 May 2021 12:35:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60550) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeh-00020W-FE for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:39 -0400 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]:37875) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0006km-K1 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:39 -0400 Received: by mail-pl1-x62a.google.com with SMTP id u7so7928776plq.4 for ; Tue, 25 May 2021 08:07:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CI/R/53O81mXWi9nTuhnEYZUkbwrVqzqCqbujiTaNEg=; b=wnQiYUJ8E86Ndlp0TOSzjXXk/6Ril2ez3ITu9iluONdOOe/Z0EXK+QHNd19tBovTQ9 I1dWSumbnLfQ5rswhRa0POpmG3NYE5sg9/NB/BxzcPzcieyUV/ooPIUBmNqUBrGcuNv5 EC6/Zh9PpFnsq/DAXObPSHHNBOdeGwP6OnGg2eyGMgNnYCa9Y8zAt7qMjkvX7X2UK4QG tWFe0G20yavm+rrNJ2ihDPy3QOsGN8sdTxEUmJgXUu0w3/nmFggMaou5yhMSLb8AR3RQ R4w06ECQ5K1VZhvXZoN5ZCuEJZQQ75qLEZHyq/pknWxtZE6MGJxFy4f8nblNBUGgvG0o bmjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CI/R/53O81mXWi9nTuhnEYZUkbwrVqzqCqbujiTaNEg=; b=FXqf3F587FT4t7Ope52ri4wmkzhbXioeM3tIMU1U3S3wSNSTEDl3VGy3h54L5gZZHe NP69u4/xYudRE4aCJaDwyzk/XHPmWoX/hmZjgisTwVpXz3SoSX/Ac8AG9xCRGrdJiRkN bJ27NooNk7EsUt2nl9SdQHSR2CULFiXMNaElrCP47ujCusYIECr0YqLusIvSWLOZCSH9 Poj0lRVSRwoTJuhDWT7FlJtopXvLmsjU2995bjIV0OY2HkbHyBhtFgR0NelQL895yurt TgODQ8NHMQ0akBZ1jG6YJ86IfY1+lrdC7g9udr8Sn88FQ4dr7IiQV5spHJXqpSBs6vm6 VqIA== X-Gm-Message-State: AOAM532nftglzpHQWy8tJ4EtQHCuj8D4CNAfFaeebQjx5tEzAUcjNo8M rL7XZhSnrmcFNtpMMUyzf2Tvy070Qt9w4g== X-Received: by 2002:a17:90a:e2c7:: with SMTP id fr7mr31156346pjb.145.1621955240964; Tue, 25 May 2021 08:07:20 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:20 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 21/28] softfloat: Convert floatx80 to integer to FloatParts Date: Tue, 25 May 2021 08:06:59 -0700 Message-Id: <20210525150706.294968-22-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- fpu/softfloat.c | 336 ++++++------------------------------------------ 1 file changed, 42 insertions(+), 294 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 435be2a0bf..52a9aa1837 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2829,6 +2829,28 @@ static int64_t float128_to_int64_scalbn(float128 a, FloatRoundMode rmode, return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s); } +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); @@ -4163,127 +4205,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 @@ -5489,179 +5410,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 Tue May 25 15:07:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447322 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4436485jac; Tue, 25 May 2021 09:38:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwCyyq2s6RFJlZUpq89ugNUrz+8/9YWMP1oO07MB02FENCa63PKTb/Ah7EgzjhzggrCaQOi X-Received: by 2002:a17:907:20a7:: with SMTP id pw7mr29983071ejb.39.1621960703143; Tue, 25 May 2021 09:38:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621960703; cv=none; d=google.com; s=arc-20160816; b=DXINUReuiKVwwLwHrp3Gp0ZJa4GzIx6GX+MeVNd6zbHXUbTnTW/u8G93BOFQqXE5AL mwxFgf0YDbeGQJ7criZEpBwciXc4WtmDoYnQZy0fhtQlDDG0dg+0jKEkN8tgDFq/FB1Q 0Huy24jOAdu6rifmG397G3OrMgMSGt16zl6vFBw2UPJQxP4JT7AsYstocYevh7W89jaE IOKOgff9c8TEs8BfqED2OXfCi4YsYOJsRMx7R8gTrK/nn0/Q2GIfAJ+ogYk9yxkSQKRe 0r8vRXPgvQBjrNkQviPcfHCfIhJiFL/8x4LkwyS2czHJPnjsRUd2G7WwPdpwYNzWSSUQ Z7jw== 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=2avWxXahubZ/o5oT70KgFRqpsBXSFNH/Xke7KM6cuMA=; b=wDWVLOIiJnUpudhuNLeN2oq0RBuauxp7JI5dr0tBq/DoIhkOjEiT7izQ/YSOMid8uw u6Ur/x/JJ3U+7110Ie+wD0odOzPQrA2LMCIxPxwFieqpOa/241y+JSkJ2XevWU2bMlO9 DKPWBl3ASKmwKzhAaxP5f/d5J27Xi04dVa7fs2z1scE/iY7T7E3AhmQmW0Gp0aKKKUEO mbG3/tM++6tPRaHXMfkdM2J/6pcJBxTaMYJGlkHPycAcqEkJf0n2lQco0cGW24diNc/I i5ekbvWxXC0TCbZbEcLXNKhWM/rlzshbqf1mIMhMeNbpnvieEhv2MK8gBkEyapbXN+Z/ rnFA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Em9r4PRl; 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 x17si15513506edr.496.2021.05.25.09.38.23 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:38: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=Em9r4PRl; 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]:58512 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla4U-0000K8-58 for patch@linaro.org; Tue, 25 May 2021 12:38:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60546) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeh-0001zs-9q for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:39 -0400 Received: from mail-pg1-x52b.google.com ([2607:f8b0:4864:20::52b]:36532) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeQ-0006kx-WC for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:38 -0400 Received: by mail-pg1-x52b.google.com with SMTP id 27so21669979pgy.3 for ; Tue, 25 May 2021 08:07:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2avWxXahubZ/o5oT70KgFRqpsBXSFNH/Xke7KM6cuMA=; b=Em9r4PRlDFRSDkqXeXPAwGjl2ne5ZDxYhGOCvwdesdsoZLz40VrS4/qpMTaTR7D28T zvb5x/UmhiUdxmJW/tD6Lmy4to6NLI7FJz2e6aYagZTj5zvWESzG/om2aR2BxWFMwr7A VLZMIue2VNiVGFklFwkTr3+TLW9SbEMBGRsGtJnGS4qLR2gDKkQZ4VZHYag01rJM5mJh UxOsx9ql05D+PIMbQH5BDVvG0O9uSIjycSqWrjjojfS/o5nVFVVwyyHmGeaWlBXlkcPa yKztmPls4bApMkNmNu5uhVDQvSZTIhL6TDsWaSDkRrVd3K76uwcSaxXL4ufEDILpg7Y8 j0IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2avWxXahubZ/o5oT70KgFRqpsBXSFNH/Xke7KM6cuMA=; b=KiFF3KTqGepo1nhr7YkrHvCaJaXfnvO4RR6krMJS9EgyhMA1zrXcbTinnCtx2nIG67 s5VKkpqGu49XGTWszStU9/yFjEGzdwmESd7GPvt7YEYmBOuMTLAYA3J112Vt/aLsTtUI UDwL2t2heCdrP47izOOEYir/4Zo25NhLU6VSe4F9s2ot1X4qNElMyHrtjoC4Enea68NX NrCwt9P40apccDFsz7OgILQqH89MhMedokf993bDvBR3rE7mKKs/7O/5f7DjZHPFEo3p OGROTnbbw/V6wugL+L1Ai5rYoQ1uxa4n+obdgf/fa4kXKTqIli0ZeLdGn44d8LJyEbIQ pysQ== X-Gm-Message-State: AOAM532ebBJ8Z1uqZdPTo9US9OG3F1fGm9vVYrw4YgkE9O23J5Fqba6m 9x8G8GS5HkIHqzCwlkTN6D4OeO/tLKSQWQ== X-Received: by 2002:a63:1953:: with SMTP id 19mr19377649pgz.273.1621955241568; Tue, 25 May 2021 08:07:21 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:21 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 22/28] softfloat: Convert floatx80_scalbn to FloatParts Date: Tue, 25 May 2021 08:07:00 -0700 Message-Id: <20210525150706.294968-23-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52b; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x52b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- fpu/softfloat.c | 50 +++++++++++-------------------------------------- 1 file changed, 11 insertions(+), 39 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 52a9aa1837..0d1d9df70d 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3914,6 +3914,17 @@ float128 float128_scalbn(float128 a, int n, float_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 */ @@ -5748,45 +5759,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 Tue May 25 15:07:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447324 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4438185jac; Tue, 25 May 2021 09:40:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzYMA4G8ww0DlzbN2pMZWnKhW5DdHtXmxqoypFZAKXf1OXiPJJx0IfmqnrsW7ChtHg4vFgu X-Received: by 2002:a17:906:8690:: with SMTP id g16mr29784445ejx.315.1621960825357; Tue, 25 May 2021 09:40:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621960825; cv=none; d=google.com; s=arc-20160816; b=pFRacnhnCIO4e/8Vy2p2ODik/tka7NwtFXYm8ML1J6LSnBTYUvBoTr2mDPAaMkeu5P A4Sh5iX9AUzs9MudM7q4MbjV9LA8kgkVVuZJxAPmFfARVq/FGnNt1Y1AfL2A+Kdf2mDa FcN/QUP2CChUId9T3jLzTdON0etX2hnnUfDxB5mf1hqCB3MoeKxEZCvCNABhKene4NwG kl7QO56PKohhWJSAmxvPPEdMZdPr7QOq0LbQU/ikJT+umFg6GwmPf9VMG6gs5AIWKMZR KE62Bqzlxq/TNzTW9ZhS0WYri8soUIa2tt2dlldh2ODXeS4pZAntCOIF+tVqiDDOoKlk xNvg== 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=ytofR8WbQtEyPToJLhefg0tEo9cYPt2fZe6o8phMK5E=; b=VOtgwsYpxkyNSQk+QOUlq8yGU50QgFo7MX4GVM6xd/MsfxGTxap4Js2AY5ei0njnff DfoQ3VkCNBZe1fnpabdP5TZNYrjFeAAQH6eCFktXiND5YFWLZH57PWdiA6nujr09NqU/ zcgjvkvOAUQODWGPq8xHYmOBgqQVMnQxnz4ZX7IcivFpOQd4ZPg0tnz+R2/HthfVuuaD gQaMSSPMXNlGwWBRiAemMuo9K25wczPExGE/lR75SGO6sF/KyrhcKUZuUqDt5g4Jpbl+ mgBv5LFC3nWNhUw9BMljx3pn5G9aiKTLaj40PliyXj2OdXqV775zuwg6RThaHWXeT2Aw h7XQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ep7y7vEP; 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 n15si17578443eda.51.2021.05.25.09.40.25 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:40:25 -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=ep7y7vEP; 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]:35794 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lla6S-0004Lj-BN for patch@linaro.org; Tue, 25 May 2021 12:40:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60620) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYen-0002Gl-RN for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:45 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]:44867) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeR-0006lB-DC for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:45 -0400 Received: by mail-pl1-x62c.google.com with SMTP id h12so4336579plf.11 for ; Tue, 25 May 2021 08:07:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ytofR8WbQtEyPToJLhefg0tEo9cYPt2fZe6o8phMK5E=; b=ep7y7vEPA+LFrDFCm6qfcE2P8K4IkD4DbYegf7nsOgXgKJum0OHHFMaUU5E4EEe7Bh 3gEJL160OWg3I7kcX/X40N4CCUS5/RGaFR6nMVV6367dwa9LZKwyyc3aG6EDhLV1VKWR bqCOq2ZxFiP5e8aXY0b5BgcjrwsCKxGCNspTr3SixNSEfgysvR/T9hX1UKOCPZDjOTEl 85SOmKtYlsaFHczf+HLsQxIgC89lCS6uSYzLeqjlHVt/dR2B0+9xvwa4D/FwRWZjoM1v LIB2oSYE+hQK1Yvhhjei2A1xzMg0OThi752GSbzfkEimdZ8248qS+yu0GpHXWq1chexo XJSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ytofR8WbQtEyPToJLhefg0tEo9cYPt2fZe6o8phMK5E=; b=qH/9Ke0Qkj/MPK+Anzouar8jCxN5F7aQ9AfYN91khIH1L0ZwR/Rbu+7vLNGL0YsqJw 6xS0LLGvOOmOONpoVn9A1nk5Cdz3PcEw/D4H2M2kIcfppAnbQbIgyLwzS7JZR8Eim2IO WuI5c6hPmnZH7RAHvBxYeFRd5A14iDCUtox9voqtG4mMWdrOQyphBi6R4i2Fc+pMsUXY Bx5u75jWo1djxW0wvEPP2qKLIs1Qmg0YWy7c53cGWIyDam3o79ZJ07SEKJqev+dSkmVY UFA/6Oj78bB4aMLZ1nSi6APJ1iRccs2FHoT/w+jIk/XCuCTHvyPNNT2ATfCMRzlbsFUe 74zw== X-Gm-Message-State: AOAM532wvOI/sf9bJZ4ehhcH4gZCk07QektbrnCTRP8YzoiSIHzD9Tu4 b0y7rn5LWu18kPCmkYIkc6CLWT087P+AGA== X-Received: by 2002:a17:90b:201:: with SMTP id fy1mr5198437pjb.119.1621955242132; Tue, 25 May 2021 08:07:22 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:21 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 23/28] softfloat: Convert floatx80 compare to FloatParts Date: Tue, 25 May 2021 08:07:01 -0700 Message-Id: <20210525150706.294968-24-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- fpu/softfloat.c | 82 +++++++++++++------------------------------------ 1 file changed, 22 insertions(+), 60 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 0d1d9df70d..b86441d0c9 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3865,6 +3865,28 @@ FloatRelation float128_compare_quiet(float128 a, 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 */ @@ -5699,66 +5721,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 Tue May 25 15:07:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447304 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4423113jac; Tue, 25 May 2021 09:22:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw60xPHnouJFWOatGFU3UqbYBZcte0IEErV2Qz2FtX8NPajxukzQ6wffSm1/KZmec5nd/k1 X-Received: by 2002:a17:906:9a53:: with SMTP id aj19mr5108161ejc.32.1621959742298; Tue, 25 May 2021 09:22:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959742; cv=none; d=google.com; s=arc-20160816; b=kydOKf9vvUo7I+VgiNAd6YUjPgOvakl0Rez2vHwy8VU6JBz4JJZeIiG5mEg//Vdqa0 JeLZ+tA8QL/+//sfQgR7Tt5oLfLyzjIbNpsfh3CrKqAOM6o+GnNCZqvN4tBaIBrR/zFb f6idCJqq0KsUdUGj0OlVYiXBtm1KrZIqAdiCezoyLHWw4P9A8/XsxiZVYtdGoR4+/o4M aLY2EpHvYh/65oRdBommoqnDsIQyF8+oOBJzIB7AK0tKrFHJLjOsj91/WYRgIbXbbgbP FtL3vr2gSjSKf2DdeJlCHU2zXLpLF6jAukVSqhojiV4GdH2Z95jMkQRmB6SWjlz91b93 JljA== 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=oFUF30PagAXhKM0dixbmpt9CMC+0KnqcFmUJiQifWoM=; b=0lU1nF9SRxEYvFadQ+rEPgOg9PPHoOjL/SPBN8OqWDzUsLtIv54cYJ6L/nkoHz0OnJ jx2doWhLW4oRs9MJEhFWcWm+WOPkPcfjqeIT91ShTMgTOXGpEWMYa4NDbezsQ8Id37iY VUk6QSqJA3sp2YQDiFkwXbwRj0TJd5u3wLn8vO+NXySs6b9ZPLx75yVE/b8E6vzh/h7E VTDtYiatYNbV8eLgeXQyy84shDJLPdkwt/B6n5WU8/Wf6jXxxmlTDWuV8y/PLYmOF5Fe YpN4dYM6d/0FK/PLz/+pDbL2mFMv+it/uuVcXWnkEA5r0M0AKiwpb/OVwUaDOYzvlbrV L8zw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=PMLlTlkv; 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 y97si17784450ede.37.2021.05.25.09.22.22 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:22:22 -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=PMLlTlkv; 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]:39742 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZoz-0001ev-88 for patch@linaro.org; Tue, 25 May 2021 12:22:21 -0400 Received: from [2001:470:142:3::10] (port=60606 helo=eggs.gnu.org) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYem-0002Ag-Gf for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:44 -0400 Received: from mail-pf1-x436.google.com ([2607:f8b0:4864:20::436]:42643) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeS-0006lb-Ez for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:43 -0400 Received: by mail-pf1-x436.google.com with SMTP id x18so19535009pfi.9 for ; Tue, 25 May 2021 08:07:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=oFUF30PagAXhKM0dixbmpt9CMC+0KnqcFmUJiQifWoM=; b=PMLlTlkvPOWxRykFfR0i0BtrNbCKbeO3YwHzCKjfpPtcrz7amfVClToEdEsSuvFlyE xfUBybHPo3OVYeZuq0MIn4BAV+MQArljh6BbHyeKctJu0gPOE3+GHU5BZZ85Ooobw6ds CrOjlyFAdYDepHE06qhooXCaqXmP3RL6Xn4nBiPSoou/+ZyrD8YxljfkJzqs7y/KOsBX 1edgB5l8wpRRbVjbANoplrJ2Fs8Cy00wZcYiTCV4v8F417BZt0fzsynui+zFj81o0bYi dQ3g0XKawb5s6u5ZtL+IYByy1IxV2G2viLmRjCIL0ewpi0Wm8BQG7JIgnQbGZE1LQha2 GNZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oFUF30PagAXhKM0dixbmpt9CMC+0KnqcFmUJiQifWoM=; b=SEDggpXtDlhA+hLPy2RThcrvmGAnOt1bVPo8YqMM+YiySU5EcDDsYGVioOislrY75N Lh1UDJM4IVmqif3E2g4G28B47U4hJ4iz2e1X+PKukKqDysHKs/D8PiqlNi0d6Kutv3wl Eqzyp93JALjeOxhtgPFJ+IV0idJ8kTR5ratcYr3DcLxB0gxmv4SsQ/BMkWYm6A37mNoI G0c0odVsiTfPKqxfNro0kscFQEAJOa5O5E2VE4/2eUJYxD5UuXUgDpxhXMes6GcWuZhA MzQjy7nOQGUE2GTuIxV3pHDnvCmmHhgSyhFhMFrACbdCSLl90Ico4Ezgf9x48IWjN57O +CAQ== X-Gm-Message-State: AOAM531FLtUp1Mf0i0X/CliEkiVVKDzs+QtN2kzCG54iwG6uanBIGbXH tvtHmqrYRAQN2gh4ixkN9r/2mHrWO+kYKA== X-Received: by 2002:a62:d447:0:b029:291:19f7:ddcd with SMTP id u7-20020a62d4470000b029029119f7ddcdmr30705548pfl.54.1621955242990; Tue, 25 May 2021 08:07:22 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:22 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 24/28] softfloat: Convert float32_exp2 to FloatParts Date: Tue, 25 May 2021 08:07:02 -0700 Message-Id: <20210525150706.294968-25-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::436; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x436.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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. Signed-off-by: Richard Henderson --- fpu/softfloat.c | 53 +++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index b86441d0c9..c778b96c37 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -5213,47 +5213,40 @@ static const float64 float32_exp2_coefficients[15] = 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 Tue May 25 15:07: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: 447303 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4422377jac; Tue, 25 May 2021 09:21:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz3UNi52xh9HGKxSEItzgfOpS6nHbixdHYp4i7JlKBxxjDDpWYWSCvWG6+6z+nl1I+up1Qy X-Received: by 2002:aa7:cb48:: with SMTP id w8mr32868046edt.12.1621959692256; Tue, 25 May 2021 09:21:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959692; cv=none; d=google.com; s=arc-20160816; b=Hwzc0YkEUrcnlGzKKj29sNfOPodFHZti3W5TSnpRrO+Sbic6rd59/7jqKcIdNgJgtv TsG5dhmm/RSMjauOrHJukcwtZfx78m2AdhppvUxzSY4B8sNyInzjNCC95oQCbvZg0ZE0 W3mXDo4EK8VYxEdTa5qGzjLKo40DwBAx3EaudCb/T+EF/VPPsaen1TxpHLuiTl3OO13Z xHvsA2Ew/8usQsY9GS+Qhv3KwEFReiPOuj4FgxDZFJO4DXyuVvWNAT88YRZnq4033DI7 lruFh1A1+w74quYyJ3vq9zimPrjsmWjHhUNF5zRsfALt+2vqSSIbvZQHTW2kSVeOqVRw Bfuw== 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=jQpxV55+RReSCj98NiG+0x+49ehVUqcsxXmjl0897cY=; b=yaQGLD0hiqR76uAH2PyRa0i/XeDBfdbmkahrO3QvPNCrUdZZeE8gXMzqqmdO2xEN4z 8yyKzYuXyf+aogWY2VK2idoPBU+PfJN9qmp5d0TmiUkFLsDS5gdA6c7NT2h9baOFxrwu a5AF0SRwRFmDNIXnjS+z4/ZXOx9oe+VexF3Xl9J9I3TcGfMuyGBTvgksqsCqymDD/zns iPRsm4hys5nET6Wn5WjHxcpR0YrUWV048GmQvW5lRk9nnfCB+bhyhQaSYQjIGKoWfdlm X5U42OMaT1diROzU7WbVz3ih9RGNfyAkHSdrQye2kNvY7aaL/RCnNqfdWictKRytCQHR x3ZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=z1ujuaUz; 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 c10si15317017edr.581.2021.05.25.09.21.31 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:21:32 -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=z1ujuaUz; 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]:38720 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZo9-0000ze-U1 for patch@linaro.org; Tue, 25 May 2021 12:21:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60608) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeo-0002IZ-8a for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:46 -0400 Received: from mail-pg1-x532.google.com ([2607:f8b0:4864:20::532]:40716) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeT-0006mX-H3 for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:44 -0400 Received: by mail-pg1-x532.google.com with SMTP id j12so22967800pgh.7 for ; Tue, 25 May 2021 08:07:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jQpxV55+RReSCj98NiG+0x+49ehVUqcsxXmjl0897cY=; b=z1ujuaUzcze3t2NvVDYvdKf9DTHfi25W2Zw3krekGLHTyzncoWbH0bNS1gPaA3IUJA AhIc+nzeYFa6FQjX6BqnL8Kj6SQzl7oK+s8We0lGCtAJN9UNoIE+RhRslSdKbQigm6uX N7t2WdQ4UVgRTNbtypVb/8VRs/ADh4IpQuFsNLw3cka7yLnmPxaofq7PI50GGqmVlmuY tjT6qPTXFh4k3QUu2xzfMf2mGfNNUP7IMhJptppsy2E6CP3+M2zmTvb37m7fxUi/S4X4 7ZCopupJ7EYc4vtqrP1iEPpzRYMig1Vd9/LohrfBCLDiDcXn57fcYtqXJ7tNOicgYMfn /+Lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jQpxV55+RReSCj98NiG+0x+49ehVUqcsxXmjl0897cY=; b=Co1az95RmtfR4f/S3wgB0ItDXa9Ns6bQt25O6BTkDWv4SguSekvTVIkH5fUFReUygB qnfIgMl/+NDzrvWyV1N9Pf1UIo8aYs0UyOm/6tUYPr9hYfAVJ6kJktCJJ3/GxEJ3x6oX PXqgbh+FpRg4Bk7YNf5/BslSYFO7IfjownvnBIsrD6cE5N+suyPSaX97SxBfzsUJICO3 1/dKWoFvX1FseGBRCUHEW7sHldWOhG5JS0HMAHWLZZT0uzTlWbZa1RDJ4CP5m00fxmyK 89LLgIyJlAB7dVVObJMNBa7e0GIWodnoyQ5KNXJR6yd1w3mm2u2mKWeO5euZd6NCqs+q V+zg== X-Gm-Message-State: AOAM532fSvEtndCRnpEEIb9x9E64LIT01Xg9h1nHs/I5Q4tMeojm0txX 4VYZ9IEm2YTBJJIwIapgC/eoDOhNanvV0Q== X-Received: by 2002:aa7:8a18:0:b029:2dd:42f3:d42f with SMTP id m24-20020aa78a180000b02902dd42f3d42fmr30494585pfa.70.1621955243828; Tue, 25 May 2021 08:07:23 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:23 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 25/28] softfloat: Move floatN_log2 to softfloat-parts.c.inc Date: Tue, 25 May 2021 08:07:03 -0700 Message-Id: <20210525150706.294968-26-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::532; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x532.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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 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 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index c778b96c37..6d2f606b39 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -927,6 +927,12 @@ static void parts128_scalbn(FloatParts128 *a, int n, 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. */ @@ -4063,6 +4069,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. *----------------------------------------------------------------------------*/ @@ -5249,56 +5276,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 @@ -5387,55 +5364,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..8ad856509b --- /dev/null +++ b/tests/fp/fp-test-log2.c @@ -0,0 +1,118 @@ +/* + * fp-test-log2.c - test QEMU's softfloat log2 + * + * Copyright (C) 2020, Linaro, Ltd. + * + * License: GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#ifndef HW_POISON_H +#error Must define HW_POISON_H to work around TARGET_* poisoning +#endif + +#include "qemu/osdep.h" +#include "qemu/cutils.h" +#include +#include "fpu/softfloat.h" + +typedef union { + double d; + float64 i; +} ufloat64; + +static int errors; + +static void compare(ufloat64 test, ufloat64 real, ufloat64 soft, bool 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 8a7f22d6b5..3fd6d97fa4 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -1331,3 +1331,128 @@ static void partsN(scalbn)(FloatPartsN *a, int n, 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 Tue May 25 15:07: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: 447330 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4443337jac; Tue, 25 May 2021 09:46:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz0gHlcaQvfkRDJctrS1AlhsVH1nEMtp25bklS4MUFRwG4cjN3zJ0AVX0FSk49mFfyGlz8a X-Received: by 2002:a05:6402:1518:: with SMTP id f24mr32360690edw.217.1621961196219; Tue, 25 May 2021 09:46:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621961196; cv=none; d=google.com; s=arc-20160816; b=VW9d1IjiJb7H1TgKRxWovw7ZPZMFDHJMYHYLCWzqb7XhbDzVhasXHYu/4tB6jX9NyW CP1ZwWDIm83/U7mU+kUYAG8+xKVyDwIJlWFEcgnlgNq+ZCrVQmnsIxEsvPacV6KQ0ZYC WWbLDIUnkMqg9daAKhud7nVzJdN7L4mKycdkOpyBKmrLloS0bNkVC5nC/bSVYNDilDda beIM3rkze1eV/9WQfdJpTdJAuYUAVm2WSL3wJnQt96DGjsb7TTpbbRjVyrJ9iNR1IJnG SmS+hSw/T+MTN/gt92rVaiNVncK893KI0YP6PWwUemQF8Ir/Z5Uy38CTHZOtwjPHO//U YQgw== 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=WhF1IZko0dh1L7wch1lEVaycxOtRYGGaXM4qmB4c8Jw=; b=fuLXleur9MZ0OOwYraX8qUB3xZyxf6K/wzFZItw2O6YQ+9VpNcATW9OpN0Z3TubJ58 9iFcL5KL2KnvbssG9uJJIPLovfNQZ8M64rCdn5H217HWOOrZP5jUWWW9M5lFF7bhPQ5c mzMn39bRnjdG5JoUAt1RyR7UrOoPefApyzzTqeom95LhcNJD+XTI6AJqK+FTjlbZ7s76 4vA4K7jTDMtp/c0kuAwArbFRWOQaBYBPVmtDSpy9negDEGJ5f03T8xytTIN91mMePkF1 REf/kRqmbQpnTM7+8sPyhrPovZ+DcDG2ysgCTdKixDi7hKKEkG8C/jW9FOE2kdCG/z3Y ki4w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WvkHqyx0; 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 z27si17058842ejl.41.2021.05.25.09.46.35 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:46: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=WvkHqyx0; 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]:52950 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llaCR-0007lv-3N for patch@linaro.org; Tue, 25 May 2021 12:46:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60722) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYer-0002YX-Sm for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:49 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]:55252) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeW-0006nS-Gs for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:49 -0400 Received: by mail-pj1-x102f.google.com with SMTP id g24so16993140pji.4 for ; Tue, 25 May 2021 08:07:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WhF1IZko0dh1L7wch1lEVaycxOtRYGGaXM4qmB4c8Jw=; b=WvkHqyx0Eqt1NaB9sWKfCrch/4EkNz+X7RN5XqKP76+Su+lXe7/2PlAlLK6CwVlL5b XkfUhWhVk0hqosWchK86TxynMjQwezNBa+ZpxuC8iJVT6Q6kvLZJ0ex0G/YNZe+85uDQ HFl/8hTXHTZ5bfszgssCSIfbK1iX6nQQ1KrnFGvgTvNNunjARjZXy3GLkAyyVC6bLEZU OIPLmOK9LVSDWiUEP4gqyLrhA97BqFCUQJBnpZS7yXTqsIvQiZGyxl/y901F5N/jix0z hr3w69VnUkGgouZggNp5SI4Nr5bOERfiDW1kBrRvtShkiX5iJlZGsPBffobxpapAnnCU kOKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WhF1IZko0dh1L7wch1lEVaycxOtRYGGaXM4qmB4c8Jw=; b=SGptxK3v910aIVeYqkqr4zp4/s4qqk3t8CT8Vd+N+/y2UJucYQYQ/o4KKZeAnbikrb K1BQMmfTqcPeOCs9McWF965Z2v9Tid2JzBiLnjxElssChBJLJ+SVKarLFuIWmiTRENMC ykJYc/fSKvnRi1csMTapr7Vq0IVpPxs2bK8xUWPk/t6Aj9dZ6DcDACPWIGmzmizjbsB2 JebWoybchxzXdjnB/4WUZgnpb9bfGPnXEdlKlKHOKe3+grH/qXOR7/QrHMQymq8VJL/R bvBV1Hp5rTJ73ose62cgTmfoIZaJvYeK9L6/QAIZB1C2O1pdHq85u4lT529U1raP8NVt nC2g== X-Gm-Message-State: AOAM530YsQcbK54g41RCypAE9C6O0CfYDZk8zscJ/Q9VB2Ur7cbmSpWT 8JkbtlmjWbDvs9llSD7OZTc3CCvpOn4PnA== X-Received: by 2002:a17:902:c784:b029:ef:b14e:2b0b with SMTP id w4-20020a170902c784b02900efb14e2b0bmr31381059pla.64.1621955244743; Tue, 25 May 2021 08:07:24 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:24 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 26/28] softfloat: Convert modrem operations to FloatParts Date: Tue, 25 May 2021 08:07:04 -0700 Message-Id: <20210525150706.294968-27-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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. 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 Reviewed-by: Alex Bennée 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 6d2f606b39..b0df5b6dc5 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -401,60 +401,6 @@ float64_gen2(float64 xa, float64 xb, float_status *s, return soft(ua.s, ub.s, s); } -/*---------------------------------------------------------------------------- -| 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 * @@ -4265,300 +4472,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 @@ -5276,94 +4807,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 @@ -5382,266 +4825,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 3fd6d97fa4..801aa86ff9 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -625,6 +625,40 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, 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 Tue May 25 15:07: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: 447307 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4424200jac; Tue, 25 May 2021 09:23:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxblEhApzCktKzyNSvbgkd5sk07EDv2F21A3HKBiQm28nQ42UzNxOh+/XzoeAgxGfwExlOj X-Received: by 2002:a17:906:1444:: with SMTP id q4mr29799629ejc.459.1621959823321; Tue, 25 May 2021 09:23:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959823; cv=none; d=google.com; s=arc-20160816; b=U4siqUtSNzui5K4ZCL70CirMLZkK1oUC6Vk/Q1q+dXfRruGJqPrtyBgD1GIOzzAk0o 4wUkLm56YObJN1cBTEIYW/7em2wkHsaNloCpBz9it0ahpoCQoM+3V1SSYvU400M+i0Hw qzEMXFj/TP7x2osaFq24ufU+DRUq47DBk0qoLFX27r9B0QMM6dvTP4mX4Z6vDvu3OlIc D1ccGMdvJZlEln3Fkf4GC4/6xzta0Fju+nGeV2pD3BPV1ALNrzUH6ABSs2cvNo/cjxs/ FhB4gPs8Bp6Hyav1rP4kgfwAJB5ZVdjD5h5QqRSnEN96W8KVdNlPzgmMtbQgqkUZp4XE P1/g== 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=NgbPyjOH6VaewfzzGoqyPl9EUTeoa2IvuTIuzwf0t4uxPrlLrdNkwOlFMiM7C5jR5B 4sLB/ufLw8hI9j9JWAxTCvILXDgF/X5TjKALEcHghrJh3ys5/6NATFB8H7CcBaQWfMww UhYa6D5unKScx3K/MYxlbGAaA1kgwzWL0dLc2AsTowJeYI6v1irLccTLS7ktytlSBCsH RXJdU/b76GlaizVhgm+9hpGoeVON/BATSz9T02TPpJcMeG1A6sZZ8hIZ2OZvdsMup5lW vzpj2r0j5RGpalyUBSaP5b+fW58QsCB8Jr8rK/32o97yAWbZuejqioOZLcgzrLrRyxJH WaFQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=U8vlAa+C; 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 h35si16747821edd.312.2021.05.25.09.23.42 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:23:43 -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=U8vlAa+C; 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]:47634 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZqI-0006sG-3B for patch@linaro.org; Tue, 25 May 2021 12:23:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60650) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYeo-0002Lk-TK for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:46 -0400 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]:36707) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeU-0006nD-Nf for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:46 -0400 Received: by mail-pf1-x435.google.com with SMTP id c12so12247783pfl.3 for ; Tue, 25 May 2021 08:07:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0sbWGfdi+vZU0+T2mHM/iN4YQ8XRnXrlumJZuqrhiwA=; b=U8vlAa+CqUqKsS5kvTd4vH9kS4wTp9q+Jxb6pGIzpbSgvDSw6fd/MMWunDL+NLsG26 TtVMeR7PxC9+iE0/15EdBl5MnU1lTNQ/MoTkrnL385fNBfNYWFCU1X+LwZxSueT28lAF zpXu18aZTFFuKLjlyUtcuMvLquygWFcP+dnIoOgnGwecLv3CQLDkxvZL6Qw+rj9Z8zS5 JV3PNkLHD/vyz8RtmKCJLquLW4oCbIHJD0mwgmGjAu4ltG22W3tfQSpV8H5rJ/rDxvrE iwFudyL6pLWLbgIQ6NV83E5IeqObcWCJVSkWpWT4Ocm1jnH/ZBVLth0575woq9XTS15i Mdsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0sbWGfdi+vZU0+T2mHM/iN4YQ8XRnXrlumJZuqrhiwA=; b=tNl04iwYZXE8qSL7AmA4WW0pLrTjuejhQCMt7GxIrJEkY1G9zcUL+4EvlqgpuZgoXu 08f4VXe6+RPXqxLdLTQ/9+v6qrZ2QT2FpVtOGazmTKXymz1EbVlZLA91y2k1ED4G8Mzs l6o/b7lPqwg1lF9D6x8oRMlr26kaIXnaYfokiBklSnzCDh1GHzJwOkxi58g2wUVP7ICY auwPG7XKzBJcv769PQD4QNzdV3PrcYbmxd9vu6wPwOMIREu7Jj5Q9qWSRrc8WZRb0E8P 0PnquSvS6IlbulCQfcrhM1Q89Wbml+a4CdJPes/7IVIHDjBIuw2FWcRivQllBsfpk3Lg voVA== X-Gm-Message-State: AOAM5317XtAn6k39Zvf2FeRcN8sFeILmQ5xkXD9JM+vdx87vY97ZTgQD e6jOrxzM3kFlaB4N8m0v4Q1L0FZXqPkJrw== X-Received: by 2002:aa7:982e:0:b029:2e4:eef5:e0c9 with SMTP id q14-20020aa7982e0000b02902e4eef5e0c9mr22082764pfl.3.1621955245403; Tue, 25 May 2021 08:07:25 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:25 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 27/28] tests/fp: Enable more tests Date: Tue, 25 May 2021 08:07:05 -0700 Message-Id: <20210525150706.294968-28-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::435; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x435.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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 Tue May 25 15:07:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 447298 Delivered-To: patch@linaro.org Received: by 2002:a02:7a1b:0:0:0:0:0 with SMTP id a27csp4418132jac; Tue, 25 May 2021 09:16:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzxIeprRPr4IjxJVm63/ES9K/8ui3aSAL3dgwBe/dA0rL+g86EVyOpfakIUdcZUthDjFZDN X-Received: by 2002:aa7:c24d:: with SMTP id y13mr32348374edo.155.1621959414716; Tue, 25 May 2021 09:16:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621959414; cv=none; d=google.com; s=arc-20160816; b=r4Gwkza+JJoZ9J7Qu1yWIi4nFnU8I9YDCn4TgbTX8bZP2WVF0hiGk8YZTkt2ggBWvQ 5Z+gzfq1YO4kzE7ju3tEzbIX1Nh4hZ4DIKyt06EsDesUuoWx3aKcH6QiJyRdsRbfA0Al D5u+LbwDCRnA/nRV3/J9PJyfU4lXwpqSnlDeGqNviFsW5HT7sLtAfd3nN95BZBxO9CsF rXGFZRe1AQZwOWA+Ox3u74cbQb7RSQOASvtoJTD/VZnk5UyAYLfnLg3TktYHB6rwB3Tu safQd6jnxcy3oNImZr6/h3e9Mcak9P1ALBe3L5Tx0PgPkcrNGggxsPLBOngWa9gjrw1H E1/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=jPESxkdne1pl9qKkpnJVzbPwFkDrkEve1zwqkORGLuk=; b=zMOd0US2GAoLhhVceprWrZs7FmhdBGmetv+UioJV/veiBOkwbQon0ptusn4nFdDvSt XG+ho/Raeke/FNZ6cadb7VHW1Og/R2iZG+KzNjP9X8A+XuzTdDtj8sYfP1/D7hq4y+o4 6nGgf6qS5saXeVb0O6rVbHAA+1VFlHw34nbU1GHHkLkGeXeyiq2/zLR27BY9TwaSxkdk Z9lxOjSWatOTt35I7NWNdqdc8LUf26QTnjzfgQto2I/W7lI4+8VCfgCfRGlJniRNYbEP mKWSEznLXt1fSbjUxGlaaEhK6Lw3RABdq8fcPa3pZP5XjrZ9o0tSXglFanH7xi0Z1W46 T/Vg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=NrGyYqhv; 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=fail (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 da12si15187040edb.130.2021.05.25.09.16.54 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 May 2021 09:16:54 -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=fail header.i=@linaro.org header.s=google header.b=NrGyYqhv; 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=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49318 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1llZjh-0005SB-PU for patch@linaro.org; Tue, 25 May 2021 12:16:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60614) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1llYen-0002Fc-DI for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:45 -0400 Received: from mail-pf1-x42e.google.com ([2607:f8b0:4864:20::42e]:40498) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1llYeW-0006nR-Gh for qemu-devel@nongnu.org; Tue, 25 May 2021 11:07:45 -0400 Received: by mail-pf1-x42e.google.com with SMTP id x188so23833956pfd.7 for ; Tue, 25 May 2021 08:07:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jPESxkdne1pl9qKkpnJVzbPwFkDrkEve1zwqkORGLuk=; b=NrGyYqhvhZuyBq9Zo6J0tCtHCQFS5Dic6ht7OBRcJpUL99xtoCLqUw+nf6qYU3/EiA AFP4Yr8iNVTAoEn5J4jEeEArpqakV69lObkYY6tE/hWD+6Vl0Qc+hfA2KEghP4R64r3L uoCze7IGdYVFmpShAO6IAUzCElRAQvJl6V/6xJ+f9fQLRb5fPDj43oHjriUYrkqDnrdS qgAWzLYrAZW/16yd9BWmwVKz95LNiBIU8Bjm4fqMgtBczjk64OGgbMECOSo8q3IjDJqJ ovImFwKwg7Cn4RxzIQ85RTwIkaWRRjOSd+qHPKRnffAt0WPg7AygbbbLCIS0ORe6//HT a88A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jPESxkdne1pl9qKkpnJVzbPwFkDrkEve1zwqkORGLuk=; b=m4HXz0Fg35VCMLIqD8/mfmwe0uXlXZidt+nkCbCnXEEcKlM+xIldIjEje+7WjuJTlm Uq9fF2t7nMvsjGCMZ8kFFZ3rWpRCxNul3sv1kO4+1UluI95fzXza5Jf8ijuUqygvOBk2 yY8nLHjz61IuPGAxUHwJr40E7fWxldGAxCfIk79IT/WZIf1ubyK6CLcZxOe//YXa4Kxc C9Qee6CrFXIq7VkJquRGU12JGDNLKYj0OLxW8SOrvKf33djS1dH4sXbccet45VnVyiXc XLaziyKsSq5/f6DXJ3UaEpCdKpq01RuWP5mmM/fsk16UhcPQjRlJs4nPmczZwHStj6Yu 7s0Q== X-Gm-Message-State: AOAM531ILG13iAa7mMKldsSbav75jBuzoPQGTECYJ0Gi9JZ5rWo2dQfg 0P0Q9pzij0Et1IlBMnDBUwhIVURUYAnnJw== X-Received: by 2002:a63:5c1:: with SMTP id 184mr19617387pgf.75.1621955246013; Tue, 25 May 2021 08:07:26 -0700 (PDT) Received: from localhost.localdomain (174-21-70-228.tukw.qwest.net. [174.21.70.228]) by smtp.gmail.com with ESMTPSA id z19sm2231943pjq.11.2021.05.25.08.07.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 May 2021 08:07:25 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 28/28] softfloat: Use hard-float for {u}int64_to_float{32, 64} Date: Tue, 25 May 2021 08:07:06 -0700 Message-Id: <20210525150706.294968-29-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210525150706.294968-1-richard.henderson@linaro.org> References: <20210525150706.294968-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42e; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42e.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+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 Signed-off-by: Richard Henderson --- fpu/softfloat.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/fpu/softfloat.c b/fpu/softfloat.c index b0df5b6dc5..79b2205070 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3559,6 +3559,13 @@ float32 int64_to_float32_scalbn(int64_t a, int scale, float_status *status) { FloatParts64 p; + /* 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); }