From patchwork Tue Oct 20 16:37:31 2020 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: 270868 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49766C4363A for ; Tue, 20 Oct 2020 16:49:08 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A81BB206DC for ; Tue, 20 Oct 2020 16:49:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="aWZ24J1x" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A81BB206DC Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:44366 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kUuos-0005SO-Dr for qemu-devel@archiver.kernel.org; Tue, 20 Oct 2020 12:49:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49272) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kUudt-0007hg-Fo for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:45 -0400 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:34825) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kUudr-0000xC-LJ for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:45 -0400 Received: by mail-wr1-x443.google.com with SMTP id n15so2988283wrq.2 for ; Tue, 20 Oct 2020 09:37:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QWLXVwtDu65vCD1CaNwfFzInaZDsuzIveGR3ZrqO5Rg=; b=aWZ24J1xg7NBdDXmrSIHd6kfQbwttHNJW9m6jAo316wJAlpsL0wYM/TC08jCRUsIU0 1PrJApvp6g7xadoMT3o7XPzu5oe8Igkp8XeTtZl/ez0MAEU2y8AA5zZ8q0LjvCh07tHp hzli0oeBB8InEJKffyj0B2IwzNBPwJv0t+aJfmlXiql4T+sxMTlsijdfijjBz7SnOZr0 EMezFUo05YHyk2thYQ7j2gvZMo/EocbXsMSok/C0snSsb+7Y1UYEegs/F3bCCz91R2bC nT2PunFSs9mSK5A9ofHVWwMRAqovLwaLFrPw8K47UCbVkRRJlCITz6V/aq5gpH6KLKIz +IgQ== 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=QWLXVwtDu65vCD1CaNwfFzInaZDsuzIveGR3ZrqO5Rg=; b=BERygg1fpQiNa7vMhVLh5QmRqyfdjLUJ+WDkIFWHB4FB2TYMrXyNgsmaTx3ocVHcEG fR719ukoaQx8YKI56sIUXjhfiShi14/6HaBFKEB0DGDBjJ4U9IfIhv4URw0z3KET5VuS Bpa4S/ShWVwsCF4BZ2fzOmW5Ftjs+02dx8DSwks9MsQrBL/U3DMpy6FwPWGDWhiOS3HH e6yBQB6YfxXxyPOsadW1zsN9L9sR+niyP773B8NwnpJkUDoGBdlHSDQBMiRtDDPRZxS6 XGLF5wxCL3Z7new+OIQtYtxc5NJZbNQsETGCZOtuSCDkOYCy9rO4pBSuWMQz6c10ZOaY WQ7A== X-Gm-Message-State: AOAM530F3l50sw6jTTW+kXujsEvwwREpMWNnfXSYnOnNN/U5yRW+B1ws PTnDrhwFDeURb4zcN8wD246laA== X-Google-Smtp-Source: ABdhPJy9QQyIOasnj4ql6wfai/PU4IGSJ8xggHaOzMidzqaxsdW7htE0k/3aTteIQYwR98jKpfM29w== X-Received: by 2002:adf:fd49:: with SMTP id h9mr4745812wrs.115.1603211861770; Tue, 20 Oct 2020 09:37:41 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id j17sm3636816wrw.68.2020.10.20.09.37.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 09:37:39 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 1AFFB1FF87; Tue, 20 Oct 2020 17:37:39 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Subject: [RFC PATCH 1/8] softfloat: Use mulu64 for mul64To128 Date: Tue, 20 Oct 2020 17:37:31 +0100 Message-Id: <20201020163738.27700-2-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201020163738.27700-1-alex.bennee@linaro.org> References: <20201020163738.27700-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::443; envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x443.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. 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: Peter Maydell , David Hildenbrand , Richard Henderson , cota@braap.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Aurelien Jarno Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Via host-utils.h, we use a host widening multiply for 64-bit hosts, and a common subroutine for 32-bit hosts. Reviewed-by: David Hildenbrand Signed-off-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20200925152047.709901-2-richard.henderson@linaro.org> --- include/fpu/softfloat-macros.h | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index a35ec2893a..57845f8af0 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -83,6 +83,7 @@ this code that are retained. #define FPU_SOFTFLOAT_MACROS_H #include "fpu/softfloat-types.h" +#include "qemu/host-utils.h" /*---------------------------------------------------------------------------- | Shifts `a' right by the number of bits given in `count'. If any nonzero @@ -515,27 +516,10 @@ static inline void | `z0Ptr' and `z1Ptr'. *----------------------------------------------------------------------------*/ -static inline void mul64To128( uint64_t a, uint64_t b, uint64_t *z0Ptr, uint64_t *z1Ptr ) +static inline void +mul64To128(uint64_t a, uint64_t b, uint64_t *z0Ptr, uint64_t *z1Ptr) { - uint32_t aHigh, aLow, bHigh, bLow; - uint64_t z0, zMiddleA, zMiddleB, z1; - - aLow = a; - aHigh = a>>32; - bLow = b; - bHigh = b>>32; - z1 = ( (uint64_t) aLow ) * bLow; - zMiddleA = ( (uint64_t) aLow ) * bHigh; - zMiddleB = ( (uint64_t) aHigh ) * bLow; - z0 = ( (uint64_t) aHigh ) * bHigh; - zMiddleA += zMiddleB; - z0 += ( ( (uint64_t) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); - zMiddleA <<= 32; - z1 += zMiddleA; - z0 += ( z1 < zMiddleA ); - *z1Ptr = z1; - *z0Ptr = z0; - + mulu64(z1Ptr, z0Ptr, a, b); } /*---------------------------------------------------------------------------- From patchwork Tue Oct 20 16:37:32 2020 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: 270867 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6CB05C4363A for ; Tue, 20 Oct 2020 16:51:12 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A7A28206DC for ; Tue, 20 Oct 2020 16:51:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="QonyN7yR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A7A28206DC Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50128 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kUuqs-0007uf-Et for qemu-devel@archiver.kernel.org; Tue, 20 Oct 2020 12:51:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49296) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kUudv-0007mA-BQ for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:47 -0400 Received: from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b]:52575) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kUudt-0000xv-JV for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:47 -0400 Received: by mail-wm1-x32b.google.com with SMTP id c194so2488229wme.2 for ; Tue, 20 Oct 2020 09:37:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nLpmmB1zOrX5GCXrMDbuop25AXmZfJe8hra4fgaIWd0=; b=QonyN7yRTAG6bfAQcdXVscZSU0F1Xep4neuChQGQe38azhQFAcmTT7muZMxKmAfnn7 NHeJYmwz4REvYd0nmwbY1u+hn+GawJ9FSFmVuJKD58/DAiQKd84C0uxymABCuROtyZXy 68t65wqqKNfVVwUmDcE0NaGCEl79lmWKQj2zYnlLr52/x6IpcfVzkyolaNtTGQK2s8Fw msZpmqrQVf9YuDz0xljO+5yXj8wW//7WxsbfuBDfGnehknXt4/mxMq6Ymsl9ZXEoXfku n0hf1yPK06V2dbEPE50tzPKon4BB4DeRge77ndN7QmWJjsaiI3oDLNlXUO9DdLpA8P8I dzLQ== 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=nLpmmB1zOrX5GCXrMDbuop25AXmZfJe8hra4fgaIWd0=; b=Np1GOTrNJrUuDpvM/2roSj1Sy0drpXtirvzumxABsiXxLbKCovvoWHigamXLX/9zkj CNR1t9oIa8O6YPeZjM3V3Tnblb8RcCh9XwDmhNNU5w6SQg0NQYTJZJxiO2cPuxgjpLvF TS3EO+AYc1EQ62Db0YGFWaRsjgiTWnNEFGAVNjoRNADAtFtyTuwszgnlHV7DiRMonHQh MfiT+qULIoh5kl7QRjbDWvUMRkb24TwsJQHpnIKHzMmgVxVhjcp4y9OqCNM5SywV7fmh iD3xRZ48GuD/E0PMv1h1Ocm3ZxTc8j6Pl0bpj8+ynmapPGwR5f280gEQet+V5IplJMJq Lk8Q== X-Gm-Message-State: AOAM5335lgbR6r2ts0eP2eSC/kIGuEENKUrTr3pPwexYwrIZi6yd6gLt t95GqTg6RCHHo91oSWZf09dEqw== X-Google-Smtp-Source: ABdhPJw2ZMF03y7F+e6uvlRg94jQtX78bXUiHIyLCrsIsieUf1HEjZI6Sq/pb9SgydUDW/cZKuiIGg== X-Received: by 2002:a1c:3b8a:: with SMTP id i132mr3852324wma.178.1603211864038; Tue, 20 Oct 2020 09:37:44 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id b190sm3469958wmd.35.2020.10.20.09.37.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 09:37:40 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 3FA4C1FF8C; Tue, 20 Oct 2020 17:37:39 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Subject: [RFC PATCH 2/8] softfloat: Use int128.h for some operations Date: Tue, 20 Oct 2020 17:37:32 +0100 Message-Id: <20201020163738.27700-3-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201020163738.27700-1-alex.bennee@linaro.org> References: <20201020163738.27700-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32b; envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x32b.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. 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: Peter Maydell , David Hildenbrand , Richard Henderson , cota@braap.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Aurelien Jarno Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Use our Int128, which wraps the compiler's __int128_t, instead of open-coding left shifts and arithmetic. We'd need to extend Int128 to have unsigned operations to replace more than these three. Reviewed-by: David Hildenbrand Signed-off-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20200925152047.709901-3-richard.henderson@linaro.org> --- include/fpu/softfloat-macros.h | 39 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index 57845f8af0..95d88d05b8 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -84,6 +84,7 @@ this code that are retained. #include "fpu/softfloat-types.h" #include "qemu/host-utils.h" +#include "qemu/int128.h" /*---------------------------------------------------------------------------- | Shifts `a' right by the number of bits given in `count'. If any nonzero @@ -352,13 +353,11 @@ static inline void shortShift128Left(uint64_t a0, uint64_t a1, int count, static inline void shift128Left(uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr) { - if (count < 64) { - *z1Ptr = a1 << count; - *z0Ptr = count == 0 ? a0 : (a0 << count) | (a1 >> (-count & 63)); - } else { - *z1Ptr = 0; - *z0Ptr = a1 << (count - 64); - } + Int128 a = int128_make128(a1, a0); + Int128 z = int128_lshift(a, count); + + *z0Ptr = int128_gethi(z); + *z1Ptr = int128_getlo(z); } /*---------------------------------------------------------------------------- @@ -405,15 +404,15 @@ static inline void *----------------------------------------------------------------------------*/ static inline void - add128( - uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, uint64_t *z0Ptr, uint64_t *z1Ptr ) +add128(uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, + uint64_t *z0Ptr, uint64_t *z1Ptr) { - uint64_t z1; - - z1 = a1 + b1; - *z1Ptr = z1; - *z0Ptr = a0 + b0 + ( z1 < a1 ); + Int128 a = int128_make128(a1, a0); + Int128 b = int128_make128(b1, b0); + Int128 z = int128_add(a, b); + *z0Ptr = int128_gethi(z); + *z1Ptr = int128_getlo(z); } /*---------------------------------------------------------------------------- @@ -463,13 +462,15 @@ static inline void *----------------------------------------------------------------------------*/ static inline void - sub128( - uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, uint64_t *z0Ptr, uint64_t *z1Ptr ) +sub128(uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, + uint64_t *z0Ptr, uint64_t *z1Ptr) { + Int128 a = int128_make128(a1, a0); + Int128 b = int128_make128(b1, b0); + Int128 z = int128_sub(a, b); - *z1Ptr = a1 - b1; - *z0Ptr = a0 - b0 - ( a1 < b1 ); - + *z0Ptr = int128_gethi(z); + *z1Ptr = int128_getlo(z); } /*---------------------------------------------------------------------------- From patchwork Tue Oct 20 16:37:33 2020 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: 302474 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5807C4363A for ; Tue, 20 Oct 2020 16:45:53 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E9DBE206CA for ; Tue, 20 Oct 2020 16:45:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="CM5bax9P" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E9DBE206CA Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:35324 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kUulj-0001eT-S6 for qemu-devel@archiver.kernel.org; Tue, 20 Oct 2020 12:45:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49330) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kUudz-0007qN-GL for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:51 -0400 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]:42283) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kUudv-0000yW-Eb for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:49 -0400 Received: by mail-wr1-x42b.google.com with SMTP id j7so2951882wrt.9 for ; Tue, 20 Oct 2020 09:37:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Ug2244h7gF1bgNo40QYky11fMBkQqW8reR6QCk5vxV0=; b=CM5bax9P6btdbc0tSV77+acjSdBLr782cvsQX/dbzD/UC3DdsBs5nYjz/9E/J24LZU n+RURlQeehPcA3UzOjhr1QpKoTfIZhaq5fFlDeerN9oKTUoo/CZjjbjFEyOFK8Ef33fu rxgPOc02gAPQGx7aitZ8ttsJutrGicxpLo3Ejj/7uld6QV7W88SgxUdFk5Zy+Hcs57WK N4if4q5C3RPrNISPodU00qywmReVWLh3uiLyVFqnPt99v6g7CbNFJYW0RPdols3O2dDD hXJ2ao8O4L2heKyVfIDkQzc27VvhgM7kNi1Db7yhxKq980Wa2QJcb3Bomm1X3Y4A7uBP o6bQ== 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=Ug2244h7gF1bgNo40QYky11fMBkQqW8reR6QCk5vxV0=; b=T1Tr7EdFkNyD5Ubl/TTMgJ/9ia9IcSwqlrvVjDpcStNh23z2swxUumIGDiAL3M/VXB B204dfvmObC99TJqXVroY5Oav2g5Z21Jfo3liMi4MKUED2ofc5qzt795+RXg/ZrgUopq pgoq30SKhUN/6wqofhqQXqkT3EasDofT08HSydpNhfbVM9Gj8extwuMeRe8Y2X4y1HBZ qZJWDN913BLpETt7Jm9a+gNyZzp2544AKMhU8cuASXUUfrbdJtTQUflYipmAQflKXuFR Fn81og/2lPeuEaH3CYgJGyDnqLESFZah3vZyoKglRfAPs/OuMHUrJd/6mhd2ZuVC3zZT 1q/A== X-Gm-Message-State: AOAM531mR3PP6tpOV0nzPo+M59SbRCGdZG2SfUGzlBJkQY0j7hzGh1tc ODKCfMqTjzYXuVW7LiAyKCROrg== X-Google-Smtp-Source: ABdhPJz+WvHPHGVXOawnQ7+h9CHPslxYhp+674jKrbXBScL6nyPVyurGLjFeQlxlix65YbYnFfJpDA== X-Received: by 2002:a5d:4c4b:: with SMTP id n11mr4361381wrt.171.1603211866078; Tue, 20 Oct 2020 09:37:46 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id v6sm3933801wrp.69.2020.10.20.09.37.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 09:37:42 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 731DD1FF8F; Tue, 20 Oct 2020 17:37:39 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Subject: [RFC PATCH 3/8] softfloat: Tidy a * b + inf return Date: Tue, 20 Oct 2020 17:37:33 +0100 Message-Id: <20201020163738.27700-4-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201020163738.27700-1-alex.bennee@linaro.org> References: <20201020163738.27700-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42b; envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x42b.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. 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: Peter Maydell , David Hildenbrand , Richard Henderson , cota@braap.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Aurelien Jarno Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson No reason to set values in 'a', when we already have float_class_inf in 'c', and can flip that sign. Reviewed-by: David Hildenbrand Signed-off-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20200925152047.709901-4-richard.henderson@linaro.org> --- fpu/softfloat.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 67cfa0fd82..9db55d2b11 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1380,9 +1380,8 @@ static FloatParts muladd_floats(FloatParts a, FloatParts b, FloatParts c, s->float_exception_flags |= float_flag_invalid; return parts_default_nan(s); } else { - a.cls = float_class_inf; - a.sign = c.sign ^ sign_flip; - return a; + c.sign ^= sign_flip; + return c; } } From patchwork Tue Oct 20 16:37:34 2020 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: 302472 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5314FC4363A for ; Tue, 20 Oct 2020 16:52:36 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6BF30206DD for ; Tue, 20 Oct 2020 16:52:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="JevuJfS8" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6BF30206DD Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:52542 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kUusE-0000c1-1Q for qemu-devel@archiver.kernel.org; Tue, 20 Oct 2020 12:52:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49342) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kUue1-0007rV-JA for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:53 -0400 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:38240) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kUudw-0000yr-GQ for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:51 -0400 Received: by mail-wr1-x443.google.com with SMTP id n18so2977442wrs.5 for ; Tue, 20 Oct 2020 09:37:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cI8HSGwWCnif3JZAlzq92xQoHYw4ZrAg/ruryZjOnLA=; b=JevuJfS8onUQ+xp4X9CVG/9Y3xqJwIGTUeQMQmRfqGoiGHiTtIMpdf72wp8OxM+D6d 00r7QZLh20wJJTj8b+zbfvMdzTXTC+85r0W0O6uqal4US/U9IogVEoz2r7Cl7fZYR72Q AITvILNNt/mOVendPby/sIoQoY94MSSTO/bwTmzYpMfkJM16sPNB0D2CZdm4+XoY4Oyc s/1rQVI4Ub3Zt5TWnHho6ll/WTf8ZS2vFJt1wycjE8ibVlOovVJcHW8hWK+tKFKhWdM5 pOAc3ZCXkFb9Qd6XKfxV6EZtEPnBhyCfXc/q1rtW0OgN7rsVuyO5cNuw07tfRvHDm6fH i63w== 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=cI8HSGwWCnif3JZAlzq92xQoHYw4ZrAg/ruryZjOnLA=; b=gCWDYCPuCf6m1l+KET46w7M/3wJw9tu/KRn1UnlQ7BGFFlOTPseZHKRblaVnVKxqal dG0ojKAEvippgvJcx8wVJ1vw/McW4ZaUIlkXfKAKbZRyvzTBXuEAZR8argH6cBCeBP9B HHSiNq2Kpdu5kFeuw937cRhAwIh52SLfdUoc8cvfqnUI6DWS9pbBFKHKpfUwJyORiUIl e2UmQmXW0Cbkk/DlV3HeBD2psmh/tgWAo1dP8yYyWtwYpNfbM7hM0fcDvOjmyzyyxOgR xqG8cjlCHRi9BRT1uLaI+1xGOUX41637a+bEtJ8kv8wVGejPO9TtQekOfIoOUMIzS5Tr jSTQ== X-Gm-Message-State: AOAM530OHbM4QbXQiHo43WEthAzn1AGCZsed87dJ/cpMqMFgPtrgrl7F Hl0kTKfBY0vpHat3GjMV0HMLAg== X-Google-Smtp-Source: ABdhPJzikJKbzedokXdIM7nQmKI5+50Boao2Sy/MZjmaE3JS1eG+u1aso49OA2K1f9TbcvfiBg4ddw== X-Received: by 2002:adf:f104:: with SMTP id r4mr4533876wro.202.1603211867164; Tue, 20 Oct 2020 09:37:47 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id v123sm3071360wme.7.2020.10.20.09.37.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 09:37:42 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 984CC1FF90; Tue, 20 Oct 2020 17:37:39 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Subject: [RFC PATCH 4/8] softfloat: Add float_cmask and constants Date: Tue, 20 Oct 2020 17:37:34 +0100 Message-Id: <20201020163738.27700-5-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201020163738.27700-1-alex.bennee@linaro.org> References: <20201020163738.27700-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::443; envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x443.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. 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: Peter Maydell , David Hildenbrand , Richard Henderson , cota@braap.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Aurelien Jarno Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Testing more than one class at a time is better done with masks. This reduces the static branch count. Reviewed-by: David Hildenbrand Signed-off-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20200925152047.709901-5-richard.henderson@linaro.org> --- fpu/softfloat.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 9db55d2b11..3e625c47cd 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -469,6 +469,20 @@ typedef enum __attribute__ ((__packed__)) { float_class_snan, } FloatClass; +#define float_cmask(bit) (1u << (bit)) + +enum { + float_cmask_zero = float_cmask(float_class_zero), + float_cmask_normal = float_cmask(float_class_normal), + float_cmask_inf = float_cmask(float_class_inf), + float_cmask_qnan = float_cmask(float_class_qnan), + float_cmask_snan = float_cmask(float_class_snan), + + float_cmask_infzero = float_cmask_zero | float_cmask_inf, + float_cmask_anynan = float_cmask_qnan | float_cmask_snan, +}; + + /* Simple helpers for checking if, or what kind of, NaN we have */ static inline __attribute__((unused)) bool is_nan(FloatClass c) { @@ -1335,24 +1349,27 @@ bfloat16 QEMU_FLATTEN bfloat16_mul(bfloat16 a, bfloat16 b, float_status *status) static FloatParts muladd_floats(FloatParts a, FloatParts b, FloatParts c, int flags, float_status *s) { - bool inf_zero = ((1 << a.cls) | (1 << b.cls)) == - ((1 << float_class_inf) | (1 << float_class_zero)); - bool p_sign; + bool inf_zero, p_sign; bool sign_flip = flags & float_muladd_negate_result; FloatClass p_class; uint64_t hi, lo; int p_exp; + int ab_mask, abc_mask; + + ab_mask = float_cmask(a.cls) | float_cmask(b.cls); + abc_mask = float_cmask(c.cls) | ab_mask; + inf_zero = ab_mask == float_cmask_infzero; /* It is implementation-defined whether the cases of (0,inf,qnan) * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN * they return if they do), so we have to hand this information * off to the target-specific pick-a-NaN routine. */ - if (is_nan(a.cls) || is_nan(b.cls) || is_nan(c.cls)) { + if (unlikely(abc_mask & float_cmask_anynan)) { return pick_nan_muladd(a, b, c, inf_zero, s); } - if (inf_zero) { + if (unlikely(inf_zero)) { s->float_exception_flags |= float_flag_invalid; return parts_default_nan(s); } @@ -1367,9 +1384,9 @@ static FloatParts muladd_floats(FloatParts a, FloatParts b, FloatParts c, p_sign ^= 1; } - if (a.cls == float_class_inf || b.cls == float_class_inf) { + if (ab_mask & float_cmask_inf) { p_class = float_class_inf; - } else if (a.cls == float_class_zero || b.cls == float_class_zero) { + } else if (ab_mask & float_cmask_zero) { p_class = float_class_zero; } else { p_class = float_class_normal; From patchwork Tue Oct 20 16:37:35 2020 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: 302470 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 684CBC4363A for ; Tue, 20 Oct 2020 16:59:47 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7CF7B2177B for ; Tue, 20 Oct 2020 16:59:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="OrxECvIv" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7CF7B2177B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38480 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kUuzB-0006ge-Hf for qemu-devel@archiver.kernel.org; Tue, 20 Oct 2020 12:59:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49428) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kUue7-0007vW-Ag for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:38:00 -0400 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:54343) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kUue2-0000zG-MT for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:59 -0400 Received: by mail-wm1-x344.google.com with SMTP id c77so2490827wmd.4 for ; Tue, 20 Oct 2020 09:37:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XpldNLE39oyJx0Efh9oGONaLZZynshqlNmAlRNDfdFs=; b=OrxECvIvdhHFefWeSlFdCh51gIHGKv7HEwcvBFShp1oYIV2eZaiydW/IGw2ZYP4c5b dtlCGinly6JbMAwPv6VvBciS3veZdD6M8Xs51P3w5Bc256t9geddCL8jtUtI+XYkQ23q NTDVjtY/OD8nOSL9pntl1GV2TGbK5a78Yxb32puoinzlA/FGLaVJvtpvOo78N8o4RqBt BPGMIunodfVFqHokepznc8o7EW//Oeny8HWDwpkzWlhiiuu4W5AVAe5Rqs6gkg9xJ2nf 6ynLJKB4MXi32DG6gxvKBoX6hkLzhLVxMYOvdlELNwYzRL5xTJHRRZN8buq5lQfT1lvV VFsw== 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=XpldNLE39oyJx0Efh9oGONaLZZynshqlNmAlRNDfdFs=; b=jTxJwgcc+NP5jo6LWvDZj13DaLMIXWMKU5xcQsA97rk2cIsb2xzlDOkhD3g+yReSKN JcItjYNQfjhMFE5Rlnluh7IAiGEekZlfhYCHE4+KwU7yyr5nAr/dbmYE6tZaCIcz1WZm E9vdik2eU24M0r7FELnuP9YlthUJSn3SeBWSHRRATufmlMvclt6Rz/o47kTakzZclrTE Q9K8BkRVbmIY/8Wo/4dD9kqnxsCwG4bayDIYee9QveP4Oydi7VLUwElACcP0/lBZR2Gb pBepjoTwYeOiJjsC27GLaHqWLQhijyyO1FxXmKqv2kNiZLxhQ85PPylvNItz5nyhMzRR H6Vw== X-Gm-Message-State: AOAM533FQznBDtUUK4KH9ADxI8Ncl/KQ8A2GHyRE3P1EwFajGHFFoggK ctMi+GjxjEmAyU6lRL0R9QTT6A== X-Google-Smtp-Source: ABdhPJyxEysbvP02GHnr8YrQi3skcoQqF+26oMsRuBQwJWZovjdmUE2NEUAgCpV8d0KHtGth4Vx2Lw== X-Received: by 2002:a05:600c:2115:: with SMTP id u21mr3714911wml.2.1603211868544; Tue, 20 Oct 2020 09:37:48 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id h3sm3832576wrw.78.2020.10.20.09.37.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 09:37:44 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id BF8C91FF91; Tue, 20 Oct 2020 17:37:39 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Subject: [RFC PATCH 5/8] softfloat: Inline pick_nan_muladd into its caller Date: Tue, 20 Oct 2020 17:37:35 +0100 Message-Id: <20201020163738.27700-6-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201020163738.27700-1-alex.bennee@linaro.org> References: <20201020163738.27700-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::344; envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x344.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. 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: Peter Maydell , David Hildenbrand , Richard Henderson , cota@braap.org, =?utf-8?q?Alex_Benn=C3=A9e?= , Aurelien Jarno Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Because of FloatParts, there will only ever be one caller. Inlining allows us to re-use abc_mask for the snan test. Reviewed-by: David Hildenbrand Signed-off-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20200925152047.709901-6-richard.henderson@linaro.org> --- fpu/softfloat.c | 75 +++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3e625c47cd..e038434a07 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -929,45 +929,6 @@ static FloatParts pick_nan(FloatParts a, FloatParts b, float_status *s) return a; } -static FloatParts pick_nan_muladd(FloatParts a, FloatParts b, FloatParts c, - bool inf_zero, float_status *s) -{ - int which; - - if (is_snan(a.cls) || is_snan(b.cls) || is_snan(c.cls)) { - s->float_exception_flags |= float_flag_invalid; - } - - which = pickNaNMulAdd(a.cls, b.cls, c.cls, inf_zero, s); - - if (s->default_nan_mode) { - /* Note that this check is after pickNaNMulAdd so that function - * has an opportunity to set the Invalid flag. - */ - which = 3; - } - - switch (which) { - case 0: - break; - case 1: - a = b; - break; - case 2: - a = c; - break; - case 3: - return parts_default_nan(s); - default: - g_assert_not_reached(); - } - - if (is_snan(a.cls)) { - return parts_silence_nan(a, s); - } - return a; -} - /* * Returns the result of adding or subtracting the values of the * floating-point values `a' and `b'. The operation is performed @@ -1366,7 +1327,41 @@ static FloatParts muladd_floats(FloatParts a, FloatParts b, FloatParts c, * off to the target-specific pick-a-NaN routine. */ if (unlikely(abc_mask & float_cmask_anynan)) { - return pick_nan_muladd(a, b, c, inf_zero, s); + int which; + + if (unlikely(abc_mask & float_cmask_snan)) { + float_raise(float_flag_invalid, s); + } + + which = pickNaNMulAdd(a.cls, b.cls, c.cls, inf_zero, s); + + if (s->default_nan_mode) { + /* + * Note that this check is after pickNaNMulAdd so that function + * has an opportunity to set the Invalid flag for inf_zero. + */ + which = 3; + } + + switch (which) { + case 0: + break; + case 1: + a = b; + break; + case 2: + a = c; + break; + case 3: + return parts_default_nan(s); + default: + g_assert_not_reached(); + } + + if (is_snan(a.cls)) { + return parts_silence_nan(a, s); + } + return a; } if (unlikely(inf_zero)) { From patchwork Tue Oct 20 16:37:36 2020 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: 302475 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C376C4363A for ; Tue, 20 Oct 2020 16:40:01 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B9B3122242 for ; Tue, 20 Oct 2020 16:40:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="OKlA4pTp" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B9B3122242 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:43510 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kUug3-0001GF-I5 for qemu-devel@archiver.kernel.org; Tue, 20 Oct 2020 12:39:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49424) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kUue6-0007uu-Hv for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:58 -0400 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:38812) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kUue2-0000zr-Kv for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:57 -0400 Received: by mail-wm1-x343.google.com with SMTP id b127so2688343wmb.3 for ; Tue, 20 Oct 2020 09:37:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ynL+ImLU8/MZiwy8JbT5zQ/0QgGC9xGdCjTroVHDtRY=; b=OKlA4pTpDYGoYJp1GCr28VzKFsKuZTGzmoSHGMK1pUZn0wYy9IxiZ7ZgjgtL2E9nj0 +xPrXoXf4RFwL67aOG77Phv5n7nTwvOE1Be0Mj9qJF3LL+Wg8bIuQ7Myzz9Uy/PhmOKM OeZaqEY4x2EeNX5L12hEzBBNpxyPO25Ne1BtLdtrOO4J4LH6/+Zgn6N0ak03/F+zE8IO HCKaTPSixcRcEJBf08Nr087hJS3+ligp7wmViTiEHE5nL+URSKqBqIbjZHydmBs3kEO7 d4pdjI+uC7FUFqeLbIUPQWN1eTf7GtrLuRv4KE+bDYOJSmF4nS8p19Z737Yt68luOLrF QBmQ== 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=ynL+ImLU8/MZiwy8JbT5zQ/0QgGC9xGdCjTroVHDtRY=; b=j7b4494pV47EH06JLwWTQlCSzFAzjPJ4yM5uj3/cipG5lbE2zIQZvLmZUFSWMmza/j YTKseCO1XuSX8yE/GAjnTCGGF0GvR5Q0bbAmFyqoJzDYH3gzjt8vnLD+XIVdLGEZ8GVr JZy7g5VvdWR68hQ48jrS3WW1kVllj9AdsVpC5ds7CZ0Xg+E+FV/RxJa6YOVTsZzkP9FR +wvRS6u3LUGiMkZdsu7AmmNhojNF3Jw68mwMxunUW/N6LJcM9hskGIsne1qPz/5urthO byjWgoB002OVsYpylvy49hwrPvlVDSGIesT/TUU8+vlC5C3jo4mBkgx+cJqGxOolKzPN WfZQ== X-Gm-Message-State: AOAM531+RwINazmX6K0F/N/RvegpCp84seNIWyA0T4IjUhRqaQLBRsT4 5369JBbQFsfzar0YaCe675/mYA== X-Google-Smtp-Source: ABdhPJyCKkQyGxAve0SGv9njdbT2dNTMKc5Y8MlsICzltaLGesAnxoXKrnadPChsTwzJpPzt6y/QNg== X-Received: by 2002:a1c:a1c2:: with SMTP id k185mr3832355wme.39.1603211871942; Tue, 20 Oct 2020 09:37:51 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id i14sm3305204wml.24.2020.10.20.09.37.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 09:37:44 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id EEE021FF92; Tue, 20 Oct 2020 17:37:39 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Subject: [RFC PATCH 6/8] int128.h: add bunch of uint128 utility functions (INCOMPLETE) Date: Tue, 20 Oct 2020 17:37:36 +0100 Message-Id: <20201020163738.27700-7-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201020163738.27700-1-alex.bennee@linaro.org> References: <20201020163738.27700-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::343; envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x343.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. 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: cota@braap.org, =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" These will be useful for softfloat. I've included the extract/desposit functions with the main Int128 header and not with cutils as we need alternate versions for systems that don't have compiler support for Uint128. Even with compiler support some stuff we need to hand-hack (like clz128). Signed-off-by: Alex Bennée --- include/qemu/int128.h | 122 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/include/qemu/int128.h b/include/qemu/int128.h index 76ea405922..38c8b1ab29 100644 --- a/include/qemu/int128.h +++ b/include/qemu/int128.h @@ -3,8 +3,10 @@ #ifdef CONFIG_INT128 #include "qemu/bswap.h" +#include "qemu/host-utils.h" typedef __int128_t Int128; +typedef __uint128_t Uint128; static inline Int128 int128_make64(uint64_t a) { @@ -16,6 +18,11 @@ static inline Int128 int128_make128(uint64_t lo, uint64_t hi) return (__uint128_t)hi << 64 | lo; } +static inline Uint128 uint128_make128(uint64_t lo, uint64_t hi) +{ + return (__uint128_t)hi << 64 | lo; +} + static inline uint64_t int128_get64(Int128 a) { uint64_t r = a; @@ -28,16 +35,31 @@ static inline uint64_t int128_getlo(Int128 a) return a; } +static inline uint64_t uint128_getlo(Uint128 a) +{ + return a; +} + static inline int64_t int128_gethi(Int128 a) { return a >> 64; } +static inline uint64_t uint128_gethi(Uint128 a) +{ + return a >> 64; +} + static inline Int128 int128_zero(void) { return 0; } +static inline Uint128 uint128_zero(void) +{ + return 0; +} + static inline Int128 int128_one(void) { return 1; @@ -58,21 +80,51 @@ static inline Int128 int128_and(Int128 a, Int128 b) return a & b; } +static inline Uint128 uint128_and(Uint128 a, Uint128 b) +{ + return a & b; +} + +static inline Int128 int128_or(Int128 a, Int128 b) +{ + return a | b; +} + +static inline Uint128 uint128_or(Uint128 a, Uint128 b) +{ + return a | b; +} + static inline Int128 int128_rshift(Int128 a, int n) { return a >> n; } +static inline Uint128 uint128_rshift(Uint128 a, int n) +{ + return a >> n; +} + static inline Int128 int128_lshift(Int128 a, int n) { return a << n; } +static inline Uint128 uint128_lshift(Uint128 a, int n) +{ + return a << n; +} + static inline Int128 int128_add(Int128 a, Int128 b) { return a + b; } +static inline Uint128 uint128_add(Uint128 a, Uint128 b) +{ + return a + b; +} + static inline Int128 int128_neg(Int128 a) { return -a; @@ -83,6 +135,11 @@ static inline Int128 int128_sub(Int128 a, Int128 b) return a - b; } +static inline Uint128 uint128_sub(Uint128 a, Uint128 b) +{ + return a - b; +} + static inline bool int128_nonneg(Int128 a) { return a >= 0; @@ -93,6 +150,11 @@ static inline bool int128_eq(Int128 a, Int128 b) return a == b; } +static inline bool uint128_eq(Uint128 a, Uint128 b) +{ + return a == b; +} + static inline bool int128_ne(Int128 a, Int128 b) { return a != b; @@ -148,6 +210,66 @@ static inline Int128 bswap128(Int128 a) return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a))); } +/** + * extract128: + * @value: the value to extract the bit field from + * @start: the lowest bit in the bit field (numbered from 0) + * @length: the length of the bit field + * + * Extract from the 128 bit input @value the bit field specified by the + * @start and @length parameters, and return it. The bit field must + * lie entirely within the 128 bit word. It is valid to request that + * all 128 bits are returned (ie @length 128 and @start 0). + * + * Returns: the value of the bit field extracted from the input value. + */ +static inline Uint128 extract128(Uint128 value, int start, int length) +{ + assert(start >= 0 && length > 0 && length <= 128 - start); + Uint128 mask = ~(Uint128)0 >> (128 - length); + Uint128 shifted = value >> start; + return shifted & mask; +} + +/** + * deposit128: + * @value: initial value to insert bit field into + * @start: the lowest bit in the bit field (numbered from 0) + * @length: the length of the bit field + * @fieldval: the value to insert into the bit field + * + * Deposit @fieldval into the 128 bit @value at the bit field specified + * by the @start and @length parameters, and return the modified + * @value. Bits of @value outside the bit field are not modified. + * Bits of @fieldval above the least significant @length bits are + * ignored. The bit field must lie entirely within the 128 bit word. + * It is valid to request that all 128 bits are modified (ie @length + * 128 and @start 0). + * + * Returns: the modified @value. + */ +static inline Uint128 deposit128(Uint128 value, int start, int length, + Uint128 fieldval) +{ + assert(start >= 0 && length > 0 && length <= 128 - start); + Uint128 mask = (~(Uint128)0 >> (128 - length)) << start; + return (value & ~mask) | ((fieldval << start) & mask); +} + +static inline int clz128(Uint128 val) +{ + if (val) { + uint64_t hi = uint128_gethi(val); + if (hi) { + return clz64(hi); + } else { + return 64 + clz64(uint128_getlo(val)); + } + } else { + return 128; + } +} + #else /* !CONFIG_INT128 */ typedef struct Int128 Int128; From patchwork Tue Oct 20 16:37:37 2020 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: 302473 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E5FE4C4363A for ; Tue, 20 Oct 2020 16:49:04 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 360B4206DC for ; Tue, 20 Oct 2020 16:49:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="kcptu55x" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 360B4206DC Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:44116 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kUuoo-0005MI-TO for qemu-devel@archiver.kernel.org; Tue, 20 Oct 2020 12:49:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49402) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kUue5-0007tj-0y for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:57 -0400 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:39880) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kUue1-0000zW-Rx for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:37:56 -0400 Received: by mail-wm1-x343.google.com with SMTP id d3so2686437wma.4 for ; Tue, 20 Oct 2020 09:37:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uOhU29/NowXaLPExLCEbzYi18ydUnYSK+IxcDeBgxSI=; b=kcptu55xjjFF/p7RbLQ4mfuLVT79FXhRb9BsjwiMmnRbHNpNNiQGckX1dZY+hu0AjB Z29hQ7tyYeNVCMZeRcqxnorFdljLHqQdh1XbQrL4p1pQSxFOOoc32ZlQoFf2gipeU3p3 KJ50vpd64IvyMtA9csJdQ2EguPJxNZQ2ai0ToNtTYIR04GV/QviMa03RbDn3Z9PFvA7J uw7zSuYa/waYdAql/Zq1vyHdY81URJd4hCksEORP3RxJiJLnrJAfChhol3AVeBLh5z8b E1W4bjINuMedweEGviUGM9NppwiFE95QWaC3pdCGmqvs1r7DLP2dW8lzcBszuPVkdr8b FDZg== 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=uOhU29/NowXaLPExLCEbzYi18ydUnYSK+IxcDeBgxSI=; b=gTP5M1jrBB8SVrOlda9RdlvnFiS1bQZ39KDkwtFB6BPBJZG/8zr3V3SbGz1jjg6I3i chyM+cp4Jjmeemq5VCTV18WBOPHuVqTyBq3O0/1EuTAo0yZMeYJUJCLIyk2HggqgEvPf E/oy8oS8itVVTKyD9c6LCkFHHGRIdehgLYW6/22cM9a69RztFDVd9s+1q/FvhrDAkS5H 4iyToOPR1CFi0WghumqMWsvYGiF9bvJdHly/jFqDG5ShfK2LrZbRsiPozry1ES3/gqkw cPCx116TzPLvDAYNU3babUmhefOMcenEzFy4FEJ6WzXAAG1o3M8qANAGRAinYXY7OIjh En2A== X-Gm-Message-State: AOAM530WkC+CSf30irbzKHl3clxNikJUJ6RRqp0f/Bx/uas8FwwELhPi Lro5jPhD2I2bQ3YunANGCAQYJw== X-Google-Smtp-Source: ABdhPJx/m7TpN5UQ4N8OQvB7B6biQybod5e/dx4k5irZDXDnH2+4gm5Lyvc64dvjyQ/q/bTyEa93oA== X-Received: by 2002:a1c:e1d7:: with SMTP id y206mr3793231wmg.48.1603211870679; Tue, 20 Oct 2020 09:37:50 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id q10sm3639313wrp.83.2020.10.20.09.37.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 09:37:44 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 2E5611FF93; Tue, 20 Oct 2020 17:37:40 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Subject: [RFC PATCH 7/8] tests/fp: add quad support to the benchmark utility Date: Tue, 20 Oct 2020 17:37:37 +0100 Message-Id: <20201020163738.27700-8-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201020163738.27700-1-alex.bennee@linaro.org> References: <20201020163738.27700-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::343; envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x343.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. 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: Peter Maydell , cota@braap.org, =?utf-8?q?Al?= =?utf-8?q?ex_Benn=C3=A9e?= , Aurelien Jarno Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Currently this only support softfloat calculations because working out if the hardware supports 128 bit floats needs configure magic. The 3 op muladd operation is currently unimplemented so commented out for now. Signed-off-by: Alex Bennée --- tests/fp/fp-bench.c | 88 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c index 4ba5e1d2d4..d319993280 100644 --- a/tests/fp/fp-bench.c +++ b/tests/fp/fp-bench.c @@ -14,6 +14,7 @@ #include #include #include "qemu/timer.h" +#include "qemu/int128.h" #include "fpu/softfloat.h" /* amortize the computation of random inputs */ @@ -50,8 +51,10 @@ static const char * const op_names[] = { enum precision { PREC_SINGLE, PREC_DOUBLE, + PREC_QUAD, PREC_FLOAT32, PREC_FLOAT64, + PREC_FLOAT128, PREC_MAX_NR, }; @@ -89,6 +92,7 @@ union fp { double d; float32 f32; float64 f64; + float128 f128; uint64_t u64; }; @@ -113,6 +117,10 @@ struct op_desc { static uint64_t random_ops[MAX_OPERANDS] = { SEED_A, SEED_B, SEED_C, }; + +static float128 random_quad_ops[MAX_OPERANDS] = { + {SEED_A, SEED_B}, {SEED_B, SEED_C}, {SEED_C, SEED_A}, +}; static float_status soft_status; static enum precision precision; static enum op operation; @@ -141,25 +149,45 @@ static void update_random_ops(int n_ops, enum precision prec) int i; for (i = 0; i < n_ops; i++) { - uint64_t r = random_ops[i]; switch (prec) { case PREC_SINGLE: case PREC_FLOAT32: + { + uint64_t r = random_ops[i]; do { r = xorshift64star(r); } while (!float32_is_normal(r)); + random_ops[i] = r; break; + } case PREC_DOUBLE: case PREC_FLOAT64: + { + uint64_t r = random_ops[i]; do { r = xorshift64star(r); } while (!float64_is_normal(r)); + random_ops[i] = r; + break; + } + case PREC_QUAD: + case PREC_FLOAT128: + { + float128 r = random_quad_ops[i]; + uint64_t hi = r.high; + uint64_t lo = r.low; + do { + hi = xorshift64star(hi); + lo = xorshift64star(lo); + r = make_float128(hi, lo); + } while (!float128_is_normal(r)); + random_quad_ops[i] = r; break; + } default: g_assert_not_reached(); } - random_ops[i] = r; } } @@ -184,6 +212,13 @@ static void fill_random(union fp *ops, int n_ops, enum precision prec, ops[i].f64 = float64_chs(ops[i].f64); } break; + case PREC_QUAD: + case PREC_FLOAT128: + ops[i].f128 = random_quad_ops[i]; + if (no_neg && float128_is_neg(ops[i].f128)) { + ops[i].f128 = float128_chs(ops[i].f128); + } + break; default: g_assert_not_reached(); } @@ -345,6 +380,41 @@ static void bench(enum precision prec, enum op op, int n_ops, bool no_neg) } } break; + case PREC_FLOAT128: + fill_random(ops, n_ops, prec, no_neg); + t0 = get_clock(); + for (i = 0; i < OPS_PER_ITER; i++) { + float128 a = ops[0].f128; + float128 b = ops[1].f128; + /* float128 c = ops[2].f128; */ + + switch (op) { + case OP_ADD: + res.f128 = float128_add(a, b, &soft_status); + break; + case OP_SUB: + res.f128 = float128_sub(a, b, &soft_status); + break; + case OP_MUL: + res.f128 = float128_mul(a, b, &soft_status); + break; + case OP_DIV: + res.f128 = float128_div(a, b, &soft_status); + break; + /* case OP_FMA: */ + /* res.f128 = float128_muladd(a, b, c, 0, &soft_status); */ + /* break; */ + case OP_SQRT: + res.f128 = float128_sqrt(a, &soft_status); + break; + case OP_CMP: + res.u64 = float128_compare_quiet(a, b, &soft_status); + break; + default: + g_assert_not_reached(); + } + } + break; default: g_assert_not_reached(); } @@ -369,7 +439,8 @@ static void bench(enum precision prec, enum op op, int n_ops, bool no_neg) GEN_BENCH(bench_ ## opname ## _float, float, PREC_SINGLE, op, n_ops) \ GEN_BENCH(bench_ ## opname ## _double, double, PREC_DOUBLE, op, n_ops) \ GEN_BENCH(bench_ ## opname ## _float32, float32, PREC_FLOAT32, op, n_ops) \ - GEN_BENCH(bench_ ## opname ## _float64, float64, PREC_FLOAT64, op, n_ops) + GEN_BENCH(bench_ ## opname ## _float64, float64, PREC_FLOAT64, op, n_ops) \ + GEN_BENCH(bench_ ## opname ## _float128, float128, PREC_FLOAT128, op, n_ops) GEN_BENCH_ALL_TYPES(add, OP_ADD, 2) GEN_BENCH_ALL_TYPES(sub, OP_SUB, 2) @@ -383,7 +454,8 @@ GEN_BENCH_ALL_TYPES(cmp, OP_CMP, 2) GEN_BENCH_NO_NEG(bench_ ## name ## _float, float, PREC_SINGLE, op, n) \ GEN_BENCH_NO_NEG(bench_ ## name ## _double, double, PREC_DOUBLE, op, n) \ GEN_BENCH_NO_NEG(bench_ ## name ## _float32, float32, PREC_FLOAT32, op, n) \ - GEN_BENCH_NO_NEG(bench_ ## name ## _float64, float64, PREC_FLOAT64, op, n) + GEN_BENCH_NO_NEG(bench_ ## name ## _float64, float64, PREC_FLOAT64, op, n) \ + GEN_BENCH_NO_NEG(bench_ ## name ## _float128, float128, PREC_FLOAT128, op, n) GEN_BENCH_ALL_TYPES_NO_NEG(sqrt, OP_SQRT, 1) #undef GEN_BENCH_ALL_TYPES_NO_NEG @@ -397,6 +469,7 @@ GEN_BENCH_ALL_TYPES_NO_NEG(sqrt, OP_SQRT, 1) [PREC_DOUBLE] = bench_ ## opname ## _double, \ [PREC_FLOAT32] = bench_ ## opname ## _float32, \ [PREC_FLOAT64] = bench_ ## opname ## _float64, \ + [PREC_FLOAT128] = bench_ ## opname ## _float128, \ } static const bench_func_t bench_funcs[OP_MAX_NR][PREC_MAX_NR] = { @@ -445,7 +518,7 @@ static void usage_complete(int argc, char *argv[]) fprintf(stderr, " -h = show this help message.\n"); fprintf(stderr, " -o = floating point operation (%s). Default: %s\n", op_list, op_names[0]); - fprintf(stderr, " -p = floating point precision (single, double). " + fprintf(stderr, " -p = floating point precision (single, double, quad[soft only]). " "Default: single\n"); fprintf(stderr, " -r = rounding mode (even, zero, down, up, tieaway). " "Default: even\n"); @@ -565,6 +638,8 @@ static void parse_args(int argc, char *argv[]) precision = PREC_SINGLE; } else if (!strcmp(optarg, "double")) { precision = PREC_DOUBLE; + } else if (!strcmp(optarg, "quad")) { + precision = PREC_QUAD; } else { fprintf(stderr, "Unsupported precision '%s'\n", optarg); exit(EXIT_FAILURE); @@ -608,6 +683,9 @@ static void parse_args(int argc, char *argv[]) case PREC_DOUBLE: precision = PREC_FLOAT64; break; + case PREC_QUAD: + precision = PREC_FLOAT128; + break; default: g_assert_not_reached(); } From patchwork Tue Oct 20 16:37:38 2020 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: 270866 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2D9F7C4363A for ; Tue, 20 Oct 2020 16:53:53 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 54CEE20704 for ; Tue, 20 Oct 2020 16:53:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="liD8uhbw" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 54CEE20704 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:54896 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kUutT-0001bd-CQ for qemu-devel@archiver.kernel.org; Tue, 20 Oct 2020 12:53:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49434) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kUue9-0007wf-6l for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:38:02 -0400 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]:33797) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kUue2-000104-Na for qemu-devel@nongnu.org; Tue, 20 Oct 2020 12:38:00 -0400 Received: by mail-wr1-x429.google.com with SMTP id i1so2978681wro.1 for ; Tue, 20 Oct 2020 09:37:54 -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=eYa6Q4RE3MycBw08Hofq/5V0wFL9wifbiVGcaMm5vtU=; b=liD8uhbwwVGL07PJL2ZBbsD0vJq0ODIn1Ez7pzEKVlDJ2B1tiGejZ3pKO3MUexwMiq XhET1RrUjQHWSvS5Hh+Gvu9ebdc1aN1Lx7qOqPSeN2mAgG3JOeOBG8tibps9mQciLME3 bq81NkovadjHnSh2k+9OLSqcC81Uevlf46zdQFLrUwmgohSWpzJwT72mCT1RFvaKkPbm 9ijMVjX5eant/h+vbNxPtGzdmYMHOqWD8zbgE6YsljFwEu6/zHE5HkoI8y4ndTHjOIyS IX/0zHRRvZmMs/wYVcypBdcLCaCheid26qlnx6449rDsV08rUq/reZNu2fihz9hRqNEq XDzg== 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=eYa6Q4RE3MycBw08Hofq/5V0wFL9wifbiVGcaMm5vtU=; b=m1lXENPTSppItoPxQ4D5G/SboHPZAGIjHQPxx104xJ5R7rPg84OxHETjOFMrYtVTv8 +c4+jMBvUyk4qHYdqMyAPtXveYQwjAxt9adkErVC9A0IuFaFPsMeXzjieIJ5uL5WwcQA 5alETkm+WWFt348NaSSkJUvR814htKhk5gATKAvbSEqzeUYHDe89e8gQiynHDKJEzTVs t/CU/G+4QCnlV/C4Lq9aAZSRz4Wz0Qgk7W6HGa0/Zomf/zhjBvhbK3v+bIMFau/sFvtx BOU3KxjDMdJ8Pym8dmvC6ajlWcq/Csz4oQX0CB2DPEXkWJlF9+3C/psRkteDCXMRoz0s qlyw== X-Gm-Message-State: AOAM530sx+zf/Ba/B1O0iWvrQVeZHWIjZW3XQmgUIZ1BWuSQyitVEqTo akQY5Fb1wtoD4zbAVbI4acE6qg== X-Google-Smtp-Source: ABdhPJwX7rqVP5zKEwc2NEVTIug9bbAUz+BzG8lIVzqn0sr89NPcy8EiwL5QO8nPegC/5igpCzEm8w== X-Received: by 2002:adf:ee4c:: with SMTP id w12mr4319211wro.22.1603211873167; Tue, 20 Oct 2020 09:37:53 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id d30sm3988261wrc.19.2020.10.20.09.37.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 09:37:44 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 62AE11FF96; Tue, 20 Oct 2020 17:37:40 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: qemu-devel@nongnu.org Subject: [RFC PATCH 8/8] softfloat: implement addsub_floats128 using Uint128 and new style code Date: Tue, 20 Oct 2020 17:37:38 +0100 Message-Id: <20201020163738.27700-9-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201020163738.27700-1-alex.bennee@linaro.org> References: <20201020163738.27700-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::429; envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x429.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. 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: Peter Maydell , cota@braap.org, =?utf-8?q?Al?= =?utf-8?q?ex_Benn=C3=A9e?= , Aurelien Jarno Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This inevitably leads to duplication of almost identical functions for the 128 bit and the 64/32/16 bit code. We will try and address that later. The expanded code is longer than the previous softfloat code and we see a drop in performance from ~85 MFlops to ~72 MFlops. Signed-off-by: Alex Bennée --- include/fpu/softfloat-macros.h | 17 + fpu/softfloat.c | 586 ++++++++++++++++++++------------- fpu/softfloat-specialize.c.inc | 39 +++ 3 files changed, 421 insertions(+), 221 deletions(-) diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index 95d88d05b8..8e6158886d 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -259,6 +259,23 @@ static inline void } +/* as above with Uint128 */ +static inline Uint128 shift128RightJammingUint128(Int128 in, int count) +{ + Uint128 out; + + if (count == 0) { + out = in; + } else if ( count < 128 ) { + Uint128 jam_mask = uint128_sub(uint128_lshift(1, count), 1); + int shifted_away = uint128_and(in, jam_mask) != 0; + out = uint128_or(uint128_rshift(in, count), shifted_away); + } else { + out = ( in != 0 ); + } + return out; +} + /*---------------------------------------------------------------------------- | Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right | by 64 _plus_ the number of bits given in `count'. The shifted result is diff --git a/fpu/softfloat.c b/fpu/softfloat.c index e038434a07..694616bb3d 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -517,9 +517,20 @@ typedef struct { bool sign; } FloatParts; +/* Similar for float128. */ +typedef struct { + Uint128 frac; + int32_t exp; + FloatClass cls; + bool sign; +} FloatParts128; + #define DECOMPOSED_BINARY_POINT (64 - 2) #define DECOMPOSED_IMPLICIT_BIT (1ull << DECOMPOSED_BINARY_POINT) #define DECOMPOSED_OVERFLOW_BIT (DECOMPOSED_IMPLICIT_BIT << 1) +#define DECOMPOSED128_BINARY_POINT (128 - 2) +#define DECOMPOSED128_IMPLICIT_BIT (uint128_lshift(1, DECOMPOSED128_BINARY_POINT)) +#define DECOMPOSED128_OVERFLOW_BIT (uint128_lshift(DECOMPOSED128_IMPLICIT_BIT, 1)) /* Structure holding all of the relevant parameters for a format. * exp_size: the size of the exponent field @@ -559,6 +570,13 @@ typedef struct { .round_mask = (1ull << (DECOMPOSED_BINARY_POINT - F)) - 1, \ .roundeven_mask = (2ull << (DECOMPOSED_BINARY_POINT - F)) - 1 +#define FLOAT128_PARAMS(E, F) \ + .exp_size = E, \ + .exp_bias = ((1 << E) - 1) >> 1, \ + .exp_max = (1 << E) - 1, \ + .frac_size = F, \ + .frac_shift = DECOMPOSED128_BINARY_POINT - F, + static const FloatFmt float16_params = { FLOAT_PARAMS(5, 10) }; @@ -580,6 +598,16 @@ static const FloatFmt float64_params = { FLOAT_PARAMS(11, 52) }; +static const FloatFmt float128_params = { + FLOAT128_PARAMS(15, 112) + /* the remaining fields are not used for 128 bit ops */ + .frac_lsb = 0, + .frac_lsbm1 = 0, + .round_mask = 0, + .roundeven_mask = 0, + .arm_althp = false +}; + /* Unpack a float to parts, but do not canonicalize. */ static inline FloatParts unpack_raw(FloatFmt fmt, uint64_t raw) { @@ -593,6 +621,18 @@ static inline FloatParts unpack_raw(FloatFmt fmt, uint64_t raw) }; } +static inline FloatParts128 unpack128_raw(FloatFmt fmt, Uint128 raw) +{ + const int sign_pos = fmt.frac_size + fmt.exp_size; + + return (FloatParts128) { + .cls = float_class_unclassified, + .sign = extract128(raw, sign_pos, 1), + .exp = extract128(raw, fmt.frac_size, fmt.exp_size), + .frac = extract128(raw, 0, fmt.frac_size), + }; +} + static inline FloatParts float16_unpack_raw(float16 f) { return unpack_raw(float16_params, f); @@ -613,6 +653,11 @@ static inline FloatParts float64_unpack_raw(float64 f) return unpack_raw(float64_params, f); } +static inline FloatParts128 float128_unpack_raw(float128 f) +{ + return unpack128_raw(float128_params, uint128_make128(f.low, f.high)); +} + /* Pack a float from parts, but do not canonicalize. */ static inline uint64_t pack_raw(FloatFmt fmt, FloatParts p) { @@ -621,6 +666,13 @@ static inline uint64_t pack_raw(FloatFmt fmt, FloatParts p) return deposit64(ret, sign_pos, 1, p.sign); } +static inline Uint128 pack128_raw(FloatFmt fmt, FloatParts128 p) +{ + const int sign_pos = fmt.frac_size + fmt.exp_size; + Uint128 ret = deposit128(p.frac, fmt.frac_size, fmt.exp_size, p.exp); + return deposit128(ret, sign_pos, 1, p.sign); +} + static inline float16 float16_pack_raw(FloatParts p) { return make_float16(pack_raw(float16_params, p)); @@ -641,6 +693,12 @@ static inline float64 float64_pack_raw(FloatParts p) return make_float64(pack_raw(float64_params, p)); } +static inline float128 float128_pack_raw(FloatParts128 p) +{ + Uint128 out = pack128_raw(float128_params, p); + return make_float128(uint128_gethi(out), uint128_getlo(out)); +} + /*---------------------------------------------------------------------------- | Functions and definitions to determine: (1) whether tininess for underflow | is detected before or after rounding by default, (2) what (if anything) @@ -684,6 +742,41 @@ static FloatParts sf_canonicalize(FloatParts part, const FloatFmt *parm, return part; } +/* Almost exactly the same as sf_canonicalize except 128 bit */ +static FloatParts128 sf128_canonicalize(FloatParts128 part, const FloatFmt *parm, + float_status *status) +{ + bool frac_is_zero = uint128_eq(part.frac, uint128_zero()); + if (part.exp == parm->exp_max) { + if (frac_is_zero) { + part.cls = float_class_inf; + } else { + part.frac = uint128_lshift(part.frac, parm->frac_shift); + part.cls = (parts128_is_snan_frac(part.frac, status) + ? float_class_snan : float_class_qnan); + } + } else if (part.exp == 0) { + if (likely(frac_is_zero)) { + part.cls = float_class_zero; + } else if (status->flush_inputs_to_zero) { + float_raise(float_flag_input_denormal, status); + part.cls = float_class_zero; + part.frac = uint128_zero(); + } else { + int shift = clz128(part.frac) - 1; + part.cls = float_class_normal; + part.exp = parm->frac_shift - parm->exp_bias - shift + 1; + part.frac = uint128_lshift(part.frac, shift); + } + } else { + Uint128 imp_bit = uint128_lshift(1, DECOMPOSED128_BINARY_POINT); + part.cls = float_class_normal; + part.exp -= parm->exp_bias; + part.frac = uint128_add(imp_bit, uint128_lshift(part.frac, parm->frac_shift)); + } + return part; +} + /* Round and uncanonicalize a floating-point number by parts. There * are FRAC_SHIFT bits that may require rounding at the bottom of the * fraction; these bits will be removed. The exponent will be biased @@ -836,6 +929,144 @@ static FloatParts round_canonical(FloatParts p, float_status *s, return p; } +/* As above but wider */ +static FloatParts128 round128_canonical(FloatParts128 p, float_status *s, + const FloatFmt *parm) +{ + /* Do these by hand rather than widening the FloatFmt structure */ + const Uint128 frac_lsb = uint128_lshift(1, DECOMPOSED128_BINARY_POINT - parm->frac_size); + const Uint128 frac_lsbm1 = uint128_lshift(1, (DECOMPOSED128_BINARY_POINT - parm->frac_size) - 1); + const Uint128 round_mask = uint128_sub(frac_lsb, 1); + const Uint128 roundeven_mask = uint128_sub(uint128_lshift(2, DECOMPOSED128_BINARY_POINT - parm->frac_size), 1); + const int exp_max = parm->exp_max; + const int frac_shift = parm->frac_shift; + Uint128 frac, inc; + int exp, flags = 0; + bool overflow_norm; + + frac = p.frac; + exp = p.exp; + + switch (p.cls) { + case float_class_normal: + switch (s->float_rounding_mode) { + case float_round_nearest_even: + overflow_norm = false; + inc = ((frac & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0); + break; + case float_round_ties_away: + overflow_norm = false; + inc = frac_lsbm1; + break; + case float_round_to_zero: + overflow_norm = true; + inc = 0; + break; + case float_round_up: + inc = p.sign ? 0 : round_mask; + overflow_norm = p.sign; + break; + case float_round_down: + 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(); + } + + exp += parm->exp_bias; + if (likely(exp > 0)) { + if (frac & round_mask) { + flags |= float_flag_inexact; + frac += inc; + if (frac & DECOMPOSED128_OVERFLOW_BIT) { + frac >>= 1; + exp++; + } + } + frac >>= frac_shift; + + if (unlikely(exp >= exp_max)) { + flags |= float_flag_overflow | float_flag_inexact; + if (overflow_norm) { + exp = exp_max - 1; + frac = -1; + } else { + p.cls = float_class_inf; + goto do_inf; + } + } + } else if (s->flush_to_zero) { + flags |= float_flag_output_denormal; + p.cls = float_class_zero; + goto do_zero; + } else { + bool is_tiny = s->tininess_before_rounding + || (exp < 0) + || !(uint128_and(uint128_add(frac, inc), DECOMPOSED128_OVERFLOW_BIT)); + + frac = shift128RightJammingUint128(frac, 1 - exp); + if (frac & round_mask) { + /* Need to recompute round-to-even. */ + switch (s->float_rounding_mode) { + case float_round_nearest_even: + inc = ((uint128_and(frac, roundeven_mask)) != frac_lsbm1 + ? frac_lsbm1 : 0); + break; + case float_round_to_odd: + inc = uint128_and(frac, frac_lsb ? 0 : round_mask); + break; + default: + break; + } + flags |= float_flag_inexact; + uint128_add(frac, inc); + } + + exp = (uint128_and(frac, DECOMPOSED128_IMPLICIT_BIT) ? 1 : 0); + frac = uint128_rshift(frac, parm->frac_shift); + + if (is_tiny && (flags & float_flag_inexact)) { + flags |= float_flag_underflow; + } + if (exp == 0 && frac == 0) { + p.cls = float_class_zero; + } + } + break; + + case float_class_zero: + do_zero: + exp = 0; + frac = 0; + break; + + case float_class_inf: + do_inf: + exp = exp_max; + frac = 0; + break; + + case float_class_qnan: + case float_class_snan: + exp = exp_max; + frac = uint128_rshift(frac, parm->frac_shift); + break; + + default: + g_assert_not_reached(); + } + + float_raise(flags, s); + p.exp = exp; + p.frac = frac; + return p; +} + /* Explicit FloatFmt version */ static FloatParts float16a_unpack_canonical(float16 f, float_status *s, const FloatFmt *params) @@ -889,6 +1120,16 @@ static float64 float64_round_pack_canonical(FloatParts p, float_status *s) return float64_pack_raw(round_canonical(p, s, &float64_params)); } +static FloatParts128 float128_unpack_canonical(float128 f, float_status *s) +{ + return sf128_canonicalize(float128_unpack_raw(f), &float128_params, s); +} + +static float128 float128_round_pack_canonical(FloatParts128 p, float_status *s) +{ + return float128_pack_raw(round128_canonical(p, s, &float128_params)); +} + static FloatParts return_nan(FloatParts a, float_status *s) { switch (a.cls) { @@ -1018,6 +1259,110 @@ static FloatParts addsub_floats(FloatParts a, FloatParts b, bool subtract, g_assert_not_reached(); } +/* As above but with Uint128 fractions */ +static FloatParts128 pick_nan128(FloatParts128 a, FloatParts128 b, float_status *s) +{ + if (is_snan(a.cls) || is_snan(b.cls)) { + s->float_exception_flags |= float_flag_invalid; + } + + if (s->default_nan_mode) { + return parts128_default_nan(s); + } else { + if (pickNaN(a.cls, b.cls, + a.frac > b.frac || + (a.frac == b.frac && a.sign < b.sign), s)) { + a = b; + } + if (is_snan(a.cls)) { + return parts128_silence_nan(a, s); + } + } + return a; +} + +static FloatParts128 addsub_floats128(FloatParts128 a, FloatParts128 b, bool subtract, + float_status *s) +{ + bool a_sign = a.sign; + bool b_sign = b.sign ^ subtract; + + if (a_sign != b_sign) { + /* Subtraction */ + + if (a.cls == float_class_normal && b.cls == float_class_normal) { + if (a.exp > b.exp || (a.exp == b.exp && a.frac >= b.frac)) { + b.frac = shift128RightJammingUint128(b.frac, a.exp - b.exp); + a.frac = uint128_sub(a.frac, b.frac); + } else { + a.frac = shift128RightJammingUint128(a.frac, b.exp - a.exp); + a.frac = uint128_sub(b.frac, a.frac); + a.exp = b.exp; + a_sign ^= 1; + } + + if (a.frac == 0) { + a.cls = float_class_zero; + a.sign = s->float_rounding_mode == float_round_down; + } else { + int shift = clz128(a.frac) - 1; + a.frac = uint128_lshift(a.frac, shift); + a.exp = a.exp - shift; + a.sign = a_sign; + } + return a; + } + if (is_nan(a.cls) || is_nan(b.cls)) { + return pick_nan128(a, b, s); + } + if (a.cls == float_class_inf) { + if (b.cls == float_class_inf) { + float_raise(float_flag_invalid, s); + return parts128_default_nan(s); + } + return a; + } + if (a.cls == float_class_zero && b.cls == float_class_zero) { + a.sign = s->float_rounding_mode == float_round_down; + return a; + } + if (a.cls == float_class_zero || b.cls == float_class_inf) { + b.sign = a_sign ^ 1; + return b; + } + if (b.cls == float_class_zero) { + return a; + } + } else { + /* Addition */ + if (a.cls == float_class_normal && b.cls == float_class_normal) { + if (a.exp > b.exp) { + b.frac = shift128RightJammingUint128(b.frac, a.exp - b.exp); + } else if (a.exp < b.exp) { + a.frac = shift128RightJammingUint128(a.frac, b.exp - a.exp); + a.exp = b.exp; + } + a.frac = uint128_add(a.frac, b.frac); + if (a.frac & DECOMPOSED128_OVERFLOW_BIT) { + a.frac = shift128RightJammingUint128(a.frac, 1); + a.exp += 1; + } + return a; + } + if (is_nan(a.cls) || is_nan(b.cls)) { + return pick_nan128(a, b, s); + } + if (a.cls == float_class_inf || b.cls == float_class_zero) { + return a; + } + if (b.cls == float_class_inf || a.cls == float_class_zero) { + b.sign = b_sign; + return b; + } + } + g_assert_not_reached(); +} + /* * Returns the result of adding or subtracting the floating-point * values `a' and `b'. The operation is performed according to the @@ -1157,6 +1502,26 @@ float64_sub(float64 a, float64 b, float_status *s) return float64_addsub(a, b, s, hard_f64_sub, soft_f64_sub); } +float128 QEMU_FLATTEN +float128_add(float128 a, float128 b, float_status *status) +{ + FloatParts128 pa = float128_unpack_canonical(a, status); + FloatParts128 pb = float128_unpack_canonical(b, status); + FloatParts128 pr = addsub_floats128(pa, pb, false, status); + + return float128_round_pack_canonical(pr, status); +} + +float128 QEMU_FLATTEN +float128_sub(float128 a, float128 b, float_status *status) +{ + FloatParts128 pa = float128_unpack_canonical(a, status); + FloatParts128 pb = float128_unpack_canonical(b, status); + FloatParts128 pr = addsub_floats128(pa, pb, true, status); + + return float128_round_pack_canonical(pr, status); +} + /* * Returns the result of adding or subtracting the bfloat16 * values `a' and `b'. @@ -6921,227 +7286,6 @@ float128 float128_round_to_int(float128 a, float_status *status) } -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the quadruple-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 float128 addFloat128Sigs(float128 a, float128 b, bool zSign, - float_status *status) -{ - int32_t aExp, bExp, zExp; - uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; - int32_t expDiff; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) { - if ( aExp == 0x7FFF ) { - if (aSig0 | aSig1) { - return propagateFloat128NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig0 |= UINT64_C(0x0001000000000000); - } - shift128ExtraRightJamming( - bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FFF ) { - if (bSig0 | bSig1) { - return propagateFloat128NaN(a, b, status); - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig0 |= UINT64_C(0x0001000000000000); - } - shift128ExtraRightJamming( - aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 ); - zExp = bExp; - } - else { - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 | bSig0 | bSig1 ) { - return propagateFloat128NaN(a, b, status); - } - return a; - } - add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - if ( aExp == 0 ) { - if (status->flush_to_zero) { - if (zSig0 | zSig1) { - float_raise(float_flag_output_denormal, status); - } - return packFloat128(zSign, 0, 0, 0); - } - return packFloat128( zSign, 0, zSig0, zSig1 ); - } - zSig2 = 0; - zSig0 |= UINT64_C(0x0002000000000000); - zExp = aExp; - goto shiftRight1; - } - aSig0 |= UINT64_C(0x0001000000000000); - add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - --zExp; - if ( zSig0 < UINT64_C(0x0002000000000000) ) goto roundAndPack; - ++zExp; - shiftRight1: - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); - roundAndPack: - return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the quadruple- -| 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 float128 subFloat128Sigs(float128 a, float128 b, bool zSign, - float_status *status) -{ - int32_t aExp, bExp, zExp; - uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; - int32_t expDiff; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - expDiff = aExp - bExp; - shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); - shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 ); - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 | bSig0 | bSig1 ) { - return propagateFloat128NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float128_default_nan(status); - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig0 < aSig0 ) goto aBigger; - if ( aSig0 < bSig0 ) goto bBigger; - if ( bSig1 < aSig1 ) goto aBigger; - if ( aSig1 < bSig1 ) goto bBigger; - return packFloat128(status->float_rounding_mode == float_round_down, - 0, 0, 0); - bExpBigger: - if ( bExp == 0x7FFF ) { - if (bSig0 | bSig1) { - return propagateFloat128NaN(a, b, status); - } - return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig0 |= UINT64_C(0x4000000000000000); - } - shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); - bSig0 |= UINT64_C(0x4000000000000000); - bBigger: - sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 ); - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FFF ) { - if (aSig0 | aSig1) { - return propagateFloat128NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig0 |= UINT64_C(0x4000000000000000); - } - shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 ); - aSig0 |= UINT64_C(0x4000000000000000); - aBigger: - sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat128(zSign, zExp - 14, zSig0, zSig1, - status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the quadruple-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_add(float128 a, float128 b, float_status *status) -{ - bool aSign, bSign; - - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign == bSign ) { - return addFloat128Sigs(a, b, aSign, status); - } - else { - return subFloat128Sigs(a, b, aSign, status); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the quadruple-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_sub(float128 a, float128 b, float_status *status) -{ - bool aSign, bSign; - - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign == bSign ) { - return subFloat128Sigs(a, b, aSign, status); - } - else { - return addFloat128Sigs(a, b, aSign, status); - } - -} - /*---------------------------------------------------------------------------- | Returns the result of multiplying the quadruple-precision floating-point | values `a' and `b'. The operation is performed according to the IEC/IEEE diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc index c2f87addb2..347896bf57 100644 --- a/fpu/softfloat-specialize.c.inc +++ b/fpu/softfloat-specialize.c.inc @@ -125,6 +125,16 @@ static bool parts_is_snan_frac(uint64_t frac, float_status *status) } } +static bool parts128_is_snan_frac(Uint128 frac, float_status *status) +{ + if (no_signaling_nans(status)) { + return false; + } else { + bool msb = extract128(frac, DECOMPOSED128_BINARY_POINT - 1, 1); + return msb == snan_bit_is_one(status); + } +} + /*---------------------------------------------------------------------------- | The pattern for a default generated deconstructed floating-point NaN. *----------------------------------------------------------------------------*/ @@ -169,6 +179,23 @@ static FloatParts parts_default_nan(float_status *status) }; } +static FloatParts128 parts128_default_nan(float_status *status) +{ + bool sign = 0; + Uint128 frac; + + /* !snan_bit_is_one, set sign and msb */ + frac = uint128_lshift(1, DECOMPOSED128_BINARY_POINT - 1); + sign = 1; + + return (FloatParts128) { + .cls = float_class_qnan, + .sign = sign, + .exp = INT_MAX, + .frac = frac + }; +} + /*---------------------------------------------------------------------------- | Returns a quiet NaN from a signalling NaN for the deconstructed | floating-point parts. @@ -191,6 +218,18 @@ static FloatParts parts_silence_nan(FloatParts a, float_status *status) return a; } +static FloatParts128 parts128_silence_nan(FloatParts128 a, float_status *status) +{ + g_assert(!no_signaling_nans(status)); + if (snan_bit_is_one(status)) { + return parts128_default_nan(status); + } else { + a.frac = uint128_or(a.frac, int128_lshift(1, DECOMPOSED128_BINARY_POINT - 1)); + } + a.cls = float_class_qnan; + return a; +} + /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. *----------------------------------------------------------------------------*/