From patchwork Tue Feb 26 14:12:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 159208 Delivered-To: patch@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp3264374jad; Tue, 26 Feb 2019 06:15:05 -0800 (PST) X-Google-Smtp-Source: AHgI3Ib4r0ExAqzs5t04yGzV6kc4MUCRasbMi3/kXXNEjWT+oKWZ16P1Mmoad1XuvVUyOJPPskIt X-Received: by 2002:a81:67c1:: with SMTP id b184mr18700046ywc.39.1551190505446; Tue, 26 Feb 2019 06:15:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551190505; cv=none; d=google.com; s=arc-20160816; b=zKCzLhIfj9HP4qbxZQOA2LbiBK8TKh3BOZq8+x23jWPZ34t6U5f/9JROrRJeGirqZ2 1GBinEoOQU7F6lpFWN+0NXK62Wlww8nRTVWD0ooUSbEOX3fJV86U7H/aYeleaXAZZPAl /228Be08zNaXbJPSrTHxuFh73K8aSibKmOUOZXoak6uc/6wiWpXi1HtUsOHqpJMX1xH0 HFkiVKheDy3lQ6PT4kQw8CB7CfddZ/JkKA8BApf68k9SNYhm0Bs701Znp5hAf6Ng4mmQ MLItN6v7wdZ+BsIFnhvEcnw53HYEmJFATXK4UYU4fsE+fyv7CgV1dQjf6NRbVznbXY8a hAsQ== 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:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=1Q0k9QQTnRWHqnwq52Tx8dR/n33a7rMpg27Spk2nK1k=; b=K4ryv0Gtqk8euXWTK5EBIaFsCf3iLOAksQ9PrjaWh7L8XV2UcyQYgy5seojngaiO1x wZUwx83p8AF5NJzgrjeZdr1jmkWRL63yK1W5kLwT/tmlpaGmWTuZm7u26DIQY5T8Q7V0 UtkgNmVINkkNpnOpQeOg5XQ3zHGm/QyXK4KkdGz+19PCypZuuTAwHV1pWQGiuQjqWq8q PnwPO267rFq/0i4F5x3zX2zZZCvGsssl8UNX6lp+8yk+M3/TmFtoLcdveUMrgZZDcIHR U82Vy9qQlU1CQEpjRY9t+hAUztguXaMkKaRhHF2AICjoyMlJOUqvdIQwxzoWxWcE7AJW 8h6g== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=oSyFwQM8; 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" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id q203si7714242ybc.34.2019.02.26.06.15.05 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 26 Feb 2019 06:15:05 -0800 (PST) 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=oSyFwQM8; 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" Received: from localhost ([127.0.0.1]:56089 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gydVg-0001qV-Rd for patch@linaro.org; Tue, 26 Feb 2019 09:15:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:52785) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gydSt-0008BR-IS for qemu-devel@nongnu.org; Tue, 26 Feb 2019 09:12:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gydSs-0003Q9-7J for qemu-devel@nongnu.org; Tue, 26 Feb 2019 09:12:11 -0500 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]:34144) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gydSr-0003Ou-Tp for qemu-devel@nongnu.org; Tue, 26 Feb 2019 09:12:10 -0500 Received: by mail-wr1-x433.google.com with SMTP id f14so14141764wrg.1 for ; Tue, 26 Feb 2019 06:12:09 -0800 (PST) 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=1Q0k9QQTnRWHqnwq52Tx8dR/n33a7rMpg27Spk2nK1k=; b=oSyFwQM8J5o4K54ohX+3mLUiSMZ6vG7Mjn6RYYlii9S1MyRuuYOp/4hY9Xq4bnqF2P CK7cyzpttGn61261LG0Z3HCf1oF29XKzAfLJlqVDYAxYyXRtMgPBUbx0Skgo6ZP+ZX3G SPmuIXrxhdxQKrP6zc8jtqy1hNquxQn/nnAAsBAZbnU8Pa+oiJHYQOY6VJ7pvuZ+WCwB e18zYzvezGBXeqi+1CXGtqCv2BA8nBO/x3KUKtbqB1LUIA1CGbpAarLVSZnMbE3WHne2 tmnceUgYqYS2AHKBLYhzeCVN1xX+CG9ABE/8eZW9y7whwZADKED211Q7b7MzxHwtFzHD UTFQ== 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=1Q0k9QQTnRWHqnwq52Tx8dR/n33a7rMpg27Spk2nK1k=; b=PE5+KAvgv6d7xj+H0wKBzwta8Ynv/wmzeutA+qiBs6Y7hn39TSeol++cXmmjQLzXon wCVsKlEN9rBjEByfo5VYJDfd+cHAxaTmh4E9jcucqbEgFa0hvxjG3oVphQgd6R2GyspM LhsUXPzdyuynhb4PXfMWzEaluwGp/8bBCu/4/C1vA2FfRq3qjqw4Eh+fi+VdOi8myEq5 p44WDyWFSnRSXcm2nTRn0yAKgN3w7J3Dl5p1tAgUoItLH3xzpjXDMXMu0v2D4RCEICbL sHpSZ9lvDbUz9+hHpaDgGZL8QKi5TkR2gAIskj1XDhKwD4A9kYpwD0KWQXii+o5rbQng vWWQ== X-Gm-Message-State: AHQUAuZ83A8dxGzhuiLgNCeyYKbaSeUa4uQvntY6WitCwKmb2k3HU9Bc Bn0MVmSXJ7Mzs3x5ZemTYXwavQ== X-Received: by 2002:adf:f391:: with SMTP id m17mr15693570wro.137.1551190328743; Tue, 26 Feb 2019 06:12:08 -0800 (PST) Received: from zen.linaroharston ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id c1sm12233156wmb.14.2019.02.26.06.12.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 26 Feb 2019 06:12:04 -0800 (PST) Received: from zen.linaroharston. (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 21E421FF89; Tue, 26 Feb 2019 14:12:02 +0000 (UTC) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Tue, 26 Feb 2019 14:12:00 +0000 Message-Id: <20190226141201.16999-7-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190226141201.16999-1-alex.bennee@linaro.org> References: <20190226141201.16999-1-alex.bennee@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::433 Subject: [Qemu-devel] [PULL 6/7] softfloat: Support float_round_to_odd more places X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson , qemu-devel@nongnu.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Previously this was only supported for roundAndPackFloat64. New support in round_canonical, round_to_int, float128_round_to_int, roundAndPackFloat32, roundAndPackInt32, roundAndPackInt64, roundAndPackUint64. This does not include any of the floatx80 routines, as we do not have users for that rounding mode there. Signed-off-by: Richard Henderson Message-Id: <20190215170225.15537-1-richard.henderson@linaro.org> Tested-by: David Hildenbrand [AJB: add missing break] Signed-off-by: Alex Bennée -- 2.20.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index c69cd6b5d1..4610738ab1 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -696,6 +696,7 @@ static FloatParts sf_canonicalize(FloatParts part, const FloatFmt *parm, static FloatParts round_canonical(FloatParts p, float_status *s, const FloatFmt *parm) { + const uint64_t frac_lsb = parm->frac_lsb; const uint64_t frac_lsbm1 = parm->frac_lsbm1; const uint64_t round_mask = parm->round_mask; const uint64_t roundeven_mask = parm->roundeven_mask; @@ -731,6 +732,10 @@ static FloatParts round_canonical(FloatParts p, float_status *s, inc = p.sign ? round_mask : 0; overflow_norm = !p.sign; break; + case float_round_to_odd: + overflow_norm = true; + inc = frac & frac_lsb ? 0 : round_mask; + break; default: g_assert_not_reached(); } @@ -778,9 +783,14 @@ static FloatParts round_canonical(FloatParts p, float_status *s, shift64RightJamming(frac, 1 - exp, &frac); if (frac & round_mask) { /* Need to recompute round-to-even. */ - if (s->float_rounding_mode == float_round_nearest_even) { + switch (s->float_rounding_mode) { + case float_round_nearest_even: inc = ((frac & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0); + break; + case float_round_to_odd: + inc = frac & frac_lsb ? 0 : round_mask; + break; } flags |= float_flag_inexact; frac += inc; @@ -1988,6 +1998,9 @@ static FloatParts round_to_int(FloatParts a, int rmode, case float_round_down: one = a.sign; break; + case float_round_to_odd: + one = true; + break; default: g_assert_not_reached(); } @@ -2021,6 +2034,9 @@ static FloatParts round_to_int(FloatParts a, int rmode, case float_round_down: inc = a.sign ? rnd_mask : 0; break; + case float_round_to_odd: + inc = a.frac & frac_lsb ? 0 : rnd_mask; + break; default: g_assert_not_reached(); } @@ -3314,6 +3330,9 @@ static int32_t roundAndPackInt32(flag zSign, uint64_t absZ, float_status *status case float_round_down: roundIncrement = zSign ? 0x7f : 0; break; + case float_round_to_odd: + roundIncrement = absZ & 0x80 ? 0 : 0x7f; + break; default: abort(); } @@ -3368,6 +3387,9 @@ static int64_t roundAndPackInt64(flag zSign, uint64_t absZ0, uint64_t absZ1, case float_round_down: increment = zSign && absZ1; break; + case float_round_to_odd: + increment = !(absZ0 & 1) && absZ1; + break; default: abort(); } @@ -3424,6 +3446,9 @@ static int64_t roundAndPackUint64(flag zSign, uint64_t absZ0, case float_round_down: increment = zSign && absZ1; break; + case float_round_to_odd: + increment = !(absZ0 & 1) && absZ1; + break; default: abort(); } @@ -3526,6 +3551,9 @@ static float32 roundAndPackFloat32(flag zSign, int zExp, uint32_t zSig, case float_round_down: roundIncrement = zSign ? 0x7f : 0; break; + case float_round_to_odd: + roundIncrement = zSig & 0x80 ? 0 : 0x7f; + break; default: abort(); break; @@ -3536,8 +3564,10 @@ static float32 roundAndPackFloat32(flag zSign, int zExp, uint32_t zSig, || ( ( 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, - ( roundIncrement == 0 )); + return packFloat32(zSign, 0xFF, -!overflow_to_inf); } if ( zExp < 0 ) { if (status->flush_to_zero) { @@ -3555,6 +3585,13 @@ static float32 roundAndPackFloat32(flag zSign, int zExp, uint32_t zSig, 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) { @@ -6987,6 +7024,15 @@ float128 float128_round_to_int(float128 a, float_status *status) add128(z.high, z.low, 0, roundBitsMask, &z.high, &z.low); } break; + case float_round_to_odd: + /* + * Note that if lastBitMask == 0, the last bit is the lsb + * of high, and roundBitsMask == -1. + */ + if ((lastBitMask ? z.low & lastBitMask : z.high & 1) == 0) { + add128(z.high, z.low, 0, roundBitsMask, &z.high, &z.low); + } + break; default: abort(); } @@ -6998,7 +7044,7 @@ float128 float128_round_to_int(float128 a, float_status *status) status->float_exception_flags |= float_flag_inexact; aSign = extractFloat128Sign( a ); switch (status->float_rounding_mode) { - case float_round_nearest_even: + case float_round_nearest_even: if ( ( aExp == 0x3FFE ) && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) @@ -7011,14 +7057,17 @@ float128 float128_round_to_int(float128 a, float_status *status) return packFloat128(aSign, 0x3FFF, 0, 0); } break; - case float_round_down: + case float_round_down: return aSign ? packFloat128( 1, 0x3FFF, 0, 0 ) : packFloat128( 0, 0, 0, 0 ); - case float_round_up: + case float_round_up: return aSign ? packFloat128( 1, 0, 0, 0 ) : packFloat128( 0, 0x3FFF, 0, 0 ); + + case float_round_to_odd: + return packFloat128(aSign, 0x3FFF, 0, 0); } return packFloat128( aSign, 0, 0, 0 ); } @@ -7051,6 +7100,12 @@ float128 float128_round_to_int(float128 a, float_status *status) z.high += roundBitsMask; } break; + case float_round_to_odd: + if ((z.high & lastBitMask) == 0) { + z.high |= (a.low != 0); + z.high += roundBitsMask; + } + break; default: abort(); } diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c index 4114f346a9..7d0faf2b47 100644 --- a/tests/fp/fp-test.c +++ b/tests/fp/fp-test.c @@ -125,17 +125,42 @@ static void not_implemented(void) static bool blacklisted(unsigned op, int rmode) { - /* odd has only been implemented for a few 128-bit ops */ + /* odd has not been implemented for any 80-bit ops */ if (rmode == softfloat_round_odd) { switch (op) { - case F128_ADD: - case F128_SUB: - case F128_MUL: - case F128_DIV: - case F128_TO_F64: - case F128_SQRT: - return false; - default: + case EXTF80_TO_UI32: + case EXTF80_TO_UI64: + case EXTF80_TO_I32: + case EXTF80_TO_I64: + case EXTF80_TO_UI32_R_MINMAG: + case EXTF80_TO_UI64_R_MINMAG: + case EXTF80_TO_I32_R_MINMAG: + case EXTF80_TO_I64_R_MINMAG: + case EXTF80_TO_F16: + case EXTF80_TO_F32: + case EXTF80_TO_F64: + case EXTF80_TO_F128: + case EXTF80_ROUNDTOINT: + case EXTF80_ADD: + case EXTF80_SUB: + case EXTF80_MUL: + case EXTF80_DIV: + case EXTF80_REM: + case EXTF80_SQRT: + case EXTF80_EQ: + case EXTF80_LE: + case EXTF80_LT: + case EXTF80_EQ_SIGNALING: + case EXTF80_LE_QUIET: + case EXTF80_LT_QUIET: + case UI32_TO_EXTF80: + case UI64_TO_EXTF80: + case I32_TO_EXTF80: + case I64_TO_EXTF80: + case F16_TO_EXTF80: + case F32_TO_EXTF80: + case F64_TO_EXTF80: + case F128_TO_EXTF80: return true; } }