From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997337473610.7529363954967; Mon, 11 Dec 2017 05:02:17 -0800 (PST) Received: from localhost ([::1]:52608 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONio-0006Hr-2O for importer@patchew.org; Mon, 11 Dec 2017 08:02:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51416) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONdv-0002JW-VX for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONdt-0007Y5-At for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:12 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:43926) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONdt-0007XB-4U for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:09 -0500 Received: by mail-wr0-x244.google.com with SMTP id z34so17439199wrz.10 for ; Mon, 11 Dec 2017 04:57:08 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id r14sm20060585wrb.43.2017.12.11.04.57.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:06 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 76C5B3E042D; Mon, 11 Dec 2017 12:57:05 +0000 (GMT) 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=kFWWImcJFakK6Q/MS9IUPme+eMbtlWRk0/W9mj8nEvI=; b=ea6sGEAVJgWF1bzup+xnZvuOFG8RCcJnt+M36usCfZx2qxRSCj/r3lmSntOkiucKWU HGfh1d3GtuRJOGBFQQSvNmdFXFdDFZhURtqCa3gIfp4+mmlyvm9+bmoJGHnzBpvdMpdu h5b1I+X3yJJ/ATHTz1upZIKH3vlXYtPSVqcU8= 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=kFWWImcJFakK6Q/MS9IUPme+eMbtlWRk0/W9mj8nEvI=; b=WvsjEc4ck0ymMKTlBVwAQAXwV9/qJN1btQQQk/GNUu/kRdW3gy42j8nHDTcICwoOAz pAeDxRL9Q3tteDDxLF62dEgLxzTHDuMPzKhY7iqjrQdm42RptauBFieol+WckcNqvjPk XCo7Gu9N3Tpym8oDEngvnkZC93rbPGt3c0wPZgVpygTXXcuLO0WXB18ChjAJHVPUXTuY jpMNoaI1yhqqHRtgl2IvmlXs5Nu3buaXjMtzL9qgopYE6UjIUJx6y1Pia0aLLE37Qd4L 5A42TqqVJhRe6VeDUoAZEQLET+zL05DDi73dhlldlP4adGzIf7C8LlK4z3NDhaewRbbw mXCw== X-Gm-Message-State: AKGB3mII6uO/C7wflZfIAaj0YWGLigEKQJjuSLt5f7mUMF+7Eh6+cSJV gNoaJ8u48/g/QAk5kHMGtznMmQ== X-Google-Smtp-Source: ACJfBoucH4+IUEGa9BWJoii3GRhsL9vHmzwr87V/na07PMrPVWVofFyQRt+1hgowsVlXH06lempE/w== X-Received: by 10.223.176.113 with SMTP id g46mr300933wra.267.1512997027866; Mon, 11 Dec 2017 04:57:07 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:47 +0000 Message-Id: <20171211125705.16120-2-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v1 01/19] fpu/softfloat: implement float16_squash_input_denormal 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 This will be required when expanding the MINMAX() macro for 16 bit/half-precision operations. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- fpu/softfloat.c | 15 +++++++++++++++ include/fpu/softfloat.h | 1 + 2 files changed, 16 insertions(+) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 433c5dad2d..3a4ab1355f 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3488,6 +3488,21 @@ static float16 roundAndPackFloat16(flag zSign, int z= Exp, return packFloat16(zSign, zExp, zSig >> 13); } =20 +/*------------------------------------------------------------------------= ---- +| If `a' is denormal and we are in flush-to-zero mode then set the +| input-denormal exception and return zero. Otherwise just return the valu= e. +*-------------------------------------------------------------------------= ---*/ +float16 float16_squash_input_denormal(float16 a, float_status *status) +{ + if (status->flush_inputs_to_zero) { + if (extractFloat16Exp(a) =3D=3D 0 && extractFloat16Frac(a) !=3D 0)= { + float_raise(float_flag_input_denormal, status); + return make_float16(float16_val(a) & 0x8000); + } + } + return a; +} + static void normalizeFloat16Subnormal(uint32_t aSig, int *zExpPtr, uint32_t *zSigPtr) { diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 0f96a0edd1..d5e99667b6 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -277,6 +277,7 @@ void float_raise(uint8_t flags, float_status *status); | If `a' is denormal and we are in flush-to-zero mode then set the | input-denormal exception and return zero. Otherwise just return the valu= e. *-------------------------------------------------------------------------= ---*/ +float16 float16_squash_input_denormal(float16 a, float_status *status); float32 float32_squash_input_denormal(float32 a, float_status *status); float64 float64_squash_input_denormal(float64 a, float_status *status); =20 --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997165702287.9290936587563; Mon, 11 Dec 2017 04:59:25 -0800 (PST) Received: from localhost ([::1]:52586 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONfs-0003Tq-Tw for importer@patchew.org; Mon, 11 Dec 2017 07:59:12 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51412) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONdv-0002JU-Uk for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONdu-0007ZG-9G for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:12 -0500 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:45377) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONdu-0007YG-32 for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:10 -0500 Received: by mail-wm0-x243.google.com with SMTP id 9so14236012wme.4 for ; Mon, 11 Dec 2017 04:57:09 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id o88sm19867994wrc.10.2017.12.11.04.57.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:06 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 886953E0620; Mon, 11 Dec 2017 12:57:05 +0000 (GMT) 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=u5wQ9RSdeDG1Nh66eJT3Ak6Ya8mFr9eGwuAxMU+ctEc=; b=D3hLtmfsFjL4E5J5x2LNzfNQv7/V3W6XsH0NfTJwcVzZureJwgFY2kCsK/RIjaMW2v inKqvfvmpqY077tSwwQ3MgCRp+mp+GoeQpJlFhiIGmaOueOgsiuUjGQg9VKVlJZ0Z0JW Vr0P/SXzbyvPm1ENhYPUUb8txADsXVniUdtuI= 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=u5wQ9RSdeDG1Nh66eJT3Ak6Ya8mFr9eGwuAxMU+ctEc=; b=AOVYcCZyjlWt/kT3d0vnYntB/a8xC7f/tosiVjQK4GPzgsXg7eTbbYUn5eijBOwqMH 4S0UxGysKbnlJrxoXBzpGQGRf7KMlup8CUQMGtniqA/4jrvwc0Ez8K8zLjEh2ydMbjck esdCAs3E4tsQyAz6q1gVwXAolq/kgewAsCBEtjvAEj+cu8heq3xBxTdZeJirkNiAgZTr 2NAwiaFyrdoGnE5CfJPMMAd8r+3XuS+Ktq3Oey0eGgOL9YX22X38RrGM3bFSom/apwjx +yRGSn2BuFlynjMfF3g2qeUXrkOQxmrvjqkGIlKycgwiKDOYPmRrFg/EyxlOzsDERKyX nyJw== X-Gm-Message-State: AKGB3mL81FpPaIRjnRmghOn8OLDF0vit0wvqOo+BHZvsH/6LcGcCT2GU S+VIIy0yBSg96owsDni/PYeZwg== X-Google-Smtp-Source: ACJfBov7H4bAeYWdEtwhlh473mxgScAgzQHRpE71giwKUY7TdAgK/GH5D9I05PjUKgb14mWBsJrz9g== X-Received: by 10.28.54.207 with SMTP id y76mr800617wmh.94.1512997028895; Mon, 11 Dec 2017 04:57:08 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:48 +0000 Message-Id: <20171211125705.16120-3-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::243 Subject: [Qemu-devel] [PATCH v1 02/19] include/fpu/softfloat: implement float16_abs helper 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 This will be required when expanding the MINMAX() macro for 16 bit/half-precision operations. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/fpu/softfloat.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index d5e99667b6..edf402d422 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -374,6 +374,13 @@ static inline int float16_is_zero_or_denormal(float16 = a) return (float16_val(a) & 0x7c00) =3D=3D 0; } =20 +static inline float16 float16_abs(float16 a) +{ + /* Note that abs does *not* handle NaN specially, nor does + * it flush denormal inputs to zero. + */ + return make_float16(float16_val(a) & 0x7fff); +} /*------------------------------------------------------------------------= ---- | The pattern for a default generated half-precision NaN. *-------------------------------------------------------------------------= ---*/ --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997159077600.7331087405781; Mon, 11 Dec 2017 04:59:19 -0800 (PST) Received: from localhost ([::1]:52587 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONfs-0003UO-Gp for importer@patchew.org; Mon, 11 Dec 2017 07:59:12 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51422) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONdw-0002JY-6y for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONdv-0007aZ-Hr for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:12 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:33095) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONdv-0007Zs-BF for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:11 -0500 Received: by mail-wr0-x244.google.com with SMTP id v22so17487449wrb.0 for ; Mon, 11 Dec 2017 04:57:11 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id o10sm16392287wrg.5.2017.12.11.04.57.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:07 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 99D753E0980; Mon, 11 Dec 2017 12:57:05 +0000 (GMT) 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=WZvri1dDkG2IakN/Qfkr3MWLAtg0qnWiEiEX++bbsGw=; b=GMegaiGgES4glguOVJzA/BGbdrfptNykTYAvcm8uG1EGll0x+AreKxISvHgVxLB/UL kA/sDho1Axe3oWvJiEkkdT/Hz/ABJiSG79HrwX7CcSCy2qD4KNuA8Ig/hdoo5lSpkfty Y7N35+kTxWIty29V/9jGxwZ26iGX7OGit7m9Y= 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=WZvri1dDkG2IakN/Qfkr3MWLAtg0qnWiEiEX++bbsGw=; b=U4gFfyxMTvOZbN9ezJZ8yXowPi0R878963TtXFHOI6zSotP3igrUdwRS7byCgXMnZp lhpYz9jMwDY2wBaDk9Uj2orpMsXHPA7WPHci8smsWMciOlfItnmRjSpYPafGz1ocsGXY /usOaLgEcvqK4wNNP8X1Y8IRuu5pb2YrQoFwbBXvdEJwF8SqmkXWerYZcjxu+NQ1cgyM bQ9ucBCslX5U8W/BqfurIcoRcqUIKN3EQdYQ7B1IzidXkXKQKt2TS6wqQK9MqSDwlyIR M4+IpxLSfAycB9AYgnRT6QpPr85qiWRfAJgk3U2sPlbBTAIQIry7L5RXb2FfN3r5NP31 Riqw== X-Gm-Message-State: AKGB3mKmW33YSClLGYyA6ZIEjuZY6FV/aXZNIg6eqJ+0n3zCoZNm4bkt +9bmOsNcvOR7ctfM/58KW0Si3g== X-Google-Smtp-Source: ACJfBotMXJ9W+KObR6GuIG0P8d+O3KVzJ2pLmSVZL3BO397Ei7aypGfjUe7Lnyeq0nLzN8AtnXlnXQ== X-Received: by 10.223.148.199 with SMTP id 65mr332551wrr.14.1512997030192; Mon, 11 Dec 2017 04:57:10 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:49 +0000 Message-Id: <20171211125705.16120-4-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v1 03/19] include/fpu/softfloat: implement float16_chs helper 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- include/fpu/softfloat.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index edf402d422..32036382c6 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -381,6 +381,15 @@ static inline float16 float16_abs(float16 a) */ return make_float16(float16_val(a) & 0x7fff); } + +static inline float16 float16_chs(float16 a) +{ + /* Note that chs does *not* handle NaN specially, nor does + * it flush denormal inputs to zero. + */ + return make_float16(float16_val(a) ^ 0x8000); +} + /*------------------------------------------------------------------------= ---- | The pattern for a default generated half-precision NaN. *-------------------------------------------------------------------------= ---*/ --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997520544794.6300810119935; Mon, 11 Dec 2017 05:05:20 -0800 (PST) Received: from localhost ([::1]:52622 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONle-0002wo-7b for importer@patchew.org; Mon, 11 Dec 2017 08:05:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51504) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONe0-0002Mv-N4 for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONdw-0007bL-9Y for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:16 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:43925) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONdw-0007aN-3N for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:12 -0500 Received: by mail-wr0-x242.google.com with SMTP id z34so17439355wrz.10 for ; Mon, 11 Dec 2017 04:57:11 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id r14sm15427220wra.71.2017.12.11.04.57.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:07 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id AB6103E098D; Mon, 11 Dec 2017 12:57:05 +0000 (GMT) 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=X3hgaRG54kX7m+io7AI45XFgBi4t8Rc9hxlfJtpvpb0=; b=V7RGqFiwNxg1ML9ZWDyTsDRkJBL/+2fI/VbVn7nOMUuAryS5alXWyN3bPTD1s9BJZd VdixBodAYYXOl9x7CmvSjpXIYEM9VmE9jT7zC5wEItVp3nAb/KqCQiW8/2Vj8DhUnuyS PJmuOVhFKPj710Iy/OUZ4Od3F+dgVvFHDAZjI= 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=X3hgaRG54kX7m+io7AI45XFgBi4t8Rc9hxlfJtpvpb0=; b=cMOTo6ccYZjcQCgditXt7VWyuNcdWVkpABOBIErZVQL3zTMO12T77kd/Pz6TdZK+fz KmcoXSPy8yn9+zyCapKQF3FCyYpfMPsjjRo8wQstRouxzOL4xGsahp8suC6JufpRHBCG DYyxKw1AF2sY9Foqa5Xnlo/dTjiLeBQ6mp1KEmP3Fi3AR/B76qhRAhFvlCgktqlpL6as Dmde2piRZmq8YJ7fgRO/AplbZIFZ8BMpY+OBRY+4JH31AWsPf9QfR0vSXel/LpIuu9gZ pF1D+jJSjLcJ5IiXNLcb4tyTz8rxm4JjKC7sXIuoR2womvdVc6V19m8FFod05KdvbDs8 gV5A== X-Gm-Message-State: AKGB3mK21fjjV6UdtfnujyIPNh+SdEdlEdrPpEySWPHUPZeILoGWulIb WlYkfkSxlBAlI3tboGjmpYdgCA== X-Google-Smtp-Source: ACJfBou2Dc7LvFRSvj6NVFCCUpwEnSX3qyypMjI9VC5HzxCuD84Z8c/qmHP7d+aTOkcDchg2jgGH8g== X-Received: by 10.223.171.177 with SMTP id s46mr315433wrc.194.1512997030937; Mon, 11 Dec 2017 04:57:10 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:50 +0000 Message-Id: <20171211125705.16120-5-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::242 Subject: [Qemu-devel] [PATCH v1 04/19] include/fpu/softfloat: implement float16_set_sign helper 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- include/fpu/softfloat.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 32036382c6..17dfe60dbd 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -390,6 +390,11 @@ static inline float16 float16_chs(float16 a) return make_float16(float16_val(a) ^ 0x8000); } =20 +static inline float16 float16_set_sign(float16 a, int sign) +{ + return make_float16((float16_val(a) & 0x7fff) | (sign << 15)); +} + /*------------------------------------------------------------------------= ---- | The pattern for a default generated half-precision NaN. *-------------------------------------------------------------------------= ---*/ --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997336669144.4341123672491; Mon, 11 Dec 2017 05:02:16 -0800 (PST) Received: from localhost ([::1]:52609 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONip-0006IN-2P for importer@patchew.org; Mon, 11 Dec 2017 08:02:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51470) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONdy-0002Kj-JQ for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONdx-0007d7-PL for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:14 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:45092) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONdx-0007c4-K4 for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:13 -0500 Received: by mail-wr0-x241.google.com with SMTP id h1so17430996wre.12 for ; Mon, 11 Dec 2017 04:57:13 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id n17sm8661877wmd.22.2017.12.11.04.57.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:10 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id BC1A53E0990; Mon, 11 Dec 2017 12:57:05 +0000 (GMT) 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=wP46SW2yKAaBmdenl9zzdRFHNYQbxZPYsnCJ88KO1hI=; b=SR2T/vLKEnltmpgfgR24vtr+Wf0BgToXQ6TRMJW8y5NXkKIc25EBMufZz8gyyoBISp DsckOgZJaHjrsqoiauvZ4OHffm6Pq8soz0Yt0dc0hszznYTNFG7Co6GMKlxfBQLNX3Xm LMbHTQgbjBHYGgfex7sbS55wfHyNInNfG+RAY= 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=wP46SW2yKAaBmdenl9zzdRFHNYQbxZPYsnCJ88KO1hI=; b=OZtkT8EYNlz0Lk/7MzM8Waez180NLH+l52mIuhQNlfSSRXk612K2g7d09iCqXEO322 h9yisCx2O2whPOso/gv4WovC62t33BB8b6SYMeDI7r/+VedQqLbfdXLmGpOztW7GW/PG oj2LHJ2zLcuI7Np+E1cGeq+PwZgKh75wV+h8nuLmFMFfW1ic3hikx/0dtdBwNYK3k83s LPf81rLQ5DAwJCEHtw5I3V4tupGOxu8pqXkcWA9JX07eWHruZyHYrpZRPr0RGjK1yNYJ Nn/XoctpzoIbjjq3Y/BA8Oly+SRpMgvQuIpaaJzcv+l2myz8JMOd/G3OEWj1mxhjbQDA lwjA== X-Gm-Message-State: AKGB3mJ0v+tkxCCiy7PIH21wWY4kK5LQtrEPEWRI7ZepD4pxncrOBqzM 4GXgpzClrMVAbmNHfRtSm0XYYg== X-Google-Smtp-Source: ACJfBouwxFtAEHeMwXKTMoJODMs7dRSKmuBwgfy3UZ7mwR5/4G2lLWCDP820hZnNuCb4ps5UmfDXcQ== X-Received: by 10.223.149.6 with SMTP id 6mr314677wrs.112.1512997032444; Mon, 11 Dec 2017 04:57:12 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:51 +0000 Message-Id: <20171211125705.16120-6-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::241 Subject: [Qemu-devel] [PATCH v1 05/19] include/fpu/softfloat: add some float16 contants 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 This defines the same set of common constants for float 16 as defined for 32 and 64 bit floats. These are often used by target helper functions. Signed-off-by: Alex Benn=C3=A9e --- include/fpu/softfloat.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 17dfe60dbd..5a9258c57c 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -395,6 +395,13 @@ static inline float16 float16_set_sign(float16 a, int = sign) return make_float16((float16_val(a) & 0x7fff) | (sign << 15)); } =20 +#define float16_zero make_float16(0) +#define float16_one make_float16(0x3a00) +#define float16_ln2 make_float16(0x34d1) +#define float16_pi make_float16(0x4448) +#define float16_half make_float16(0x3800) +#define float16_infinity make_float16(0x7a00) + /*------------------------------------------------------------------------= ---- | The pattern for a default generated half-precision NaN. *-------------------------------------------------------------------------= ---*/ --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151299725207490.34425943932831; Mon, 11 Dec 2017 05:00:52 -0800 (PST) Received: from localhost ([::1]:52603 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONhN-0004tL-Im for importer@patchew.org; Mon, 11 Dec 2017 08:00:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51486) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONdz-0002La-Ea for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONdy-0007e5-IT for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:15 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:45093) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONdy-0007dE-CL for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:14 -0500 Received: by mail-wr0-x242.google.com with SMTP id h1so17431058wre.12 for ; Mon, 11 Dec 2017 04:57:14 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 201sm8488742wmm.38.2017.12.11.04.57.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:10 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id CDF1C3E0992; Mon, 11 Dec 2017 12:57:05 +0000 (GMT) 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=a8qJvGNOHj73yUicqTGoW6jItVWTSgReiBPPFz2yrLk=; b=Ktv/wxD1H2PdhZcXiBa12rQRFBC5iXsSmM0PNtPExSiPxrSc0avcU34rVNEUXR6yF4 KBkivQj2stXv0ciPqnjDp4SV+Cu49srFUQ4/k7NwYdwdPdNomwjKIzcn74F7DvI/RXf/ oi6/tucajccxCaD6WaCW2CS0VcQH2aSU8I6cU= 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=a8qJvGNOHj73yUicqTGoW6jItVWTSgReiBPPFz2yrLk=; b=o7cWHOKXpSwGhgFdP7vFDZKlohpkqYrS2DddPS9I7toSTyLRL8y5txA2e8BpufPGLw Cmx3OorrwNsL1IYSdQn52pnNndZmUcb/dvEHJwGjbcKfXa2Hoi2FfXbzCNszFibtN0YA yg7waHmxjijURrmrObphrHYMcnuKxLx+NAbG3mCoFyYGzINPveIzz6BNVXaOgkn90PcT MFmiqHq9vGYaAXOGjO5siLhRpoKQoAxQIVu9iB7Zo4tRhD//NHmKuKVJctW9bZwksVvv YeMCZS8ylibgcMp1K55/eHk7vcGjrSy1uqcUr+BCYgYuNOFh8FFjcSrYEtq9PmzoNkTM zFKg== X-Gm-Message-State: AKGB3mK1WRMyNRmhxdmVzc0Ne6IL/tWw7/gTE2JMcJwqvtAxZT3zatXj vZIHehHs45N+1yRHcXJpfvnU47d3nYY= X-Google-Smtp-Source: ACJfBouGMIGXYpTTq8P/NbMOpNIVl35ZOPztXKVyQGrjqnK7a/hXvoG5Hp9AdOjNcs0zjlpDQz5dFg== X-Received: by 10.223.158.203 with SMTP id b11mr346185wrf.82.1512997033243; Mon, 11 Dec 2017 04:57:13 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:52 +0000 Message-Id: <20171211125705.16120-7-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::242 Subject: [Qemu-devel] [PATCH v1 06/19] fpu/softfloat: propagate signalling NaNs in MINMAX 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 While a comparison between a QNaN and a number will return the number it is not the same with a signaling NaN. In this case the SNaN will "win" and after potentially raising an exception it will be quietened. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- v2 - added return for propageFloat --- fpu/softfloat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3a4ab1355f..44c043924e 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -7683,6 +7683,7 @@ int float128_compare_quiet(float128 a, float128 b, fl= oat_status *status) * minnum() and maxnum() functions. These are similar to the min() * and max() functions but if one of the arguments is a QNaN and * the other is numerical then the numerical argument is returned. + * SNaNs will get quietened before being returned. * minnum() and maxnum correspond to the IEEE 754-2008 minNum() * and maxNum() operations. min() and max() are the typical min/max * semantics provided by many CPUs which predate that specification. @@ -7703,11 +7704,14 @@ static inline float ## s float ## s ## _minmax(floa= t ## s a, float ## s b, \ if (float ## s ## _is_any_nan(a) || \ float ## s ## _is_any_nan(b)) { \ if (isieee) { \ - if (float ## s ## _is_quiet_nan(a, status) && \ + if (float ## s ## _is_signaling_nan(a, status) || \ + float ## s ## _is_signaling_nan(b, status)) { \ + return propagateFloat ## s ## NaN(a, b, status); \ + } else if (float ## s ## _is_quiet_nan(a, status) && \ !float ## s ##_is_any_nan(b)) { \ return b; \ } else if (float ## s ## _is_quiet_nan(b, status) && \ - !float ## s ## _is_any_nan(a)) { \ + !float ## s ## _is_any_nan(a)) { \ return a; \ } \ } \ --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997343796262.7864825649532; Mon, 11 Dec 2017 05:02:23 -0800 (PST) Received: from localhost ([::1]:52610 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONiw-0006OQ-8v for importer@patchew.org; Mon, 11 Dec 2017 08:02:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51571) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONe4-0002QK-Bb for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONe1-0007hy-Uz for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:20 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:35787) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONe1-0007gp-PO for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:17 -0500 Received: by mail-wr0-x244.google.com with SMTP id g53so17479029wra.2 for ; Mon, 11 Dec 2017 04:57:17 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id s30sm17434558wrc.89.2017.12.11.04.57.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:11 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id DF2C43E099D; Mon, 11 Dec 2017 12:57:05 +0000 (GMT) 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=FzwTmZYzQddLlG5oQWYZVSPcWE3+WT8pXshd4eSan+k=; b=KS3Qj0JnsDt0s3wqunMV3ZVgte8dRN+cD4nBkqN8qQCfevueyXZctFUxKrwzqnU6qN xpbPjXtiJb2y0q2pw7PYSTDJQIBk9FaHlD6ztz6LYdyRCYVehobaPBbueZU6ZIfATCCo aPXU8+x40+BhCE0V9SyE1VwyvQbb90wgCn/3Q= 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=FzwTmZYzQddLlG5oQWYZVSPcWE3+WT8pXshd4eSan+k=; b=ey4Y5AsUCTTu/GFPbcNPy1NDdqduNLrCibiCey/1CSTBZhKgG7+m/V0SflrY6cRTTy fTmvLsTQPco8BAj133rCHDzbqv19k7tfrDcrMrPpWcSbE2c1DvRo0r4u9mmFwZBm5dsu y0U3BTbJIZl9DxVLtQCNd6oXf9sCYhI49csjGXtVUAtzRtFLDv8f00YaVUZdVA+MkFFv oeXhXVXIFVVPE22X8l0MaVcDFIo2Wm1rlxezcn9kRtatFqOn+Vj4bhJMfIPcmZ1JuQ4m 8KcVeuDvhMRZuZ38v9vTqbyk+r8HyvWRtaLRUFnlmhHQOndIyitkcTcPbBWSVwN6pLSh wpxw== X-Gm-Message-State: AKGB3mJ8waswnOxOzdh9MxUQ0nkgDZpu9CGFdzoZDtDn9DgOv7wEFadH 8OHqakPFedePwDp08+MAUo8lfA== X-Google-Smtp-Source: ACJfBos7Z/oxwuJCvhypCDjKTv0M8BVChzo0jhGGSnI/WceBTkMASj3VPRBCCr/lxc+icod9me1COQ== X-Received: by 10.223.181.132 with SMTP id c4mr319251wre.42.1512997036638; Mon, 11 Dec 2017 04:57:16 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:53 +0000 Message-Id: <20171211125705.16120-8-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v1 07/19] fpu/softfloat: improve comments on ARM NaN propagation 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Mention the pseudo-code fragment from which this is based and correct the spelling of signalling. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- fpu/softfloat-specialize.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index de2c5d5702..3d507d8c77 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -445,14 +445,15 @@ static float32 commonNaNToFloat32(commonNaNT a, float= _status *status) =20 #if defined(TARGET_ARM) static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, - flag aIsLargerSignificand) + flag aIsLargerSignificand) { - /* ARM mandated NaN propagation rules: take the first of: - * 1. A if it is signaling - * 2. B if it is signaling + /* ARM mandated NaN propagation rules (see FPProcessNaNs()), take + * the first of: + * 1. A if it is signalling + * 2. B if it is signalling * 3. A (quiet) * 4. B (quiet) - * A signaling NaN is always quietened before returning it. + * A signalling NaN is always quietened before returning it. */ if (aIsSNaN) { return 0; --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997737608287.9968069198685; Mon, 11 Dec 2017 05:08:57 -0800 (PST) Received: from localhost ([::1]:52701 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONpG-0008BN-3g for importer@patchew.org; Mon, 11 Dec 2017 08:08:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51570) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONe4-0002QJ-BL for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONe1-0007gx-9i for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:20 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:44849) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONe1-0007g1-0S for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:17 -0500 Received: by mail-wr0-x243.google.com with SMTP id l22so17456934wrc.11 for ; Mon, 11 Dec 2017 04:57:16 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id m11sm16176601wrf.56.2017.12.11.04.57.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:11 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id EFF153E099E; Mon, 11 Dec 2017 12:57:05 +0000 (GMT) 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=b6zTeLeoJwXTa0YonO9q4Wjz9CylVVC+D6KJ/p8yPj8=; b=LNuw23AhkRiW4FD7dTWhUPsapQxPk7FgF5V3jTOZRwAsS6z7lVNsZgIYwb+sbaycs2 vjm+DK1doQlVovfjI6757iujBMB7Esn+x0Z2YjcVZedsNKrdJ3rwV1RxR0YueBcBYnVI wweu9s0QF1xQXKlB3MGvKDMsCdSjL2OrgYFr8= 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=b6zTeLeoJwXTa0YonO9q4Wjz9CylVVC+D6KJ/p8yPj8=; b=dfUrm3XiVPScZ0nQCYn8+HsULm6noMt71lqrP728hM3kj0DSEb/vJVPV1JJgOXLd0U KjL/NVeuu/hWVv3hkUegD/ocd1w8Cr+HSVIX4PdSqDfIVE3PDeSPNsp4CtDybElAxPId 9YChGak7ywV/9S0+nj3UoiCaOgo5jaFmzRc3wLWuqvagkQw/hutxWM89s7y+Qzzqcpss F1JfkEza5uG/m0Lvgiin1ePVxFMnJB0dLdoIbd4ymJH+E2Z+8wKoP7Awfd1vw7hHoTvB qz2D/XJDyRQjO8+/eQXZ2zh3zIZ2n/P3hhUXPK3Z9Fu+2SMTSUOf7Twt36aKNoI2U2/v XVMQ== X-Gm-Message-State: AKGB3mIH3TgZdPJHx2K1zFefKMds02abhpsRudCwi3zUbFeWqCFSXeo6 wJPJNYZZxlQcu4bsIqjtBlHanA== X-Google-Smtp-Source: ACJfBot4WVtOG43nimEmaPnfBKnoeUXiGTMJkrp7u37a9VrwWt7XeE/pYDUCiTG8U1E5r5ot7QrYsg== X-Received: by 10.223.158.147 with SMTP id a19mr312760wrf.179.1512997035709; Mon, 11 Dec 2017 04:57:15 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:54 +0000 Message-Id: <20171211125705.16120-9-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::243 Subject: [Qemu-devel] [PATCH v1 08/19] fpu/softfloat: move the extract functions to the top of the file 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 This is pure code-motion during re-factoring as the helpers will be needed earlier. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- fpu/softfloat.c | 119 +++++++++++++++++++++++++---------------------------= ---- 1 file changed, 53 insertions(+), 66 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 44c043924e..0850a78149 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -132,6 +132,59 @@ static inline flag extractFloat16Sign(float16 a) return float16_val(a)>>15; } =20 +/*------------------------------------------------------------------------= ---- +| Returns the fraction bits of the single-precision floating-point value `= a'. +*-------------------------------------------------------------------------= ---*/ + +static inline uint32_t extractFloat32Frac(float32 a) +{ + return float32_val(a) & 0x007FFFFF; +} + +/*------------------------------------------------------------------------= ---- +| Returns the exponent bits of the single-precision floating-point value `= a'. +*-------------------------------------------------------------------------= ---*/ + +static inline int extractFloat32Exp(float32 a) +{ + return (float32_val(a) >> 23) & 0xFF; +} + +/*------------------------------------------------------------------------= ---- +| Returns the sign bit of the single-precision floating-point value `a'. +*-------------------------------------------------------------------------= ---*/ + +static inline flag extractFloat32Sign(float32 a) +{ + return float32_val(a) >> 31; +} + +/*------------------------------------------------------------------------= ---- +| Returns the fraction bits of the double-precision floating-point value `= a'. +*-------------------------------------------------------------------------= ---*/ + +static inline uint64_t extractFloat64Frac(float64 a) +{ + return float64_val(a) & LIT64(0x000FFFFFFFFFFFFF); +} + +/*------------------------------------------------------------------------= ---- +| Returns the exponent bits of the double-precision floating-point value `= a'. +*-------------------------------------------------------------------------= ---*/ + +static inline int extractFloat64Exp(float64 a) +{ + return (float64_val(a) >> 52) & 0x7FF; +} + +/*------------------------------------------------------------------------= ---- +| Returns the sign bit of the double-precision floating-point value `a'. +*-------------------------------------------------------------------------= ---*/ + +static inline flag extractFloat64Sign(float64 a) +{ + return float64_val(a) >> 63; +} /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -299,39 +352,6 @@ static int64_t roundAndPackUint64(flag zSign, uint64_t= absZ0, return absZ0; } =20 -/*------------------------------------------------------------------------= ---- -| Returns the fraction bits of the single-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline uint32_t extractFloat32Frac( float32 a ) -{ - - return float32_val(a) & 0x007FFFFF; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the exponent bits of the single-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline int extractFloat32Exp(float32 a) -{ - - return ( float32_val(a)>>23 ) & 0xFF; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the sign bit of the single-precision floating-point value `a'. -*-------------------------------------------------------------------------= ---*/ - -static inline flag extractFloat32Sign( float32 a ) -{ - - return float32_val(a)>>31; - -} - /*------------------------------------------------------------------------= ---- | If `a' is denormal and we are in flush-to-zero mode then set the | input-denormal exception and return zero. Otherwise just return the valu= e. @@ -492,39 +512,6 @@ static float32 =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the fraction bits of the double-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline uint64_t extractFloat64Frac( float64 a ) -{ - - return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF ); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the exponent bits of the double-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline int extractFloat64Exp(float64 a) -{ - - return ( float64_val(a)>>52 ) & 0x7FF; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the sign bit of the double-precision floating-point value `a'. -*-------------------------------------------------------------------------= ---*/ - -static inline flag extractFloat64Sign( float64 a ) -{ - - return float64_val(a)>>63; - -} - /*------------------------------------------------------------------------= ---- | If `a' is denormal and we are in flush-to-zero mode then set the | input-denormal exception and return zero. Otherwise just return the valu= e. --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997520694798.7244736173552; Mon, 11 Dec 2017 05:05:20 -0800 (PST) Received: from localhost ([::1]:52621 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONlc-0002s0-N4 for importer@patchew.org; Mon, 11 Dec 2017 08:05:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51575) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONe4-0002QN-Cv for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONe3-0007jL-Bs for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:20 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:36469) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONe3-0007iW-5f for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:19 -0500 Received: by mail-wr0-x244.google.com with SMTP id v105so17471258wrc.3 for ; Mon, 11 Dec 2017 04:57:18 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id k5sm9548239wmg.21.2017.12.11.04.57.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:11 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 0D75A3E09C4; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=XPya0JZDgDrSn8vFhXRH6qNNUTXHPncbbdbXFArQOvM=; b=EVv5w8ULzcZjILOSuXU0PM1TzaHEmVd3TXJONEqS1HUDz//nG/SIeUp/1RrF0pU2qa hUXsbdWLMvNawC8xLqlfleftONhDqbDJUfpW5qnOmzfVYbwOqj9XfMNHzlncO2ktnC6A /VQdBnCoKaAkNJrnXFCO+6NbkkFyx1utYeFuM= 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=XPya0JZDgDrSn8vFhXRH6qNNUTXHPncbbdbXFArQOvM=; b=j+2eWIiFULg2dFGN6N7G+9G25aRDUiM602lKc8Ik6vMsbVLXl+1uXljBQO0krhll1t pL7EjUQCvWrY3Rhtv3GTljFanMWgYS++IhHu17bX+Rm5gBOs/A9mh0nvFiegCIU8dH62 sq7XP2szgifCIe7b1ms/MhQGt6hcE8cbvLVlfSgKSBjEpE8maBzvwmvUpForwD20a5mG 2GDsPx8F3113Q6Xt+yqy3zWdvBjWUbFfPPd/FTRe9YrmUQm9hekvLwZ2hgi/7kFr7Na4 Znafi9vo/jWthfRydTiKG8O+/KkHBr2aHgvfSokHaVBfcFOJuOIKS98che2RuwLVbwVl DaTw== X-Gm-Message-State: AKGB3mIO98EPTu7fCPTnCRbH1/wAhCQ89/eT5kiP66aPFFNC2GvwTnaH 7AxlsnrmvEKSuzN0qVPHankmCw== X-Google-Smtp-Source: ACJfBouM7AExIxz6zyMSJWmuqNOwf6KvtakehfwqXbJSNtaYfzltPEya0cjedeXk3nIPR5PZGkqqzQ== X-Received: by 10.223.139.199 with SMTP id w7mr323225wra.282.1512997038000; Mon, 11 Dec 2017 04:57:18 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:55 +0000 Message-Id: <20171211125705.16120-10-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v1 09/19] fpu/softfloat: define decompose structures 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 These structures pave the way for generic softfloat helper routines that will operate on fully decomposed numbers. Signed-off-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 0850a78149..fe443ff234 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -83,7 +83,7 @@ this code that are retained. * target-dependent and needs the TARGET_* macros. */ #include "qemu/osdep.h" - +#include "qemu/bitops.h" #include "fpu/softfloat.h" =20 /* We only need stdlib for abort() */ @@ -185,6 +185,76 @@ static inline flag extractFloat64Sign(float64 a) { return float64_val(a) >> 63; } + +/*------------------------------------------------------------------------= ---- +| Classify a floating point number. +*-------------------------------------------------------------------------= ---*/ + +typedef enum { + float_class_unclassified, + float_class_zero, + float_class_normal, + float_class_inf, + float_class_qnan, + float_class_snan, + float_class_dnan, + float_class_msnan, /* maybe silenced */ +} float_class; + +/*------------------------------------------------------------------------= ---- +| Structure holding all of the decomposed parts of a float. +| The exponent is unbiased and the fraction is normalized. +*-------------------------------------------------------------------------= ---*/ + +typedef struct { + uint64_t frac : 64; + int exp : 32; + float_class cls : 8; + int : 23; + bool sign : 1; +} decomposed_parts; + +#define DECOMPOSED_BINARY_POINT (64 - 2) +#define DECOMPOSED_IMPLICIT_BIT (1ull << DECOMPOSED_BINARY_POINT) +#define DECOMPOSED_OVERFLOW_BIT (DECOMPOSED_IMPLICIT_BIT << 1) + +/* Structure holding all of the relevant parameters for a format. */ +typedef struct { + int exp_bias; + int exp_max; + int frac_shift; + uint64_t frac_lsb; + uint64_t frac_lsbm1; + uint64_t round_mask; + uint64_t roundeven_mask; +} decomposed_params; + +#define FRAC_PARAMS(F) \ + .frac_shift =3D F, \ + .frac_lsb =3D 1ull << (F), \ + .frac_lsbm1 =3D 1ull << ((F) - 1), \ + .round_mask =3D (1ull << (F)) - 1, \ + .roundeven_mask =3D (2ull << (F)) - 1 + +static const decomposed_params float16_params =3D { + .exp_bias =3D 0x0f, + .exp_max =3D 0x1f, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 10) +}; + +static const decomposed_params float32_params =3D { + .exp_bias =3D 0x7f, + .exp_max =3D 0xff, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 23) +}; + +static const decomposed_params float64_params =3D { + .exp_bias =3D 0x3ff, + .exp_max =3D 0x7ff, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 52) +}; + + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997848394158.5032949388002; Mon, 11 Dec 2017 05:10:48 -0800 (PST) Received: from localhost ([::1]:52731 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONqy-0001GQ-AW for importer@patchew.org; Mon, 11 Dec 2017 08:10:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51641) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONe8-0002Se-0v for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONe4-0007kx-Pv for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:24 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:40659) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONe4-0007jm-Di for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:20 -0500 Received: by mail-wr0-x244.google.com with SMTP id q9so17467428wre.7 for ; Mon, 11 Dec 2017 04:57:20 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id p15sm13969118wre.24.2017.12.11.04.57.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:11 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 217203E0A1A; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=6lbSkk1s/XmLHb3qec1ZISyhVguMCAgA2iNd6IeTJZQ=; b=VeVeo6mdUgnbojlmIoAQlOlVw33cgLBFq8Iwn1Ub6RKdP6RxDvCGUwQtNr4OEaW6iQ x1XW2013JCY/qInIpgqUGfRIeoa7yw3++JWvm8T6QQlGGU0YMNEwauj4OQc8MVd/wwdP G6TBUWArRw2GmKHjqTOVcnc5XXUmSNk/4hisk= 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=6lbSkk1s/XmLHb3qec1ZISyhVguMCAgA2iNd6IeTJZQ=; b=BqI+UJ8sHfQ0H2Qwv7Ihy3ZSb9x08llWAFwSELecZr/Bw05NP4GUEWxBDHTJJIbhLH H3bCYMARKkXLQgScawzobrxkbY7pgFY8N5roGaWLhMXuA1BUjx3x5YJgwoStXbRyZ/M2 svIJnOMzzzLDWYxfYRDH73SM1akaMm9997MIknjDWVXfhwtWsxqe7tgYHXlmczEM36r+ m+N1EUI4mTaXHdRViD2ToNR0lj7nKCjPOc//0bcbTuUw1aPnFGSD0eU5Ef9C7l6CAUW+ l7mOtCIDzvZcO4sbhYBxnhN8TDiYwZOm+7TT7NVBPc+c2QtX+2ZqG4AAVb1QxyRrfZfm oASA== X-Gm-Message-State: AKGB3mIBPckVZaeMcph0vKZYLKvnKpfqz5amdWVuvE8M/sbAraQrf5hv n0V4UTbegakQutwKPokrQ5FT5Q== X-Google-Smtp-Source: ACJfBou6Pz3M3OYteAOGJvYnv+nUGbt2jtHNcw4lGWU30498Y6zHIgb7z09MQIHuGQJMeMUzgqXL8g== X-Received: by 10.223.130.205 with SMTP id 71mr312545wrc.101.1512997038714; Mon, 11 Dec 2017 04:57:18 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:56 +0000 Message-Id: <20171211125705.16120-11-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v1 10/19] fpu/softfloat: re-factor add/sub 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We can now add float16_add/sub and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 add and sub functions. Signed-off-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 903 +++++++++++++++++++++++++-------------------= ---- include/fpu/softfloat.h | 4 + 2 files changed, 480 insertions(+), 427 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index fe443ff234..f89e47e3ef 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -195,7 +195,7 @@ typedef enum { float_class_zero, float_class_normal, float_class_inf, - float_class_qnan, + float_class_qnan, /* all NaNs from here */ float_class_snan, float_class_dnan, float_class_msnan, /* maybe silenced */ @@ -254,6 +254,481 @@ static const decomposed_params float64_params =3D { FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 52) }; =20 +/* Unpack a float16 to parts, but do not canonicalize. */ +static inline decomposed_parts float16_unpack_raw(float16 f) +{ + return (decomposed_parts){ + .cls =3D float_class_unclassified, + .sign =3D extract32(f, 15, 1), + .exp =3D extract32(f, 10, 5), + .frac =3D extract32(f, 0, 10) + }; +} + +/* Unpack a float32 to parts, but do not canonicalize. */ +static inline decomposed_parts float32_unpack_raw(float32 f) +{ + return (decomposed_parts){ + .cls =3D float_class_unclassified, + .sign =3D extract32(f, 31, 1), + .exp =3D extract32(f, 23, 8), + .frac =3D extract32(f, 0, 23) + }; +} + +/* Unpack a float64 to parts, but do not canonicalize. */ +static inline decomposed_parts float64_unpack_raw(float64 f) +{ + return (decomposed_parts){ + .cls =3D float_class_unclassified, + .sign =3D extract64(f, 63, 1), + .exp =3D extract64(f, 52, 11), + .frac =3D extract64(f, 0, 52), + }; +} + +/* Pack a float32 from parts, but do not canonicalize. */ +static inline float16 float16_pack_raw(decomposed_parts p) +{ + uint32_t ret =3D p.frac; + ret =3D deposit32(ret, 10, 5, p.exp); + ret =3D deposit32(ret, 15, 1, p.sign); + return make_float16(ret); +} + +/* Pack a float32 from parts, but do not canonicalize. */ +static inline float32 float32_pack_raw(decomposed_parts p) +{ + uint32_t ret =3D p.frac; + ret =3D deposit32(ret, 23, 8, p.exp); + ret =3D deposit32(ret, 31, 1, p.sign); + return make_float32(ret); +} + +/* Pack a float64 from parts, but do not canonicalize. */ +static inline float64 float64_pack_raw(decomposed_parts p) +{ + uint64_t ret =3D p.frac; + ret =3D deposit64(ret, 52, 11, p.exp); + ret =3D deposit64(ret, 63, 1, p.sign); + return make_float64(ret); +} + +/* Canonicalize EXP and FRAC, setting CLS. */ +static decomposed_parts decomposed_canonicalize(decomposed_parts part, + const decomposed_params *parm, + float_status *status) +{ + if (part.exp =3D=3D parm->exp_max) { + if (part.frac =3D=3D 0) { + part.cls =3D float_class_inf; + } else { +#ifdef NO_SIGNALING_NANS + part.cls =3D float_class_qnan; +#else + int64_t msb =3D part.frac << (parm->frac_shift + 2); + if ((msb < 0) =3D=3D status->snan_bit_is_one) { + part.cls =3D float_class_snan; + } else { + part.cls =3D float_class_qnan; + } +#endif + } + } else if (part.exp =3D=3D 0) { + if (likely(part.frac =3D=3D 0)) { + part.cls =3D float_class_zero; + } else if (status->flush_inputs_to_zero) { + float_raise(float_flag_input_denormal, status); + part.cls =3D float_class_zero; + part.frac =3D 0; + } else { + int shift =3D clz64(part.frac) - 1; + part.cls =3D float_class_normal; + part.exp =3D parm->frac_shift - parm->exp_bias - shift + 1; + part.frac <<=3D shift; + } + } else { + part.cls =3D float_class_normal; + part.exp -=3D parm->exp_bias; + part.frac =3D DECOMPOSED_IMPLICIT_BIT + (part.frac << parm->frac_s= hift); + } + 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 by EXP_BIAS and must be bounded by [EXP_MAX-1, 0]. */ +static decomposed_parts decomposed_round_canonical(decomposed_parts p, + float_status *s, + const decomposed_params= *parm) +{ + const uint64_t frac_lsbm1 =3D parm->frac_lsbm1; + const uint64_t round_mask =3D parm->round_mask; + const uint64_t roundeven_mask =3D parm->roundeven_mask; + const int exp_max =3D parm->exp_max; + const int frac_shift =3D parm->frac_shift; + uint64_t frac, inc; + int exp, flags =3D 0; + bool overflow_norm; + + frac =3D p.frac; + exp =3D p.exp; + + switch (p.cls) { + case float_class_normal: + switch (s->float_rounding_mode) { + case float_round_nearest_even: + overflow_norm =3D false; + inc =3D ((frac & roundeven_mask) !=3D frac_lsbm1 ? frac_lsbm1 = : 0); + break; + case float_round_ties_away: + overflow_norm =3D false; + inc =3D frac_lsbm1; + break; + case float_round_to_zero: + overflow_norm =3D true; + inc =3D 0; + break; + case float_round_up: + inc =3D p.sign ? 0 : round_mask; + overflow_norm =3D p.sign; + break; + case float_round_down: + inc =3D p.sign ? round_mask : 0; + overflow_norm =3D !p.sign; + break; + default: + g_assert_not_reached(); + } + + exp +=3D parm->exp_bias; + if (likely(exp > 0)) { + if (frac & round_mask) { + flags |=3D float_flag_inexact; + frac +=3D inc; + if (frac & DECOMPOSED_OVERFLOW_BIT) { + frac >>=3D 1; + exp++; + } + } + frac >>=3D frac_shift; + + if (unlikely(exp >=3D exp_max)) { + flags |=3D float_flag_overflow | float_flag_inexact; + if (overflow_norm) { + exp =3D exp_max - 1; + frac =3D -1; + } else { + p.cls =3D float_class_inf; + goto do_inf; + } + } + } else if (s->flush_to_zero) { + flags |=3D float_flag_output_denormal; + p.cls =3D float_class_zero; + goto do_zero; + } else { + bool is_tiny =3D (s->float_detect_tininess + =3D=3D float_tininess_before_rounding) + || (exp < 0) + || !((frac + inc) & DECOMPOSED_OVERFLOW_BIT); + + shift64RightJamming(frac, 1 - exp, &frac); + if (frac & round_mask) { + /* Need to recompute round-to-even. */ + if (s->float_rounding_mode =3D=3D float_round_nearest_even= ) { + inc =3D ((frac & roundeven_mask) !=3D frac_lsbm1 + ? frac_lsbm1 : 0); + } + flags |=3D float_flag_inexact; + frac +=3D inc; + } + + exp =3D (frac & DECOMPOSED_IMPLICIT_BIT ? 1 : 0); + frac >>=3D frac_shift; + + if (is_tiny && (flags & float_flag_inexact)) { + flags |=3D float_flag_underflow; + } + if (exp =3D=3D 0 && frac =3D=3D 0) { + p.cls =3D float_class_zero; + } + } + break; + + case float_class_zero: + do_zero: + exp =3D 0; + frac =3D 0; + break; + + case float_class_inf: + do_inf: + exp =3D exp_max; + frac =3D 0; + break; + + case float_class_qnan: + case float_class_snan: + exp =3D exp_max; + break; + + default: + g_assert_not_reached(); + } + + float_raise(flags, s); + p.exp =3D exp; + p.frac =3D frac; + return p; +} + +static decomposed_parts float16_unpack_canonical(float16 f, float_status *= s) +{ + return decomposed_canonicalize(float16_unpack_raw(f), &float16_params,= s); +} + +static float16 float16_round_pack_canonical(decomposed_parts p, float_stat= us *s) +{ + switch (p.cls) { + case float_class_dnan: + return float16_default_nan(s); + case float_class_msnan: + return float16_maybe_silence_nan(float16_pack_raw(p), s); + default: + p =3D decomposed_round_canonical(p, s, &float16_params); + return float16_pack_raw(p); + } +} + +static decomposed_parts float32_unpack_canonical(float32 f, float_status *= s) +{ + return decomposed_canonicalize(float32_unpack_raw(f), &float32_params,= s); +} + +static float32 float32_round_pack_canonical(decomposed_parts p, float_stat= us *s) +{ + switch (p.cls) { + case float_class_dnan: + return float32_default_nan(s); + case float_class_msnan: + return float32_maybe_silence_nan(float32_pack_raw(p), s); + default: + p =3D decomposed_round_canonical(p, s, &float32_params); + return float32_pack_raw(p); + } +} + +static decomposed_parts float64_unpack_canonical(float64 f, float_status *= s) +{ + return decomposed_canonicalize(float64_unpack_raw(f), &float64_params,= s); +} + +static float64 float64_round_pack_canonical(decomposed_parts p, float_stat= us *s) +{ + switch (p.cls) { + case float_class_dnan: + return float64_default_nan(s); + case float_class_msnan: + return float64_maybe_silence_nan(float64_pack_raw(p), s); + default: + p =3D decomposed_round_canonical(p, s, &float64_params); + return float64_pack_raw(p); + } +} + +static decomposed_parts pick_nan_parts(decomposed_parts a, decomposed_part= s b, + float_status *s) +{ + if (a.cls =3D=3D float_class_snan || b.cls =3D=3D float_class_snan) { + s->float_exception_flags |=3D float_flag_invalid; + } + + if (s->default_nan_mode) { + a.cls =3D float_class_dnan; + } else { + if (pickNaN(a.cls =3D=3D float_class_qnan, + a.cls =3D=3D float_class_snan, + b.cls =3D=3D float_class_qnan, + b.cls =3D=3D float_class_snan, + a.frac > b.frac + || (a.frac =3D=3D b.frac && a.sign < b.sign))) { + a =3D b; + } + a.cls =3D float_class_msnan; + } + return a; +} + + +/* + * Returns the result of adding the absolute values of the + * floating-point values `a' and `b'. If `subtract' is set, the sum is + * negated before being returned. `subtract' is ignored if the result + * is a NaN. The addition is performed according to the IEC/IEEE + * Standard for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts add_decomposed(decomposed_parts a, decomposed_part= s b, + bool subtract, float_status *s) +{ + bool a_sign =3D a.sign; + bool b_sign =3D b.sign ^ subtract; + + if (a_sign !=3D b_sign) { + /* Subtraction */ + + if (a.cls =3D=3D float_class_normal && b.cls =3D=3D float_class_no= rmal) { + int a_exp =3D a.exp; + int b_exp =3D b.exp; + uint64_t a_frac =3D a.frac; + uint64_t b_frac =3D b.frac; + + if (a_exp > b_exp || (a_exp =3D=3D b_exp && a_frac >=3D b_frac= )) { + shift64RightJamming(b_frac, a_exp - b_exp, &b_frac); + a_frac =3D a_frac - b_frac; + } else { + shift64RightJamming(a_frac, b_exp - a_exp, &a_frac); + a_frac =3D b_frac - a_frac; + a_exp =3D b_exp; + a_sign ^=3D 1; + } + + if (a_frac =3D=3D 0) { + a.cls =3D float_class_zero; + a.sign =3D s->float_rounding_mode =3D=3D float_round_down; + } else { + int shift =3D clz64(a_frac) - 1; + a.frac =3D a_frac << shift; + a.exp =3D a_exp - shift; + a.sign =3D a_sign; + } + return a; + } + if (a.cls >=3D float_class_qnan + || + b.cls >=3D float_class_qnan) + { + return pick_nan_parts(a, b, s); + } + if (a.cls =3D=3D float_class_inf) { + if (b.cls =3D=3D float_class_inf) { + float_raise(float_flag_invalid, s); + a.cls =3D float_class_dnan; + } + return a; + } + if (a.cls =3D=3D float_class_zero && b.cls =3D=3D float_class_zero= ) { + a.sign =3D s->float_rounding_mode =3D=3D float_round_down; + return a; + } + if (a.cls =3D=3D float_class_zero || b.cls =3D=3D float_class_inf)= { + b.sign =3D a_sign ^ 1; + return b; + } + if (b.cls =3D=3D float_class_zero) { + return a; + } + } else { + /* Addition */ + if (a.cls =3D=3D float_class_normal && b.cls =3D=3D float_class_no= rmal) { + int a_exp =3D a.exp; + int b_exp =3D b.exp; + uint64_t a_frac =3D a.frac; + uint64_t b_frac =3D b.frac; + + if (a_exp > b_exp) { + shift64RightJamming(b_frac, a_exp - b_exp, &b_frac); + } else if (a_exp < b_exp) { + shift64RightJamming(a_frac, b_exp - a_exp, &a_frac); + a_exp =3D b_exp; + } + a_frac +=3D b_frac; + if (a_frac & DECOMPOSED_OVERFLOW_BIT) { + a_frac >>=3D 1; + a_exp +=3D 1; + } + + a.exp =3D a_exp; + a.frac =3D a_frac; + return a; + } + if (a.cls >=3D float_class_qnan + || + b.cls >=3D float_class_qnan) { + return pick_nan_parts(a, b, s); + } + if (a.cls =3D=3D float_class_inf || b.cls =3D=3D float_class_zero)= { + return a; + } + if (b.cls =3D=3D float_class_inf || a.cls =3D=3D float_class_zero)= { + b.sign =3D 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 + * IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +float16 float16_add(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pb =3D float16_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, false, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_add(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pb =3D float32_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, false, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_add(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pb =3D float64_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, false, status); + + return float64_round_pack_canonical(pr, status); +} + +float16 float16_sub(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pb =3D float16_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, true, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_sub(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pb =3D float32_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, true, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_sub(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pb =3D float64_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, true, status); + + return float64_round_pack_canonical(pr, status); +} =20 /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 @@ -2066,219 +2541,6 @@ float32 float32_round_to_int(float32 a, float_statu= s *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of adding the absolute values of the single-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 float32 addFloat32Sigs(float32 a, float32 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint32_t aSig, bSig, zSig; - int expDiff; - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - bSig =3D extractFloat32Frac( b ); - bExp =3D extractFloat32Exp( b ); - expDiff =3D aExp - bExp; - aSig <<=3D 6; - bSig <<=3D 6; - if ( 0 < expDiff ) { - if ( aExp =3D=3D 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - --expDiff; - } - else { - bSig |=3D 0x20000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - zExp =3D aExp; - } - else if ( expDiff < 0 ) { - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp =3D=3D 0 ) { - ++expDiff; - } - else { - aSig |=3D 0x20000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - zExp =3D bExp; - } - else { - if ( aExp =3D=3D 0xFF ) { - if (aSig | bSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( aExp =3D=3D 0 ) { - if (status->flush_to_zero) { - if (aSig | bSig) { - float_raise(float_flag_output_denormal, status); - } - return packFloat32(zSign, 0, 0); - } - return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); - } - zSig =3D 0x40000000 + aSig + bSig; - zExp =3D aExp; - goto roundAndPack; - } - aSig |=3D 0x20000000; - zSig =3D ( aSig + bSig )<<1; - --zExp; - if ( (int32_t) zSig < 0 ) { - zSig =3D aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of subtracting the absolute values of the single- -| 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 float32 subFloat32Sigs(float32 a, float32 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint32_t aSig, bSig, zSig; - int expDiff; - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - bSig =3D extractFloat32Frac( b ); - bExp =3D extractFloat32Exp( b ); - expDiff =3D aExp - bExp; - aSig <<=3D 7; - bSig <<=3D 7; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp =3D=3D 0xFF ) { - if (aSig | bSig) { - return propagateFloat32NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - if ( aExp =3D=3D 0 ) { - aExp =3D 1; - bExp =3D 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat32(status->float_rounding_mode =3D=3D float_round_down= , 0, 0); - bExpBigger: - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign ^ 1, 0xFF, 0 ); - } - if ( aExp =3D=3D 0 ) { - ++expDiff; - } - else { - aSig |=3D 0x40000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - bSig |=3D 0x40000000; - bBigger: - zSig =3D bSig - aSig; - zExp =3D bExp; - zSign ^=3D 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp =3D=3D 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - --expDiff; - } - else { - bSig |=3D 0x40000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - aSig |=3D 0x40000000; - aBigger: - zSig =3D aSig - bSig; - zExp =3D aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat32(zSign, zExp, zSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of adding the single-precision floating-point values = `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard = for -| Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_add(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign; - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - aSign =3D extractFloat32Sign( a ); - bSign =3D extractFloat32Sign( b ); - if ( aSign =3D=3D bSign ) { - return addFloat32Sigs(a, b, aSign, status); - } - else { - return subFloat32Sigs(a, b, aSign, status); - } - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of subtracting the single-precision floating-point va= lues -| `a' and `b'. The operation is performed according to the IEC/IEEE Stand= ard -| for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_sub(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign; - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - aSign =3D extractFloat32Sign( a ); - bSign =3D extractFloat32Sign( b ); - if ( aSign =3D=3D bSign ) { - return subFloat32Sigs(a, b, aSign, status); - } - else { - return addFloat32Sigs(a, b, aSign, status); - } - -} =20 /*------------------------------------------------------------------------= ---- | Returns the result of multiplying the single-precision floating-point va= lues @@ -3876,219 +4138,6 @@ float64 float64_trunc_to_int(float64 a, float_statu= s *status) return res; } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of adding the absolute values of the double-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -static float64 addFloat64Sigs(float64 a, float64 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig; - int expDiff; - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - bSig =3D extractFloat64Frac( b ); - bExp =3D extractFloat64Exp( b ); - expDiff =3D aExp - bExp; - aSig <<=3D 9; - bSig <<=3D 9; - if ( 0 < expDiff ) { - if ( aExp =3D=3D 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - --expDiff; - } - else { - bSig |=3D LIT64( 0x2000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - zExp =3D aExp; - } - else if ( expDiff < 0 ) { - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp =3D=3D 0 ) { - ++expDiff; - } - else { - aSig |=3D LIT64( 0x2000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - zExp =3D bExp; - } - else { - if ( aExp =3D=3D 0x7FF ) { - if (aSig | bSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( aExp =3D=3D 0 ) { - if (status->flush_to_zero) { - if (aSig | bSig) { - float_raise(float_flag_output_denormal, status); - } - return packFloat64(zSign, 0, 0); - } - return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); - } - zSig =3D LIT64( 0x4000000000000000 ) + aSig + bSig; - zExp =3D aExp; - goto roundAndPack; - } - aSig |=3D LIT64( 0x2000000000000000 ); - zSig =3D ( aSig + bSig )<<1; - --zExp; - if ( (int64_t) zSig < 0 ) { - zSig =3D aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat64(zSign, zExp, zSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of subtracting the absolute values of the double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -static float64 subFloat64Sigs(float64 a, float64 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig; - int expDiff; - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - bSig =3D extractFloat64Frac( b ); - bExp =3D extractFloat64Exp( b ); - expDiff =3D aExp - bExp; - aSig <<=3D 10; - bSig <<=3D 10; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp =3D=3D 0x7FF ) { - if (aSig | bSig) { - return propagateFloat64NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - if ( aExp =3D=3D 0 ) { - aExp =3D 1; - bExp =3D 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat64(status->float_rounding_mode =3D=3D float_round_down= , 0, 0); - bExpBigger: - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign ^ 1, 0x7FF, 0 ); - } - if ( aExp =3D=3D 0 ) { - ++expDiff; - } - else { - aSig |=3D LIT64( 0x4000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - bSig |=3D LIT64( 0x4000000000000000 ); - bBigger: - zSig =3D bSig - aSig; - zExp =3D bExp; - zSign ^=3D 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp =3D=3D 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - --expDiff; - } - else { - bSig |=3D LIT64( 0x4000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - aSig |=3D LIT64( 0x4000000000000000 ); - aBigger: - zSig =3D aSig - bSig; - zExp =3D aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat64(zSign, zExp, zSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of adding the double-precision floating-point values = `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard = for -| Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_add(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign; - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - - aSign =3D extractFloat64Sign( a ); - bSign =3D extractFloat64Sign( b ); - if ( aSign =3D=3D bSign ) { - return addFloat64Sigs(a, b, aSign, status); - } - else { - return subFloat64Sigs(a, b, aSign, status); - } - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of subtracting the double-precision floating-point va= lues -| `a' and `b'. The operation is performed according to the IEC/IEEE Stand= ard -| for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_sub(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign; - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - - aSign =3D extractFloat64Sign( a ); - bSign =3D extractFloat64Sign( b ); - if ( aSign =3D=3D bSign ) { - return subFloat64Sigs(a, b, aSign, status); - } - else { - return addFloat64Sigs(a, b, aSign, status); - } - -} =20 /*------------------------------------------------------------------------= ---- | Returns the result of multiplying the double-precision floating-point va= lues diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 5a9258c57c..3238916aba 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -345,6 +345,10 @@ float64 float16_to_float64(float16 a, flag ieee, float= _status *status); /*------------------------------------------------------------------------= ---- | Software half-precision operations. *-------------------------------------------------------------------------= ---*/ + +float16 float16_add(float16, float16, float_status *status); +float16 float16_sub(float16, float16, float_status *status); + int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); float16 float16_maybe_silence_nan(float16, float_status *status); --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997826530645.2306656069717; Mon, 11 Dec 2017 05:10:26 -0800 (PST) Received: from localhost ([::1]:52725 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONqd-0000zv-LF for importer@patchew.org; Mon, 11 Dec 2017 08:10:19 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55032) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONn5-0005KP-Tu for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONn2-0006A8-NP for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:39 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:44910) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONn2-00069U-De for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:36 -0500 Received: by mail-wr0-x244.google.com with SMTP id l22so17488118wrc.11 for ; Mon, 11 Dec 2017 05:06:36 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 38sm19639439wry.34.2017.12.11.05.06.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 05:06:34 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 335EF3E0A29; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=LLNgZdVyhPcAlMxeRXALcg0XHGk4OuhYNQ8keGJgIiw=; b=bqK9VhOIWonBVLHbE+zjo+HsMzA2Tq4gsCZFk1fXoP2x9f8ycNNQXDDiPe5INyHkvm ttjf/KMGdWvhDBjqJxd0w6qlS0b+jj1/DRPfnjPjjUIr2SSZN0ShiXs7zNak5QPPTk9B BcMPdkJyXOCdG6GY6pCEx4tMPQZ7s8lc7Smrs= 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=LLNgZdVyhPcAlMxeRXALcg0XHGk4OuhYNQ8keGJgIiw=; b=at6dwRzKUB2mMvugLvUzmJtWgrot36C9SCABWoZpRKO4CNGrntzHHq47KNHkiMG1Xp eFMWoLOKT9DB0Y7pU1V3GBXhBuO1u07Vrh2fTyiw0T710joGtc9WKfErdm1dZd0SApVQ lPlCzNZSJD/P8ccXPL56ZLmDDDPW8Zvf7UeyQsWQtpHFGK3QTurnr7qo4jYKGFseSzRu 94lIO2J2dWKo+MiEHtLhHYPuOEAJQrsHncCiMouNqf5cFJNUcNTiYWPEutBJkdUXv0Lz 1eRx5R6RUYH8eTL9x2GDEx77D+m6XjpsXyV6Xbz7TUx0g6B6M/ZMB1dET6/82guy15DE 5pCw== X-Gm-Message-State: AKGB3mLtfACJUs+Tco+ykN1zZNHWJqONnU8GprGM6Onr7rau/tv26ZhW m/M3SjHTRXWH0Xj6hrjttTf0zA== X-Google-Smtp-Source: ACJfBosdfmOUaraVFJLy3BB4pMbW5MB7OCnlGdqFL9zyXj6O0i1O1bVzSfwZBehV+kYSAn5GvecOOw== X-Received: by 10.223.135.121 with SMTP id 54mr370455wrz.160.1512997595161; Mon, 11 Dec 2017 05:06:35 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:57 +0000 Message-Id: <20171211125705.16120-12-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v1 11/19] fpu/softfloat: re-factor mul 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We can now add float16_mul and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 versions. Signed-off-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 207 ++++++++++++++++++--------------------------= ---- include/fpu/softfloat.h | 1 + 2 files changed, 80 insertions(+), 128 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index f89e47e3ef..6e9d4c172c 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -730,6 +730,85 @@ float64 float64_sub(float64 a, float64 b, float_status= *status) return float64_round_pack_canonical(pr, status); } =20 +/* + * Returns the result of multiplying the floating-point values `a' and + * `b'. The operation is performed according to the IEC/IEEE Standard + * for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts mul_decomposed(decomposed_parts a, decomposed_part= s b, + float_status *s) +{ + bool sign =3D a.sign ^ b.sign; + + if (a.cls =3D=3D float_class_normal && b.cls =3D=3D float_class_normal= ) { + uint64_t hi, lo; + int exp =3D a.exp + b.exp; + + mul64To128(a.frac, b.frac, &hi, &lo); + shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, &hi, &lo); + if (lo & DECOMPOSED_OVERFLOW_BIT) { + shift64RightJamming(lo, 1, &lo); + exp +=3D 1; + } + + /* Re-use a */ + a.exp =3D exp; + a.sign =3D sign; + a.frac =3D lo; + return a; + } + /* handle all the NaN cases */ + if (a.cls >=3D float_class_qnan || b.cls >=3D float_class_qnan) { + return pick_nan_parts(a, b, s); + } + /* Inf * Zero =3D=3D NaN */ + if (((1 << a.cls) | (1 << b.cls)) =3D=3D + ((1 << float_class_inf) | (1 << float_class_zero))) { + s->float_exception_flags |=3D float_flag_invalid; + a.cls =3D float_class_dnan; + a.sign =3D sign; + return a; + } + /* Multiply by 0 or Inf */ + if (a.cls =3D=3D float_class_inf || a.cls =3D=3D float_class_zero) { + a.sign =3D sign; + return a; + } + if (b.cls =3D=3D float_class_inf || b.cls =3D=3D float_class_zero) { + b.sign =3D sign; + return b; + } + g_assert_not_reached(); +} + +float16 float16_mul(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pb =3D float16_unpack_canonical(b, status); + decomposed_parts pr =3D mul_decomposed(pa, pb, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_mul(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pb =3D float32_unpack_canonical(b, status); + decomposed_parts pr =3D mul_decomposed(pa, pb, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_mul(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pb =3D float64_unpack_canonical(b, status); + decomposed_parts pr =3D mul_decomposed(pa, pb, status); + + return float64_round_pack_canonical(pr, status); +} + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -2542,70 +2621,6 @@ float32 float32_round_to_int(float32 a, float_status= *status) } =20 =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of multiplying the single-precision floating-point va= lues -| `a' and `b'. The operation is performed according to the IEC/IEEE Stand= ard -| for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_mul(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint32_t aSig, bSig; - uint64_t zSig64; - uint32_t zSig; - - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - bSig =3D extractFloat32Frac( b ); - bExp =3D extractFloat32Exp( b ); - bSign =3D extractFloat32Sign( b ); - zSign =3D aSign ^ bSign; - if ( aExp =3D=3D 0xFF ) { - if ( aSig || ( ( bExp =3D=3D 0xFF ) && bSig ) ) { - return propagateFloat32NaN(a, b, status); - } - if ( ( bExp | bSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - if ( ( aExp | aSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - zExp =3D aExp + bExp - 0x7F; - aSig =3D ( aSig | 0x00800000 )<<7; - bSig =3D ( bSig | 0x00800000 )<<8; - shift64RightJamming( ( (uint64_t) aSig ) * bSig, 32, &zSig64 ); - zSig =3D zSig64; - if ( 0 <=3D (int32_t) ( zSig<<1 ) ) { - zSig <<=3D 1; - --zExp; - } - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} =20 /*------------------------------------------------------------------------= ---- | Returns the result of dividing the single-precision floating-point value= `a' @@ -4138,70 +4153,6 @@ float64 float64_trunc_to_int(float64 a, float_status= *status) return res; } =20 - -/*------------------------------------------------------------------------= ---- -| Returns the result of multiplying the double-precision floating-point va= lues -| `a' and `b'. The operation is performed according to the IEC/IEEE Stand= ard -| for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_mul(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig0, zSig1; - - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - bSig =3D extractFloat64Frac( b ); - bExp =3D extractFloat64Exp( b ); - bSign =3D extractFloat64Sign( b ); - zSign =3D aSign ^ bSign; - if ( aExp =3D=3D 0x7FF ) { - if ( aSig || ( ( bExp =3D=3D 0x7FF ) && bSig ) ) { - return propagateFloat64NaN(a, b, status); - } - if ( ( bExp | bSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - if ( ( aExp | aSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - zExp =3D aExp + bExp - 0x3FF; - aSig =3D ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig =3D ( bSig | LIT64( 0x0010000000000000 ) )<<11; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - zSig0 |=3D ( zSig1 !=3D 0 ); - if ( 0 <=3D (int64_t) ( zSig0<<1 ) ) { - zSig0 <<=3D 1; - --zExp; - } - return roundAndPackFloat64(zSign, zExp, zSig0, status); - -} - /*------------------------------------------------------------------------= ---- | Returns the result of dividing the double-precision floating-point value= `a' | by the corresponding value `b'. The operation is performed according to diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 3238916aba..1fe8734261 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -348,6 +348,7 @@ float64 float16_to_float64(float16 a, flag ieee, float_= status *status); =20 float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); +float16 float16_mul(float16, float16, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512998052162805.750367897173; Mon, 11 Dec 2017 05:14:12 -0800 (PST) Received: from localhost ([::1]:52869 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONuF-0005Ds-Iq for importer@patchew.org; Mon, 11 Dec 2017 08:14:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55066) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONnA-0005OO-Az for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONn4-0006CT-V8 for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:44 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:34302) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONn4-0006BO-Lt for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:38 -0500 Received: by mail-wr0-x244.google.com with SMTP id y21so17532075wrc.1 for ; Mon, 11 Dec 2017 05:06:38 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 90sm15429766wrp.93.2017.12.11.05.06.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 05:06:34 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 46EA43E0B5D; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=I7dngJ0yPM3FsvpuZ+nIa2f1Icnze4NIyWUeSiroSUg=; b=f6RJreK0cxX0QbnGu+SwJgTAi0Cn7TlFVUrngKz/tXsXapRKwwr8V6aZlRepbVfKXg xsYzetqG+qV5FLEImItOriGKhfD7gvH3kJs9p5RS+VgsNUtmOBJO1Tw/Mo4kScGKEdxK EGflCGFKRbzz+m2YHs39q3uITx3Svxw5Cnts0= 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=I7dngJ0yPM3FsvpuZ+nIa2f1Icnze4NIyWUeSiroSUg=; b=HnDkCS/j2Nxt5LuyMUAARHF0knXqK8mGx1sLHEJq8H7B0sm8pkHaDcT2r5Jbj/et7f vxU9RRV+aKOSTq11V3kL+dAm6Edl55L8wmGj803S20MCaFnsw2leHaqMI+kx/SON1B1o iChUMvHUx+e9thEtk5dHJxEUg5qtYDAyXRtdqQgPzDRPUOLQRdqirXwnhxSWvXwRjN/D qGI/AObt4+RremA/iBPDmEJqGpqdCNvGQDel/dbAUqceyfJjiMgyl48zVT/UEGTqT3YB FdGpWZgWOopMhnphFCeyLtjTC/y1Wtr6Ra//glsK4fDbMDg1OsYi6PvfZcY3TFffqq9l JhMw== X-Gm-Message-State: AKGB3mLkmm/t7GKnwC8jy51c7WMFO0Sv+zJQyo8uwKmEzAmf4E6/dQGy n/Ue5Oj+zRvzlikBBNFchAaJTg== X-Google-Smtp-Source: ACJfBouggZKBHwlW9tOZDDJenFGSC75vTp+zHbvEmx+4A/fIDc7n8W6Kv414dlH4RotnI8s593huTw== X-Received: by 10.223.176.113 with SMTP id g46mr333922wra.267.1512997597474; Mon, 11 Dec 2017 05:06:37 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:58 +0000 Message-Id: <20171211125705.16120-13-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v1 12/19] fpu/softfloat: re-factor div 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We can now add float16_div and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 versions. Signed-off-by: Alex Benn=C3=A9e --- fpu/softfloat-macros.h | 44 +++++++++ fpu/softfloat.c | 235 ++++++++++++++++++--------------------------= ---- include/fpu/softfloat.h | 1 + 3 files changed, 134 insertions(+), 146 deletions(-) diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h index 9cc6158cb4..980be2c051 100644 --- a/fpu/softfloat-macros.h +++ b/fpu/softfloat-macros.h @@ -625,6 +625,50 @@ static uint64_t estimateDiv128To64( uint64_t a0, uint6= 4_t a1, uint64_t b ) =20 } =20 +/* Nicked from gmp longlong.h __udiv_qrnnd */ +static uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d) +{ + uint64_t d0, d1, q0, q1, r1, r0, m; + + d0 =3D (uint32_t)d; + d1 =3D d >> 32; + + r1 =3D n1 % d1; + q1 =3D n1 / d1; + m =3D q1 * d0; + r1 =3D (r1 << 32) | (n0 >> 32); + if (r1 < m) { + q1 -=3D 1; + r1 +=3D d; + if (r1 >=3D d) { + if (r1 < m) { + q1 -=3D 1; + r1 +=3D d; + } + } + } + r1 -=3D m; + + r0 =3D r1 % d1; + q0 =3D r1 / d1; + m =3D q0 * d0; + r0 =3D (r0 << 32) | (uint32_t)n0; + if (r0 < m) { + q0 -=3D 1; + r0 +=3D d; + if (r0 >=3D d) { + if (r0 < m) { + q0 -=3D 1; + r0 +=3D d; + } + } + } + r0 -=3D m; + + /* Return remainder in LSB */ + return (q1 << 32) | q0 | (r0 !=3D 0); +} + /*------------------------------------------------------------------------= ---- | Returns an approximation to the square root of the 32-bit significand gi= ven | by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 = of diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6e9d4c172c..2b703c12ed 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -809,6 +809,95 @@ float64 float64_mul(float64 a, float64 b, float_status= *status) return float64_round_pack_canonical(pr, status); } =20 +/* + * Returns the result of dividing the floating-point value `a' by the + * corresponding value `b'. The operation is performed according to + * the IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts div_decomposed(decomposed_parts a, decomposed_part= s b, + float_status *s) +{ + bool sign =3D a.sign ^ b.sign; + + if (a.cls =3D=3D float_class_normal && b.cls =3D=3D float_class_normal= ) { + uint64_t temp_lo, temp_hi; + int exp =3D a.exp - b.exp; + if (a.frac < b.frac) { + exp -=3D 1; + shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT + 1, + &temp_hi, &temp_lo); + } else { + shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT, + &temp_hi, &temp_lo); + } + /* LSB of quot is set if inexact which roundandpack will use + * to set flags. Yet again we re-use a for the result */ + a.frac =3D div128To64(temp_lo, temp_hi, b.frac); + a.sign =3D sign; + a.exp =3D exp; + return a; + } + /* handle all the NaN cases */ + if (a.cls >=3D float_class_qnan || b.cls >=3D float_class_qnan) { + return pick_nan_parts(a, b, s); + } + /* 0/0 or Inf/Inf */ + if (a.cls =3D=3D b.cls + && + (a.cls =3D=3D float_class_inf || a.cls =3D=3D float_class_zero)) { + s->float_exception_flags |=3D float_flag_invalid; + a.cls =3D float_class_dnan; + return a; + } + /* Div 0 =3D> Inf */ + if (b.cls =3D=3D float_class_zero) { + s->float_exception_flags |=3D float_flag_divbyzero; + a.cls =3D float_class_inf; + a.sign =3D sign; + return a; + } + /* Inf / x or 0 / x */ + if (a.cls =3D=3D float_class_inf || a.cls =3D=3D float_class_zero) { + a.sign =3D sign; + return a; + } + /* Div by Inf */ + if (b.cls =3D=3D float_class_inf) { + a.cls =3D float_class_zero; + a.sign =3D sign; + return a; + } + g_assert_not_reached(); +} + +float16 float16_div(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pb =3D float16_unpack_canonical(b, status); + decomposed_parts pr =3D div_decomposed(pa, pb, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_div(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pb =3D float32_unpack_canonical(b, status); + decomposed_parts pr =3D div_decomposed(pa, pb, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_div(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pb =3D float64_unpack_canonical(b, status); + decomposed_parts pr =3D div_decomposed(pa, pb, status); + + return float64_round_pack_canonical(pr, status); +} + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -2622,75 +2711,6 @@ float32 float32_round_to_int(float32 a, float_status= *status) =20 =20 =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of dividing the single-precision floating-point value= `a' -| by the corresponding value `b'. The operation is performed according to= the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_div(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint32_t aSig, bSig, zSig; - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - bSig =3D extractFloat32Frac( b ); - bExp =3D extractFloat32Exp( b ); - bSign =3D extractFloat32Sign( b ); - zSign =3D aSign ^ bSign; - if ( aExp =3D=3D 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign, 0, 0 ); - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) { - if ( ( aExp | aSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - float_raise(float_flag_divbyzero, status); - return packFloat32( zSign, 0xFF, 0 ); - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp =3D aExp - bExp + 0x7D; - aSig =3D ( aSig | 0x00800000 )<<7; - bSig =3D ( bSig | 0x00800000 )<<8; - if ( bSig <=3D ( aSig + aSig ) ) { - aSig >>=3D 1; - ++zExp; - } - zSig =3D ( ( (uint64_t) aSig )<<32 ) / bSig; - if ( ( zSig & 0x3F ) =3D=3D 0 ) { - zSig |=3D ( (uint64_t) bSig * zSig !=3D ( (uint64_t) aSig )<<32 ); - } - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} =20 /*------------------------------------------------------------------------= ---- | Returns the remainder of the single-precision floating-point value `a' @@ -4153,83 +4173,6 @@ float64 float64_trunc_to_int(float64 a, float_status= *status) return res; } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of dividing the double-precision floating-point value= `a' -| by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_div(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig; - uint64_t rem0, rem1; - uint64_t term0, term1; - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - bSig =3D extractFloat64Frac( b ); - bExp =3D extractFloat64Exp( b ); - bSign =3D extractFloat64Sign( b ); - zSign =3D aSign ^ bSign; - if ( aExp =3D=3D 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign, 0, 0 ); - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) { - if ( ( aExp | aSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - float_raise(float_flag_divbyzero, status); - return packFloat64( zSign, 0x7FF, 0 ); - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp =3D aExp - bExp + 0x3FD; - aSig =3D ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig =3D ( bSig | LIT64( 0x0010000000000000 ) )<<11; - if ( bSig <=3D ( aSig + aSig ) ) { - aSig >>=3D 1; - ++zExp; - } - zSig =3D estimateDiv128To64( aSig, 0, bSig ); - if ( ( zSig & 0x1FF ) <=3D 2 ) { - mul64To128( bSig, zSig, &term0, &term1 ); - sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (int64_t) rem0 < 0 ) { - --zSig; - add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); - } - zSig |=3D ( rem1 !=3D 0 ); - } - return roundAndPackFloat64(zSign, zExp, zSig, status); - -} =20 /*------------------------------------------------------------------------= ---- | Returns the remainder of the double-precision floating-point value `a' diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 1fe8734261..d2b8d29f22 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -349,6 +349,7 @@ float64 float16_to_float64(float16 a, flag ieee, float_= status *status); float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); float16 float16_mul(float16, float16, float_status *status); +float16 float16_div(float16, float16, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997441793410.8346523604731; Mon, 11 Dec 2017 05:04:01 -0800 (PST) Received: from localhost ([::1]:52620 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONkV-0000Uw-Pf for importer@patchew.org; Mon, 11 Dec 2017 08:03:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51690) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONeA-0002VS-HG for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONe6-0007n5-OF for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:26 -0500 Received: from mail-wr0-x22c.google.com ([2a00:1450:400c:c0c::22c]:41589) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONe6-0007lp-A9 for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:22 -0500 Received: by mail-wr0-x22c.google.com with SMTP id z18so17479254wrb.8 for ; Mon, 11 Dec 2017 04:57:22 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id w76sm19581562wrc.79.2017.12.11.04.57.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:13 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 5B50D3E0C02; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=5t1m3meS4KvstcFcWlNP1dTrxEuOocu5zOe+N5EdqD8=; b=S62GJzBsL7PNcMScQAT6uqfaziE0kmOYUC+kt5Xij5Z0ykURiKRJ6ClryL7bGyaEM0 ekkpSMs5+jH8ZzD21eoLKjR+TFZ8CvPZoPyLwjJ7F4e7RAWSOgJtQ2VJW3Es20gfXMhg xUfD/nN3E61TjpCBoiET297qh7ebIHHMCuzRo= 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=5t1m3meS4KvstcFcWlNP1dTrxEuOocu5zOe+N5EdqD8=; b=gQtehC/ZBEIlBDc92NyUNrCCRSuN7Ec8PJkv2vAKNIL+6dDTbOMlPBhLKEhdMQyILQ fodJ8mD1/w0hRXVFQdeRjlKtvjeJ5nb5KPGqOLKP8AxN98UwwZQnZMAeUeV0/xmJ1aRN h2ssF30Idr7dCbSNYPtffFfgtjxjFh4xRu67knG20ax/vLgeuuKVOtyXhh/XVoRIuqLQ 2eGhsEILXiifDTWY+xuNVUTbmYqMFGbg6GSI8o2aNZkHca2+FnSRvRFbQTH29s7ZlqlU X7fv54rv+x0h6PR2O895JAuqHWqFkPqEQdUeTu3Ds+qobx6x1NAQIy0QcIrCDisSIIqZ ddrw== X-Gm-Message-State: AKGB3mLQv+5nVbU2VeZluYYB9akEtm6tg5u2dH6xSqH61oR/yUs9Q2xT n8VO8/mL90rmhQIwiyhp9Jm93Q== X-Google-Smtp-Source: ACJfBosklfyiQL9vrEJmy1kkvSM35aUmvo/Zd43lt4ZZVSo39W7zPgzSz5iNq4os8DRl/8zcAZxWrg== X-Received: by 10.223.139.149 with SMTP id o21mr289568wra.87.1512997040539; Mon, 11 Dec 2017 04:57:20 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:56:59 +0000 Message-Id: <20171211125705.16120-14-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::22c Subject: [Qemu-devel] [PATCH v1 13/19] fpu/softfloat: re-factor muladd 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We can now add float16_muladd and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 muladd functions. Signed-off-by: Alex Benn=C3=A9e --- fpu/softfloat-specialize.h | 104 ------- fpu/softfloat.c | 756 +++++++++++++++++------------------------= ---- include/fpu/softfloat.h | 1 + 3 files changed, 286 insertions(+), 575 deletions(-) diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 3d507d8c77..98fb0e7001 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -729,58 +729,6 @@ static float32 propagateFloat32NaN(float32 a, float32 = b, float_status *status) } } =20 -/*------------------------------------------------------------------------= ---- -| Takes three single-precision floating-point values `a', `b' and `c', one= of -| which is a NaN, and returns the appropriate NaN result. If any of `a', -| `b' or `c' is a signaling NaN, the invalid exception is raised. -| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case -| obviously c is a NaN, and whether to propagate c or some other NaN is -| implementation defined). -*-------------------------------------------------------------------------= ---*/ - -static float32 propagateFloat32MulAddNaN(float32 a, float32 b, - float32 c, flag infzero, - float_status *status) -{ - flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN; - int which; - - aIsQuietNaN =3D float32_is_quiet_nan(a, status); - aIsSignalingNaN =3D float32_is_signaling_nan(a, status); - bIsQuietNaN =3D float32_is_quiet_nan(b, status); - bIsSignalingNaN =3D float32_is_signaling_nan(b, status); - cIsQuietNaN =3D float32_is_quiet_nan(c, status); - cIsSignalingNaN =3D float32_is_signaling_nan(c, status); - - if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { - float_raise(float_flag_invalid, status); - } - - which =3D pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN, - bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN, infzero, status); - - if (status->default_nan_mode) { - /* Note that this check is after pickNaNMulAdd so that function - * has an opportunity to set the Invalid flag. - */ - return float32_default_nan(status); - } - - switch (which) { - case 0: - return float32_maybe_silence_nan(a, status); - case 1: - return float32_maybe_silence_nan(b, status); - case 2: - return float32_maybe_silence_nan(c, status); - case 3: - default: - return float32_default_nan(status); - } -} - #ifdef NO_SIGNALING_NANS int float64_is_quiet_nan(float64 a_, float_status *status) { @@ -936,58 +884,6 @@ static float64 propagateFloat64NaN(float64 a, float64 = b, float_status *status) } } =20 -/*------------------------------------------------------------------------= ---- -| Takes three double-precision floating-point values `a', `b' and `c', one= of -| which is a NaN, and returns the appropriate NaN result. If any of `a', -| `b' or `c' is a signaling NaN, the invalid exception is raised. -| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case -| obviously c is a NaN, and whether to propagate c or some other NaN is -| implementation defined). -*-------------------------------------------------------------------------= ---*/ - -static float64 propagateFloat64MulAddNaN(float64 a, float64 b, - float64 c, flag infzero, - float_status *status) -{ - flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN; - int which; - - aIsQuietNaN =3D float64_is_quiet_nan(a, status); - aIsSignalingNaN =3D float64_is_signaling_nan(a, status); - bIsQuietNaN =3D float64_is_quiet_nan(b, status); - bIsSignalingNaN =3D float64_is_signaling_nan(b, status); - cIsQuietNaN =3D float64_is_quiet_nan(c, status); - cIsSignalingNaN =3D float64_is_signaling_nan(c, status); - - if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { - float_raise(float_flag_invalid, status); - } - - which =3D pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN, - bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN, infzero, status); - - if (status->default_nan_mode) { - /* Note that this check is after pickNaNMulAdd so that function - * has an opportunity to set the Invalid flag. - */ - return float64_default_nan(status); - } - - switch (which) { - case 0: - return float64_maybe_silence_nan(a, status); - case 1: - return float64_maybe_silence_nan(b, status); - case 2: - return float64_maybe_silence_nan(c, status); - case 3: - default: - return float64_default_nan(status); - } -} - #ifdef NO_SIGNALING_NANS int floatx80_is_quiet_nan(floatx80 a_, float_status *status) { diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 2b703c12ed..bf37f23f6a 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -561,6 +561,50 @@ static decomposed_parts pick_nan_parts(decomposed_part= s a, decomposed_parts b, return a; } =20 +static decomposed_parts pick_nan_muladd_parts(decomposed_parts a, + decomposed_parts b, + decomposed_parts c, + bool inf_zero, + float_status *s) +{ + if (a.cls =3D=3D float_class_snan + || + b.cls =3D=3D float_class_snan + || + c.cls =3D=3D float_class_snan) { + s->float_exception_flags |=3D float_flag_invalid; + } + + if (s->default_nan_mode) { + a.cls =3D float_class_dnan; + } else { + switch (pickNaNMulAdd(a.cls =3D=3D float_class_qnan, + a.cls =3D=3D float_class_snan, + b.cls =3D=3D float_class_qnan, + b.cls =3D=3D float_class_snan, + c.cls =3D=3D float_class_qnan, + c.cls =3D=3D float_class_snan, + inf_zero, s)) { + case 0: + break; + case 1: + a =3D b; + break; + case 2: + a =3D c; + break; + case 3: + a.cls =3D float_class_dnan; + return a; + default: + g_assert_not_reached(); + } + + a.cls =3D float_class_msnan; + } + return a; +} + =20 /* * Returns the result of adding the absolute values of the @@ -809,6 +853,247 @@ float64 float64_mul(float64 a, float64 b, float_statu= s *status) return float64_round_pack_canonical(pr, status); } =20 +/* + * Returns the result of multiplying the floating-point values `a' and + * `b' then adding 'c', with no intermediate rounding step after the + * multiplication. The operation is performed according to the + * IEC/IEEE Standard for Binary Floating-Point Arithmetic 754-2008. + * The flags argument allows the caller to select negation of the + * addend, the intermediate product, or the final result. (The + * difference between this and having the caller do a separate + * negation is that negating externally will flip the sign bit on + * NaNs.) + */ + +static decomposed_parts muladd_decomposed(decomposed_parts a, + decomposed_parts b, + decomposed_parts c, int flags, + float_status *s) +{ + bool inf_zero =3D ((1 << a.cls) | (1 << b.cls)) =3D=3D + ((1 << float_class_inf) | (1 << float_class_zero)); + bool p_sign; + bool sign_flip =3D flags & float_muladd_negate_result; + float_class p_class; + uint64_t hi, lo; + int p_exp; + + /* 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 (a.cls >=3D float_class_qnan || + b.cls >=3D float_class_qnan || + c.cls >=3D float_class_qnan) { + return pick_nan_muladd_parts(a, b, c, inf_zero, s); + } + + if (inf_zero) { + s->float_exception_flags |=3D float_flag_invalid; + a.cls =3D float_class_dnan; + return a; + } + + if (flags & float_muladd_negate_c) { + c.sign ^=3D 1; + } + + p_sign =3D a.sign ^ b.sign; + + if (flags & float_muladd_negate_product) { + p_sign ^=3D 1; + } + + if (a.cls =3D=3D float_class_inf || b.cls =3D=3D float_class_inf) { + p_class =3D float_class_inf; + } else if (a.cls =3D=3D float_class_zero || b.cls =3D=3D float_class_z= ero) { + p_class =3D float_class_zero; + } else { + p_class =3D float_class_normal; + } + + if (c.cls =3D=3D float_class_inf) { + if (p_class =3D=3D float_class_inf && p_sign !=3D c.sign) { + s->float_exception_flags |=3D float_flag_invalid; + a.cls =3D float_class_dnan; + } else { + a.cls =3D float_class_inf; + a.sign =3D c.sign ^ sign_flip; + } + return a; + } + + if (p_class =3D=3D float_class_inf) { + a.cls =3D float_class_inf; + a.sign =3D p_sign ^ sign_flip; + return a; + } + + if (p_class =3D=3D float_class_zero) { + if (c.cls =3D=3D float_class_zero) { + if (p_sign !=3D c.sign) { + p_sign =3D s->float_rounding_mode =3D=3D float_round_down; + } + c.sign =3D p_sign; + } else if (flags & float_muladd_halve_result) { + c.exp -=3D 1; + } + c.sign ^=3D sign_flip; + return c; + } + + /* a & b should be normals now... */ + assert(a.cls =3D=3D float_class_normal && + b.cls =3D=3D float_class_normal); + + p_exp =3D a.exp + b.exp; + + /* Multiply of 2 62-bit numbers produces a (2*62) =3D=3D 124-bit + * result. + */ + mul64To128(a.frac, b.frac, &hi, &lo); + /* binary point now at bit 124 */ + + /* check for overflow */ + if (hi & (1ULL << (DECOMPOSED_BINARY_POINT * 2 + 1 - 64))) { + shift128RightJamming(hi, lo, 1, &hi, &lo); + p_exp +=3D 1; + } + + /* + add/sub */ + if (c.cls =3D=3D float_class_zero) { + /* move binary point back to 62 */ + shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, &hi, &lo); + } else { + int exp_diff =3D p_exp - c.exp; + if (p_sign =3D=3D c.sign) { + /* Addition */ + if (exp_diff <=3D 0) { + shift128RightJamming(hi, lo, + DECOMPOSED_BINARY_POINT - exp_diff, + &hi, &lo); + lo +=3D c.frac; + p_exp =3D c.exp; + } else { + uint64_t c_hi, c_lo; + /* shift c to the same binary point as the product (124) */ + c_hi =3D c.frac >> 2; + c_lo =3D 0; + shift128RightJamming(c_hi, c_lo, + exp_diff, + &c_hi, &c_lo); + add128(hi, lo, c_hi, c_lo, &hi, &lo); + /* move binary point back to 62 */ + shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, &hi,= &lo); + } + + if (lo & DECOMPOSED_OVERFLOW_BIT) { + shift64RightJamming(lo, 1, &lo); + p_exp +=3D 1; + } + + } else { + /* Subtraction */ + uint64_t c_hi, c_lo; + /* make C binary point match product at bit 124 */ + c_hi =3D c.frac >> 2; + c_lo =3D 0; + + if (exp_diff <=3D 0) { + shift128RightJamming(hi, lo, -exp_diff, &hi, &lo); + if (exp_diff =3D=3D 0 + && + (hi > c_hi || (hi =3D=3D c_hi && lo >=3D c_lo))) { + sub128(hi, lo, c_hi, c_lo, &hi, &lo); + } else { + sub128(c_hi, c_lo, hi, lo, &hi, &lo); + p_sign ^=3D 1; + p_exp =3D c.exp; + } + } else { + shift128RightJamming(c_hi, c_lo, + exp_diff, + &c_hi, &c_lo); + sub128(hi, lo, c_hi, c_lo, &hi, &lo); + } + + if (hi =3D=3D 0 && lo =3D=3D 0) { + a.cls =3D float_class_zero; + a.sign =3D s->float_rounding_mode =3D=3D float_round_down; + a.sign ^=3D sign_flip; + return a; + } else { + int shift; + if (hi !=3D 0) { + shift =3D clz64(hi); + } else { + shift =3D clz64(lo) + 64; + } + /* Normalizing to a binary point of 124 is the + correct adjust for the exponent. However since we're + shifting, we might as well put the binary point back + at 62 where we really want it. Therefore shift as + if we're leaving 1 bit at the top of the word, but + adjust the exponent as if we're leaving 3 bits. */ + shift -=3D 1; + if (shift >=3D 64) { + lo =3D lo << (shift - 64); + } else { + hi =3D (hi << shift) | (lo >> (64 - shift)); + lo =3D hi | ((lo << shift) !=3D 0); + } + p_exp -=3D shift - 2; + } + } + } + + if (flags & float_muladd_halve_result) { + p_exp -=3D 1; + } + + /* finally prepare our result */ + a.cls =3D float_class_normal; + a.sign =3D p_sign ^ sign_flip; + a.exp =3D p_exp; + a.frac =3D lo; + + return a; +} + +float16 float16_muladd(float16 a, float16 b, float16 c, int flags, + float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pb =3D float16_unpack_canonical(b, status); + decomposed_parts pc =3D float16_unpack_canonical(c, status); + decomposed_parts pr =3D muladd_decomposed(pa, pb, pc, flags, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_muladd(float32 a, float32 b, float32 c, int flags, + float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pb =3D float32_unpack_canonical(b, status); + decomposed_parts pc =3D float32_unpack_canonical(c, status); + decomposed_parts pr =3D muladd_decomposed(pa, pb, pc, flags, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_muladd(float64 a, float64 b, float64 c, int flags, + float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pb =3D float64_unpack_canonical(b, status); + decomposed_parts pc =3D float64_unpack_canonical(c, status); + decomposed_parts pr =3D muladd_decomposed(pa, pb, pc, flags, status); + + return float64_round_pack_canonical(pr, status); +} + /* * Returns the result of dividing the floating-point value `a' by the * corresponding value `b'. The operation is performed according to @@ -2814,231 +3099,6 @@ float32 float32_rem(float32 a, float32 b, float_sta= tus *status) return normalizeRoundAndPackFloat32(aSign ^ zSign, bExp, aSig, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of multiplying the single-precision floating-point va= lues -| `a' and `b' then adding 'c', with no intermediate rounding step after the -| multiplication. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic 754-2008. -| The flags argument allows the caller to select negation of the -| addend, the intermediate product, or the final result. (The difference -| between this and having the caller do a separate negation is that negati= ng -| externally will flip the sign bit on NaNs.) -*-------------------------------------------------------------------------= ---*/ - -float32 float32_muladd(float32 a, float32 b, float32 c, int flags, - float_status *status) -{ - flag aSign, bSign, cSign, zSign; - int aExp, bExp, cExp, pExp, zExp, expDiff; - uint32_t aSig, bSig, cSig; - flag pInf, pZero, pSign; - uint64_t pSig64, cSig64, zSig64; - uint32_t pSig; - int shiftcount; - flag signflip, infzero; - - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - c =3D float32_squash_input_denormal(c, status); - aSig =3D extractFloat32Frac(a); - aExp =3D extractFloat32Exp(a); - aSign =3D extractFloat32Sign(a); - bSig =3D extractFloat32Frac(b); - bExp =3D extractFloat32Exp(b); - bSign =3D extractFloat32Sign(b); - cSig =3D extractFloat32Frac(c); - cExp =3D extractFloat32Exp(c); - cSign =3D extractFloat32Sign(c); - - infzero =3D ((aExp =3D=3D 0 && aSig =3D=3D 0 && bExp =3D=3D 0xff && bS= ig =3D=3D 0) || - (aExp =3D=3D 0xff && aSig =3D=3D 0 && bExp =3D=3D 0 && bSig= =3D=3D 0)); - - /* 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 (((aExp =3D=3D 0xff) && aSig) || - ((bExp =3D=3D 0xff) && bSig) || - ((cExp =3D=3D 0xff) && cSig)) { - return propagateFloat32MulAddNaN(a, b, c, infzero, status); - } - - if (infzero) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - - if (flags & float_muladd_negate_c) { - cSign ^=3D 1; - } - - signflip =3D (flags & float_muladd_negate_result) ? 1 : 0; - - /* Work out the sign and type of the product */ - pSign =3D aSign ^ bSign; - if (flags & float_muladd_negate_product) { - pSign ^=3D 1; - } - pInf =3D (aExp =3D=3D 0xff) || (bExp =3D=3D 0xff); - pZero =3D ((aExp | aSig) =3D=3D 0) || ((bExp | bSig) =3D=3D 0); - - if (cExp =3D=3D 0xff) { - if (pInf && (pSign ^ cSign)) { - /* addition of opposite-signed infinities =3D> InvalidOperatio= n */ - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - /* Otherwise generate an infinity of the same sign */ - return packFloat32(cSign ^ signflip, 0xff, 0); - } - - if (pInf) { - return packFloat32(pSign ^ signflip, 0xff, 0); - } - - if (pZero) { - if (cExp =3D=3D 0) { - if (cSig =3D=3D 0) { - /* Adding two exact zeroes */ - if (pSign =3D=3D cSign) { - zSign =3D pSign; - } else if (status->float_rounding_mode =3D=3D float_round_= down) { - zSign =3D 1; - } else { - zSign =3D 0; - } - return packFloat32(zSign ^ signflip, 0, 0); - } - /* Exact zero plus a denorm */ - if (status->flush_to_zero) { - float_raise(float_flag_output_denormal, status); - return packFloat32(cSign ^ signflip, 0, 0); - } - } - /* Zero plus something non-zero : just return the something */ - if (flags & float_muladd_halve_result) { - if (cExp =3D=3D 0) { - normalizeFloat32Subnormal(cSig, &cExp, &cSig); - } - /* Subtract one to halve, and one again because roundAndPackFl= oat32 - * wants one less than the true exponent. - */ - cExp -=3D 2; - cSig =3D (cSig | 0x00800000) << 7; - return roundAndPackFloat32(cSign ^ signflip, cExp, cSig, statu= s); - } - return packFloat32(cSign ^ signflip, cExp, cSig); - } - - if (aExp =3D=3D 0) { - normalizeFloat32Subnormal(aSig, &aExp, &aSig); - } - if (bExp =3D=3D 0) { - normalizeFloat32Subnormal(bSig, &bExp, &bSig); - } - - /* Calculate the actual result a * b + c */ - - /* Multiply first; this is easy. */ - /* NB: we subtract 0x7e where float32_mul() subtracts 0x7f - * because we want the true exponent, not the "one-less-than" - * flavour that roundAndPackFloat32() takes. - */ - pExp =3D aExp + bExp - 0x7e; - aSig =3D (aSig | 0x00800000) << 7; - bSig =3D (bSig | 0x00800000) << 8; - pSig64 =3D (uint64_t)aSig * bSig; - if ((int64_t)(pSig64 << 1) >=3D 0) { - pSig64 <<=3D 1; - pExp--; - } - - zSign =3D pSign ^ signflip; - - /* Now pSig64 is the significand of the multiply, with the explicit bi= t in - * position 62. - */ - if (cExp =3D=3D 0) { - if (!cSig) { - /* Throw out the special case of c being an exact zero now */ - shift64RightJamming(pSig64, 32, &pSig64); - pSig =3D pSig64; - if (flags & float_muladd_halve_result) { - pExp--; - } - return roundAndPackFloat32(zSign, pExp - 1, - pSig, status); - } - normalizeFloat32Subnormal(cSig, &cExp, &cSig); - } - - cSig64 =3D (uint64_t)cSig << (62 - 23); - cSig64 |=3D LIT64(0x4000000000000000); - expDiff =3D pExp - cExp; - - if (pSign =3D=3D cSign) { - /* Addition */ - if (expDiff > 0) { - /* scale c to match p */ - shift64RightJamming(cSig64, expDiff, &cSig64); - zExp =3D pExp; - } else if (expDiff < 0) { - /* scale p to match c */ - shift64RightJamming(pSig64, -expDiff, &pSig64); - zExp =3D cExp; - } else { - /* no scaling needed */ - zExp =3D cExp; - } - /* Add significands and make sure explicit bit ends up in posn 62 = */ - zSig64 =3D pSig64 + cSig64; - if ((int64_t)zSig64 < 0) { - shift64RightJamming(zSig64, 1, &zSig64); - } else { - zExp--; - } - } else { - /* Subtraction */ - if (expDiff > 0) { - shift64RightJamming(cSig64, expDiff, &cSig64); - zSig64 =3D pSig64 - cSig64; - zExp =3D pExp; - } else if (expDiff < 0) { - shift64RightJamming(pSig64, -expDiff, &pSig64); - zSig64 =3D cSig64 - pSig64; - zExp =3D cExp; - zSign ^=3D 1; - } else { - zExp =3D pExp; - if (cSig64 < pSig64) { - zSig64 =3D pSig64 - cSig64; - } else if (pSig64 < cSig64) { - zSig64 =3D cSig64 - pSig64; - zSign ^=3D 1; - } else { - /* Exact zero */ - zSign =3D signflip; - if (status->float_rounding_mode =3D=3D float_round_down) { - zSign ^=3D 1; - } - return packFloat32(zSign, 0, 0); - } - } - --zExp; - /* Normalize to put the explicit bit back into bit 62. */ - shiftcount =3D countLeadingZeros64(zSig64) - 1; - zSig64 <<=3D shiftcount; - zExp -=3D shiftcount; - } - if (flags & float_muladd_halve_result) { - zExp--; - } - - shift64RightJamming(zSig64, 32, &zSig64); - return roundAndPackFloat32(zSign, zExp, zSig64, status); -} - =20 /*------------------------------------------------------------------------= ---- | Returns the square root of the single-precision floating-point value `a'. @@ -4262,252 +4322,6 @@ float64 float64_rem(float64 a, float64 b, float_sta= tus *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of multiplying the double-precision floating-point va= lues -| `a' and `b' then adding 'c', with no intermediate rounding step after the -| multiplication. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic 754-2008. -| The flags argument allows the caller to select negation of the -| addend, the intermediate product, or the final result. (The difference -| between this and having the caller do a separate negation is that negati= ng -| externally will flip the sign bit on NaNs.) -*-------------------------------------------------------------------------= ---*/ - -float64 float64_muladd(float64 a, float64 b, float64 c, int flags, - float_status *status) -{ - flag aSign, bSign, cSign, zSign; - int aExp, bExp, cExp, pExp, zExp, expDiff; - uint64_t aSig, bSig, cSig; - flag pInf, pZero, pSign; - uint64_t pSig0, pSig1, cSig0, cSig1, zSig0, zSig1; - int shiftcount; - flag signflip, infzero; - - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - c =3D float64_squash_input_denormal(c, status); - aSig =3D extractFloat64Frac(a); - aExp =3D extractFloat64Exp(a); - aSign =3D extractFloat64Sign(a); - bSig =3D extractFloat64Frac(b); - bExp =3D extractFloat64Exp(b); - bSign =3D extractFloat64Sign(b); - cSig =3D extractFloat64Frac(c); - cExp =3D extractFloat64Exp(c); - cSign =3D extractFloat64Sign(c); - - infzero =3D ((aExp =3D=3D 0 && aSig =3D=3D 0 && bExp =3D=3D 0x7ff && b= Sig =3D=3D 0) || - (aExp =3D=3D 0x7ff && aSig =3D=3D 0 && bExp =3D=3D 0 && bSi= g =3D=3D 0)); - - /* 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 (((aExp =3D=3D 0x7ff) && aSig) || - ((bExp =3D=3D 0x7ff) && bSig) || - ((cExp =3D=3D 0x7ff) && cSig)) { - return propagateFloat64MulAddNaN(a, b, c, infzero, status); - } - - if (infzero) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - - if (flags & float_muladd_negate_c) { - cSign ^=3D 1; - } - - signflip =3D (flags & float_muladd_negate_result) ? 1 : 0; - - /* Work out the sign and type of the product */ - pSign =3D aSign ^ bSign; - if (flags & float_muladd_negate_product) { - pSign ^=3D 1; - } - pInf =3D (aExp =3D=3D 0x7ff) || (bExp =3D=3D 0x7ff); - pZero =3D ((aExp | aSig) =3D=3D 0) || ((bExp | bSig) =3D=3D 0); - - if (cExp =3D=3D 0x7ff) { - if (pInf && (pSign ^ cSign)) { - /* addition of opposite-signed infinities =3D> InvalidOperatio= n */ - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - /* Otherwise generate an infinity of the same sign */ - return packFloat64(cSign ^ signflip, 0x7ff, 0); - } - - if (pInf) { - return packFloat64(pSign ^ signflip, 0x7ff, 0); - } - - if (pZero) { - if (cExp =3D=3D 0) { - if (cSig =3D=3D 0) { - /* Adding two exact zeroes */ - if (pSign =3D=3D cSign) { - zSign =3D pSign; - } else if (status->float_rounding_mode =3D=3D float_round_= down) { - zSign =3D 1; - } else { - zSign =3D 0; - } - return packFloat64(zSign ^ signflip, 0, 0); - } - /* Exact zero plus a denorm */ - if (status->flush_to_zero) { - float_raise(float_flag_output_denormal, status); - return packFloat64(cSign ^ signflip, 0, 0); - } - } - /* Zero plus something non-zero : just return the something */ - if (flags & float_muladd_halve_result) { - if (cExp =3D=3D 0) { - normalizeFloat64Subnormal(cSig, &cExp, &cSig); - } - /* Subtract one to halve, and one again because roundAndPackFl= oat64 - * wants one less than the true exponent. - */ - cExp -=3D 2; - cSig =3D (cSig | 0x0010000000000000ULL) << 10; - return roundAndPackFloat64(cSign ^ signflip, cExp, cSig, statu= s); - } - return packFloat64(cSign ^ signflip, cExp, cSig); - } - - if (aExp =3D=3D 0) { - normalizeFloat64Subnormal(aSig, &aExp, &aSig); - } - if (bExp =3D=3D 0) { - normalizeFloat64Subnormal(bSig, &bExp, &bSig); - } - - /* Calculate the actual result a * b + c */ - - /* Multiply first; this is easy. */ - /* NB: we subtract 0x3fe where float64_mul() subtracts 0x3ff - * because we want the true exponent, not the "one-less-than" - * flavour that roundAndPackFloat64() takes. - */ - pExp =3D aExp + bExp - 0x3fe; - aSig =3D (aSig | LIT64(0x0010000000000000))<<10; - bSig =3D (bSig | LIT64(0x0010000000000000))<<11; - mul64To128(aSig, bSig, &pSig0, &pSig1); - if ((int64_t)(pSig0 << 1) >=3D 0) { - shortShift128Left(pSig0, pSig1, 1, &pSig0, &pSig1); - pExp--; - } - - zSign =3D pSign ^ signflip; - - /* Now [pSig0:pSig1] is the significand of the multiply, with the expl= icit - * bit in position 126. - */ - if (cExp =3D=3D 0) { - if (!cSig) { - /* Throw out the special case of c being an exact zero now */ - shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1); - if (flags & float_muladd_halve_result) { - pExp--; - } - return roundAndPackFloat64(zSign, pExp - 1, - pSig1, status); - } - normalizeFloat64Subnormal(cSig, &cExp, &cSig); - } - - /* Shift cSig and add the explicit bit so [cSig0:cSig1] is the - * significand of the addend, with the explicit bit in position 126. - */ - cSig0 =3D cSig << (126 - 64 - 52); - cSig1 =3D 0; - cSig0 |=3D LIT64(0x4000000000000000); - expDiff =3D pExp - cExp; - - if (pSign =3D=3D cSign) { - /* Addition */ - if (expDiff > 0) { - /* scale c to match p */ - shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); - zExp =3D pExp; - } else if (expDiff < 0) { - /* scale p to match c */ - shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); - zExp =3D cExp; - } else { - /* no scaling needed */ - zExp =3D cExp; - } - /* Add significands and make sure explicit bit ends up in posn 126= */ - add128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - if ((int64_t)zSig0 < 0) { - shift128RightJamming(zSig0, zSig1, 1, &zSig0, &zSig1); - } else { - zExp--; - } - shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1); - if (flags & float_muladd_halve_result) { - zExp--; - } - return roundAndPackFloat64(zSign, zExp, zSig1, status); - } else { - /* Subtraction */ - if (expDiff > 0) { - shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); - sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - zExp =3D pExp; - } else if (expDiff < 0) { - shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); - sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); - zExp =3D cExp; - zSign ^=3D 1; - } else { - zExp =3D pExp; - if (lt128(cSig0, cSig1, pSig0, pSig1)) { - sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - } else if (lt128(pSig0, pSig1, cSig0, cSig1)) { - sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); - zSign ^=3D 1; - } else { - /* Exact zero */ - zSign =3D signflip; - if (status->float_rounding_mode =3D=3D float_round_down) { - zSign ^=3D 1; - } - return packFloat64(zSign, 0, 0); - } - } - --zExp; - /* Do the equivalent of normalizeRoundAndPackFloat64() but - * starting with the significand in a pair of uint64_t. - */ - if (zSig0) { - shiftcount =3D countLeadingZeros64(zSig0) - 1; - shortShift128Left(zSig0, zSig1, shiftcount, &zSig0, &zSig1); - if (zSig1) { - zSig0 |=3D 1; - } - zExp -=3D shiftcount; - } else { - shiftcount =3D countLeadingZeros64(zSig1); - if (shiftcount =3D=3D 0) { - zSig0 =3D (zSig1 >> 1) | (zSig1 & 1); - zExp -=3D 63; - } else { - shiftcount--; - zSig0 =3D zSig1 << shiftcount; - zExp -=3D (shiftcount + 64); - } - } - if (flags & float_muladd_halve_result) { - zExp--; - } - return roundAndPackFloat64(zSign, zExp, zSig0, status); - } -} =20 /*------------------------------------------------------------------------= ---- | Returns the square root of the double-precision floating-point value `a'. diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index d2b8d29f22..102cf4b1e1 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -349,6 +349,7 @@ float64 float16_to_float64(float16 a, flag ieee, float_= status *status); float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); float16 float16_mul(float16, float16, float_status *status); +float16 float16_muladd(float16, float16, float16, int, float_status *statu= s); float16 float16_div(float16, float16, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997528873789.2668896957379; Mon, 11 Dec 2017 05:05:28 -0800 (PST) Received: from localhost ([::1]:52623 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONlt-000363-9y for importer@patchew.org; Mon, 11 Dec 2017 08:05:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51620) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONe7-0002SR-7V for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONe5-0007ld-Ez for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:23 -0500 Received: from mail-wm0-x241.google.com ([2a00:1450:400c:c09::241]:35886) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONe5-0007kF-5W for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:21 -0500 Received: by mail-wm0-x241.google.com with SMTP id b76so13998566wmg.1 for ; Mon, 11 Dec 2017 04:57:20 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id t138sm9670382wme.16.2017.12.11.04.57.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:13 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 6D5563E0C32; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=TqLZ4logtnH/8CEr18id48c5CLf/Gq62Mao5MSosRfE=; b=NnY5uvU09L2ZYOSXXJOI/ySj42YHTfpC8k2cIyjnjp/RBFBI/qRdvMX+x3vEeWHXiG 8kIkqxSBR90qDSR9F7l6ZuzMVhVxrXNbN9Ysp5NJ95ytNXWNQiGDRu64LiW0hO48PdTl RZKZdZ+WUHj0qoE81t/c/ALycU4jn+o4NRa24= 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=TqLZ4logtnH/8CEr18id48c5CLf/Gq62Mao5MSosRfE=; b=n6pFEO9/qrJDv8JM2RAkx/Yg8fSvxcfEe6StF0CpIAGNR7psdR7OU3zkwTve5b5HFk Vmb0z3X5rNd5iWxdgG+tJEw2lcyIBMG8W1vzN049Grh4kOJPwsWW/cC1A3m0G39ViqrE FbBcUChO55GjJ3Z/NzcnW0w5xnOxM/qfvEUHkeOBYw2BxJ4kmeYsv6nmuiQoCVT8zh0U jF8yXWweGiLaMxFugaW8XnWygW2uR0kOOFf3xYtlo5Ee39yReYquzaxM+c8SSP+n0Fde w2JxgzpPzUBpqAGHAkWFshc/27JY5TrTKjhWZ04Zxvq7oIR2HQarEd3Vk9EoqJXxDjhe CqRg== X-Gm-Message-State: AKGB3mLtjf0kT6s4di2Y/bS8QPXN+BVpeXjt8h0MpivI4EERnwIvmiiZ hYdTef9cn4sp4yLsxJCGSerwEQ== X-Google-Smtp-Source: ACJfBotbPnP1l6gMwjxUaH76v5tnUxN5FrdhggfIYhwFL3uxFBxKgUtR7M1gt4v06IP3SFoCfnuaDQ== X-Received: by 10.28.62.5 with SMTP id l5mr713402wma.47.1512997039758; Mon, 11 Dec 2017 04:57:19 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:57:00 +0000 Message-Id: <20171211125705.16120-15-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::241 Subject: [Qemu-devel] [PATCH v1 14/19] fpu/softfloat: re-factor round_to_int 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We can now add float16_round_to_int and use the common round_decomposed and canonicalize functions to have a single implementation for float16/32/64 round_to_int functions. Signed-off-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 304 ++++++++++++++++++++------------------------= ---- include/fpu/softfloat.h | 1 + 2 files changed, 130 insertions(+), 175 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index bf37f23f6a..9914ecb783 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1183,6 +1183,135 @@ float64 float64_div(float64 a, float64 b, float_sta= tus *status) return float64_round_pack_canonical(pr, status); } =20 +/* + * Rounds the floating-point value `a' to an integer, and returns the + * result as a floating-point value. The operation is performed + * according to the IEC/IEEE Standard for Binary Floating-Point + * Arithmetic. + */ + +static decomposed_parts round_decomposed(decomposed_parts a, int rounding_= mode, + float_status *s) +{ + + switch (a.cls) { + case float_class_snan: + a.cls =3D s->default_nan_mode ? float_class_dnan : float_class_msn= an; + s->float_exception_flags |=3D float_flag_invalid; + break; + case float_class_zero: + case float_class_inf: + case float_class_qnan: + /* already "integral" */ + break; + case float_class_normal: + if (a.exp >=3D DECOMPOSED_BINARY_POINT) { + /* already integral */ + break; + } + if (a.exp < 0) { + bool one; + /* all fractional */ + s->float_exception_flags |=3D float_flag_inexact; + switch (rounding_mode) { + case float_round_nearest_even: + one =3D a.exp =3D=3D -1 && a.frac > DECOMPOSED_IMPLICIT_BI= T; + break; + case float_round_ties_away: + one =3D a.exp =3D=3D -1 && a.frac >=3D DECOMPOSED_IMPLICIT= _BIT; + break; + case float_round_to_zero: + one =3D false; + break; + case float_round_up: + one =3D !a.sign; + break; + case float_round_down: + one =3D a.sign; + break; + default: + g_assert_not_reached(); + } + + if (one) { + a.frac =3D DECOMPOSED_IMPLICIT_BIT; + a.exp =3D 0; + } else { + a.cls =3D float_class_zero; + } + } else { + uint64_t frac_lsb, frac_lsbm1, round_mask, roundeven_mask, inc; + + frac_lsb =3D DECOMPOSED_IMPLICIT_BIT >> a.exp; + frac_lsbm1 =3D frac_lsb >> 1; + roundeven_mask =3D (frac_lsb - 1) | frac_lsb; + round_mask =3D roundeven_mask >> 1; + + switch (rounding_mode) { + case float_round_nearest_even: + inc =3D ((a.frac & roundeven_mask) !=3D frac_lsbm1 ? frac_= lsbm1 : 0); + break; + case float_round_ties_away: + inc =3D frac_lsbm1; + break; + case float_round_to_zero: + inc =3D 0; + break; + case float_round_up: + inc =3D a.sign ? 0 : round_mask; + break; + case float_round_down: + inc =3D a.sign ? round_mask : 0; + break; + default: + g_assert_not_reached(); + } + + if (a.frac & round_mask) { + s->float_exception_flags |=3D float_flag_inexact; + a.frac +=3D inc; + a.frac &=3D ~round_mask; + if (a.frac & DECOMPOSED_OVERFLOW_BIT) { + a.frac >>=3D 1; + a.exp++; + } + } + } + break; + default: + g_assert_not_reached(); + } + return a; +} + +float16 float16_round_to_int(float16 a, float_status *s) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, s); + decomposed_parts pr =3D round_decomposed(pa, s->float_rounding_mode, s= ); + return float16_round_pack_canonical(pr, s); +} + +float32 float32_round_to_int(float32 a, float_status *s) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, s); + decomposed_parts pr =3D round_decomposed(pa, s->float_rounding_mode, s= ); + return float32_round_pack_canonical(pr, s); +} + +float64 float64_round_to_int(float64 a, float_status *s) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, s); + decomposed_parts pr =3D round_decomposed(pa, s->float_rounding_mode, s= ); + return float64_round_pack_canonical(pr, s); +} + +float64 float64_trunc_to_int(float64 a, float_status *s) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, s); + decomposed_parts pr =3D round_decomposed(pa, float_round_to_zero, s); + return float64_round_pack_canonical(pr, s); +} + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -2913,88 +3042,6 @@ float128 float32_to_float128(float32 a, float_status= *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Rounds the single-precision floating-point value `a' to an integer, and -| returns the result as a single-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_round_to_int(float32 a, float_status *status) -{ - flag aSign; - int aExp; - uint32_t lastBitMask, roundBitsMask; - uint32_t z; - a =3D float32_squash_input_denormal(a, status); - - aExp =3D extractFloat32Exp( a ); - if ( 0x96 <=3D aExp ) { - if ( ( aExp =3D=3D 0xFF ) && extractFloat32Frac( a ) ) { - return propagateFloat32NaN(a, a, status); - } - return a; - } - if ( aExp <=3D 0x7E ) { - if ( (uint32_t) ( float32_val(a)<<1 ) =3D=3D 0 ) return a; - status->float_exception_flags |=3D float_flag_inexact; - aSign =3D extractFloat32Sign( a ); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - if ( ( aExp =3D=3D 0x7E ) && extractFloat32Frac( a ) ) { - return packFloat32( aSign, 0x7F, 0 ); - } - break; - case float_round_ties_away: - if (aExp =3D=3D 0x7E) { - return packFloat32(aSign, 0x7F, 0); - } - break; - case float_round_down: - return make_float32(aSign ? 0xBF800000 : 0); - case float_round_up: - return make_float32(aSign ? 0x80000000 : 0x3F800000); - } - return packFloat32( aSign, 0, 0 ); - } - lastBitMask =3D 1; - lastBitMask <<=3D 0x96 - aExp; - roundBitsMask =3D lastBitMask - 1; - z =3D float32_val(a); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - z +=3D lastBitMask>>1; - if ((z & roundBitsMask) =3D=3D 0) { - z &=3D ~lastBitMask; - } - break; - case float_round_ties_away: - z +=3D lastBitMask >> 1; - break; - case float_round_to_zero: - break; - case float_round_up: - if (!extractFloat32Sign(make_float32(z))) { - z +=3D roundBitsMask; - } - break; - case float_round_down: - if (extractFloat32Sign(make_float32(z))) { - z +=3D roundBitsMask; - } - break; - default: - abort(); - } - z &=3D ~ roundBitsMask; - if (z !=3D float32_val(a)) { - status->float_exception_flags |=3D float_flag_inexact; - } - return make_float32(z); - -} - - =20 =20 /*------------------------------------------------------------------------= ---- @@ -4140,99 +4187,6 @@ float128 float64_to_float128(float64 a, float_status= *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Rounds the double-precision floating-point value `a' to an integer, and -| returns the result as a double-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_round_to_int(float64 a, float_status *status) -{ - flag aSign; - int aExp; - uint64_t lastBitMask, roundBitsMask; - uint64_t z; - a =3D float64_squash_input_denormal(a, status); - - aExp =3D extractFloat64Exp( a ); - if ( 0x433 <=3D aExp ) { - if ( ( aExp =3D=3D 0x7FF ) && extractFloat64Frac( a ) ) { - return propagateFloat64NaN(a, a, status); - } - return a; - } - if ( aExp < 0x3FF ) { - if ( (uint64_t) ( float64_val(a)<<1 ) =3D=3D 0 ) return a; - status->float_exception_flags |=3D float_flag_inexact; - aSign =3D extractFloat64Sign( a ); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - if ( ( aExp =3D=3D 0x3FE ) && extractFloat64Frac( a ) ) { - return packFloat64( aSign, 0x3FF, 0 ); - } - break; - case float_round_ties_away: - if (aExp =3D=3D 0x3FE) { - return packFloat64(aSign, 0x3ff, 0); - } - break; - case float_round_down: - return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0); - case float_round_up: - return make_float64( - aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF000000000000= 0 )); - } - return packFloat64( aSign, 0, 0 ); - } - lastBitMask =3D 1; - lastBitMask <<=3D 0x433 - aExp; - roundBitsMask =3D lastBitMask - 1; - z =3D float64_val(a); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - z +=3D lastBitMask >> 1; - if ((z & roundBitsMask) =3D=3D 0) { - z &=3D ~lastBitMask; - } - break; - case float_round_ties_away: - z +=3D lastBitMask >> 1; - break; - case float_round_to_zero: - break; - case float_round_up: - if (!extractFloat64Sign(make_float64(z))) { - z +=3D roundBitsMask; - } - break; - case float_round_down: - if (extractFloat64Sign(make_float64(z))) { - z +=3D roundBitsMask; - } - break; - default: - abort(); - } - z &=3D ~ roundBitsMask; - if (z !=3D float64_val(a)) { - status->float_exception_flags |=3D float_flag_inexact; - } - return make_float64(z); - -} - -float64 float64_trunc_to_int(float64 a, float_status *status) -{ - int oldmode; - float64 res; - oldmode =3D status->float_rounding_mode; - status->float_rounding_mode =3D float_round_to_zero; - res =3D float64_round_to_int(a, status); - status->float_rounding_mode =3D oldmode; - return res; -} - =20 /*------------------------------------------------------------------------= ---- | Returns the remainder of the double-precision floating-point value `a' diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 102cf4b1e1..483803ff35 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -346,6 +346,7 @@ float64 float16_to_float64(float16 a, flag ieee, float_= status *status); | Software half-precision operations. *-------------------------------------------------------------------------= ---*/ =20 +float16 float16_round_to_int(float16, float_status *status); float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); float16 float16_mul(float16, float16, float_status *status); --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997625990331.8978395292396; Mon, 11 Dec 2017 05:07:05 -0800 (PST) Received: from localhost ([::1]:52665 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONnM-0005Af-6h for importer@patchew.org; Mon, 11 Dec 2017 08:06:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51717) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONeE-0002ZZ-0u for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONeA-0007qB-2K for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:30 -0500 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:41477) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONe9-0007pR-LD for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:25 -0500 Received: by mail-wm0-x243.google.com with SMTP id g75so14340549wme.0 for ; Mon, 11 Dec 2017 04:57:25 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 90sm15409239wrp.93.2017.12.11.04.57.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:18 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 815133E0C5D; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=DnduGGMDDtkT6xEtdJHrrkG0FqNJROwpla/lkXr0lpI=; b=gAE+6ur72NRu9BPu8QGT4VvnZ3bq2y21y/GhERsgsYolwnc+lPpgENX5OsuF6TlyjG BqtB4UavTupMaYyqWeu1hGce+K5iB+wTUPq0aKgm7ws2bFn19Y+ZzmBAIaHCQS1Bn/cN VWY1pPHQ8e9cFX2J6WCFwYdJwxwWPr2bRP8sw= 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=DnduGGMDDtkT6xEtdJHrrkG0FqNJROwpla/lkXr0lpI=; b=Te5lkjaOdsD9gt97uR93qrPCjAcn/2WiCXjcUJCSxU7y8XXCGgT2dLKbJXlWDpzLHI jFThAK9cp1RMaPvJK7NCFcgx2VztQ+pwmVMB5U3fR6yz2YuP2UE6SF9nwMjs6izYjGH0 3XG+EkLw2Aatz/km1uGvI2JKObSdrgh/97ZzQGs3vD7SvUaWADqW/uMrlaws7PkPJ4yW MEHLuSesFj7MW6SijrFDfxvjslRn1hdtf0kz/x5+9zB8lrm1gX/dY2l44jT+v+fYmx6A guL2lyOWsG1O6oKJpA1ud4GikG5Ny6qdpJbCCXR73V8Mgfdmy2tTNqmSwwCA2VTxwzVI XesQ== X-Gm-Message-State: AKGB3mJK2JEHARxbdx9K11rkvJcLNf+2mzoY1g4mbNStHdrEyxtDduAo OvZXC8ErFyUgDn1vPspHKwKseg== X-Google-Smtp-Source: ACJfBovspo+zUJh3XneS+neVoGugf1OgyRQf8pnhatWCRAfFeSDquPdvudYxVNBaa6I7grk/SYp09Q== X-Received: by 10.28.12.14 with SMTP id 14mr710564wmm.49.1512997043767; Mon, 11 Dec 2017 04:57:23 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:57:01 +0000 Message-Id: <20171211125705.16120-16-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::243 Subject: [Qemu-devel] [PATCH v1 15/19] fpu/softfloat: re-factor float to int/uint 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We share the common int64/uint64_pack_decomposed function across all the helpers and simply limit the final result depending on the final size. Signed-off-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 1000 ++++++++++---------------------------------= ---- include/fpu/softfloat.h | 13 + 2 files changed, 224 insertions(+), 789 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 9914ecb783..d7858bdae5 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1312,6 +1312,183 @@ float64 float64_trunc_to_int(float64 a, float_statu= s *s) return float64_round_pack_canonical(pr, s); } =20 +/*------------------------------------------------------------------------= ---- +| Returns the result of converting the floating-point value +| `a' to the two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. Otherwise, if the conversion overflows, t= he +| largest integer with the same sign as `a' is returned. +*-------------------------------------------------------------------------= ---*/ + +static int64_t int64_pack_decomposed(decomposed_parts p, float_status *s) +{ + uint64_t r; + + switch (p.cls) { + case float_class_snan: + case float_class_qnan: + return INT64_MAX; + case float_class_inf: + return p.sign ? INT64_MIN : INT64_MAX; + case float_class_zero: + return 0; + case float_class_normal: + if (p.exp < DECOMPOSED_BINARY_POINT) { + r =3D p.frac >> (DECOMPOSED_BINARY_POINT - p.exp); + } else if (p.exp < 64) { + r =3D p.frac << (p.exp - DECOMPOSED_BINARY_POINT); + } else { + s->float_exception_flags |=3D float_flag_invalid; + r =3D UINT64_MAX; + } + if (p.sign) { + return r < - (uint64_t) INT64_MIN ? -r : INT64_MIN; + } else { + return r < INT64_MAX ? r : INT64_MAX; + } + default: + g_assert_not_reached(); + } +} + +static int16_t int16_pack_decomposed(decomposed_parts p, float_status *s) +{ + int64_t r =3D int64_pack_decomposed(p, s); + if (r < INT16_MIN) { + s->float_exception_flags |=3D float_flag_invalid; + return INT16_MIN; + } else if (r > INT16_MAX) { + s->float_exception_flags |=3D float_flag_invalid; + return INT16_MAX; + } + return r; +} + +static int32_t int32_pack_decomposed(decomposed_parts p, float_status *s) +{ + int64_t r =3D int64_pack_decomposed(p, s); + if (r < INT32_MIN) { + s->float_exception_flags |=3D float_flag_invalid; + return INT32_MIN; + } else if (r > INT32_MAX) { + s->float_exception_flags |=3D float_flag_invalid; + return INT32_MAX; + } + return r; +} + +#define FLOAT_TO_INT(fsz, isz) \ +int ## isz ## _t float ## fsz ## _to_int ## isz(float ## fsz a, float_stat= us *s) \ +{ \ + decomposed_parts pa =3D float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr =3D round_decomposed(pa, s->float_rounding_mode, s= ); \ + return int ## isz ## _pack_decomposed(pr, s); \ +} \ + \ +int ## isz ## _t float ## fsz ## _to_int ## isz ## _round_to_zero \ + (float ## fsz a, float_status *s) \ +{ \ + decomposed_parts pa =3D float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr =3D round_decomposed(pa, float_round_to_zero, s); \ + return int ## isz ## _pack_decomposed(pr, s); \ +} + +FLOAT_TO_INT(16, 16) +FLOAT_TO_INT(16, 32) +FLOAT_TO_INT(16, 64) + +FLOAT_TO_INT(32, 16) +FLOAT_TO_INT(32, 32) +FLOAT_TO_INT(32, 64) + +FLOAT_TO_INT(64, 16) +FLOAT_TO_INT(64, 32) +FLOAT_TO_INT(64, 64) + +#undef FLOAT_TO_INT + +/*------------------------------------------------------------------------= ---- +| Returns the result of converting the floating-point value +| `a' to the unsigned integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| unsigned integer is returned. Otherwise, if the conversion overflows, t= he +| largest unsigned integer is returned. If the 'a' is negative, the result +| is rounded and zero is returned; values that do not round to zero will +| raise the inexact exception flag. +*-------------------------------------------------------------------------= ---*/ + +static uint64_t uint64_pack_decomposed(decomposed_parts p, float_status *s) +{ + switch (p.cls) { + case float_class_snan: + case float_class_qnan: + return UINT64_MAX; + case float_class_inf: + return p.sign ? 0 : UINT64_MAX; + case float_class_zero: + return 0; + case float_class_normal: + if (p.sign) { + return 0; + } + if (p.exp < DECOMPOSED_BINARY_POINT) { + return p.frac >> (DECOMPOSED_BINARY_POINT - p.exp); + } else if (p.exp < 64) { + return p.frac << (p.exp - DECOMPOSED_BINARY_POINT); + } else { + return UINT64_MAX; + } + default: + g_assert_not_reached(); + } +} + +static uint16_t uint16_pack_decomposed(decomposed_parts p, float_status *s) +{ + uint64_t r =3D uint64_pack_decomposed(p, s); + return r > UINT16_MAX ? UINT16_MAX : r; +} + +static uint32_t uint32_pack_decomposed(decomposed_parts p, float_status *s) +{ + uint64_t r =3D uint64_pack_decomposed(p, s); + return r > UINT32_MAX ? UINT32_MAX : r; +} + +#define FLOAT_TO_UINT(fsz, isz) \ +uint ## isz ## _t float ## fsz ## _to_uint ## isz(float ## fsz a, float_st= atus *s) \ +{ \ + decomposed_parts pa =3D float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr =3D round_decomposed(pa, s->float_rounding_mode, s= ); \ + return uint ## isz ## _pack_decomposed(pr, s); \ +} \ + \ +uint ## isz ## _t float ## fsz ## _to_uint ## isz ## _round_to_zero \ + (float ## fsz a, float_status *s) \ +{ \ + decomposed_parts pa =3D float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr =3D round_decomposed(pa, float_round_to_zero, s); \ + return uint ## isz ## _pack_decomposed(pr, s); \ +} + +FLOAT_TO_UINT(16, 16) +FLOAT_TO_UINT(16, 32) +FLOAT_TO_UINT(16, 64) + +FLOAT_TO_UINT(32, 16) +FLOAT_TO_UINT(32, 32) +FLOAT_TO_UINT(32, 64) + +FLOAT_TO_UINT(64, 16) +FLOAT_TO_UINT(64, 32) +FLOAT_TO_UINT(64, 64) + +#undef FLOAT_TO_UINT + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -2663,288 +2840,8 @@ float128 uint64_to_float128(uint64_t a, float_statu= s *status) return normalizeRoundAndPackFloat128(0, 0x406E, a, 0, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, t= he -| largest integer with the same sign as `a' is returned. -*-------------------------------------------------------------------------= ---*/ - -int32_t float32_to_int32(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64; - - a =3D float32_squash_input_denormal(a, status); - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - if ( ( aExp =3D=3D 0xFF ) && aSig ) aSign =3D 0; - if ( aExp ) aSig |=3D 0x00800000; - shiftCount =3D 0xAF - aExp; - aSig64 =3D aSig; - aSig64 <<=3D 32; - if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64= ); - return roundAndPackInt32(aSign, aSig64, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' = is -| returned. -*-------------------------------------------------------------------------= ---*/ - -int32_t float32_to_int32_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - int32_t z; - a =3D float32_squash_input_denormal(a, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - shiftCount =3D aExp - 0x9E; - if ( 0 <=3D shiftCount ) { - if ( float32_val(a) !=3D 0xCF000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp =3D=3D 0xFF ) && aSig ) ) return 0x7F= FFFFFF; - } - return (int32_t) 0x80000000; - } - else if ( aExp <=3D 0x7E ) { - if (aExp | aSig) { - status->float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - aSig =3D ( aSig | 0x00800000 )<<8; - z =3D aSig>>( - shiftCount ); - if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { - status->float_exception_flags |=3D float_flag_inexact; - } - if ( aSign ) z =3D - z; - return z; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 16-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' = is -| returned. -*-------------------------------------------------------------------------= ---*/ - -int16_t float32_to_int16_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - int32_t z; - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - shiftCount =3D aExp - 0x8E; - if ( 0 <=3D shiftCount ) { - if ( float32_val(a) !=3D 0xC7000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp =3D=3D 0xFF ) && aSig ) ) { - return 0x7FFF; - } - } - return (int32_t) 0xffff8000; - } - else if ( aExp <=3D 0x7E ) { - if ( aExp | aSig ) { - status->float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - shiftCount -=3D 0x10; - aSig =3D ( aSig | 0x00800000 )<<8; - z =3D aSig>>( - shiftCount ); - if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { - status->float_exception_flags |=3D float_flag_inexact; - } - if ( aSign ) { - z =3D - z; - } - return z; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, t= he -| largest integer with the same sign as `a' is returned. -*-------------------------------------------------------------------------= ---*/ - -int64_t float32_to_int64(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64, aSigExtra; - a =3D float32_squash_input_denormal(a, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - shiftCount =3D 0xBE - aExp; - if ( shiftCount < 0 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp =3D=3D 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - if ( aExp ) aSig |=3D 0x00800000; - aSig64 =3D aSig; - aSig64 <<=3D 40; - shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); - return roundAndPackInt64(aSign, aSig64, aSigExtra, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| unsigned integer is returned. Otherwise, if the conversion overflows, t= he -| largest unsigned integer is returned. If the 'a' is negative, the result -| is rounded and zero is returned; values that do not round to zero will -| raise the inexact exception flag. -*-------------------------------------------------------------------------= ---*/ - -uint64_t float32_to_uint64(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64, aSigExtra; - a =3D float32_squash_input_denormal(a, status); - - aSig =3D extractFloat32Frac(a); - aExp =3D extractFloat32Exp(a); - aSign =3D extractFloat32Sign(a); - if ((aSign) && (aExp > 126)) { - float_raise(float_flag_invalid, status); - if (float32_is_any_nan(a)) { - return LIT64(0xFFFFFFFFFFFFFFFF); - } else { - return 0; - } - } - shiftCount =3D 0xBE - aExp; - if (aExp) { - aSig |=3D 0x00800000; - } - if (shiftCount < 0) { - float_raise(float_flag_invalid, status); - return LIT64(0xFFFFFFFFFFFFFFFF); - } - - aSig64 =3D aSig; - aSig64 <<=3D 40; - shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra); - return roundAndPackUint64(aSign, aSig64, aSigExtra, status); -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest unsigned integer is returned. Otherwise, if t= he -| conversion overflows, the largest unsigned integer is returned. If the -| 'a' is negative, the result is rounded and zero is returned; values that= do -| not round to zero will raise the inexact flag. -*-------------------------------------------------------------------------= ---*/ =20 -uint64_t float32_to_uint64_round_to_zero(float32 a, float_status *status) -{ - signed char current_rounding_mode =3D status->float_rounding_mode; - set_float_rounding_mode(float_round_to_zero, status); - int64_t v =3D float32_to_uint64(a, status); - set_float_rounding_mode(current_rounding_mode, status); - return v; -} =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest positive integer is returned. Otherwise, if t= he -| conversion overflows, the largest integer with the same sign as `a' is -| returned. -*-------------------------------------------------------------------------= ---*/ - -int64_t float32_to_int64_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64; - int64_t z; - a =3D float32_squash_input_denormal(a, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - shiftCount =3D aExp - 0xBE; - if ( 0 <=3D shiftCount ) { - if ( float32_val(a) !=3D 0xDF000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp =3D=3D 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - else if ( aExp <=3D 0x7E ) { - if (aExp | aSig) { - status->float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - aSig64 =3D aSig | 0x00800000; - aSig64 <<=3D 40; - z =3D aSig64>>( - shiftCount ); - if ( (uint64_t) ( aSig64<<( shiftCount & 63 ) ) ) { - status->float_exception_flags |=3D float_flag_inexact; - } - if ( aSign ) z =3D - z; - return z; - -} =20 /*------------------------------------------------------------------------= ---- | Returns the result of converting the single-precision floating-point val= ue @@ -3500,289 +3397,59 @@ int float32_le_quiet(float32 a, float32 b, float_s= tatus *status) | Returns 1 if the single-precision floating-point value `a' is less than | the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an | exception. Otherwise, the comparison is performed according to the IEC/= IEEE -| Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -int float32_lt_quiet(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign; - uint32_t av, bv; - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - if ( ( ( extractFloat32Exp( a ) =3D=3D 0xFF ) && extractFloat32Frac= ( a ) ) - || ( ( extractFloat32Exp( b ) =3D=3D 0xFF ) && extractFloat32Frac= ( b ) ) - ) { - if (float32_is_signaling_nan(a, status) - || float32_is_signaling_nan(b, status)) { - float_raise(float_flag_invalid, status); - } - return 0; - } - aSign =3D extractFloat32Sign( a ); - bSign =3D extractFloat32Sign( b ); - av =3D float32_val(a); - bv =3D float32_val(b); - if ( aSign !=3D bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 = ) !=3D 0 ); - return ( av !=3D bv ) && ( aSign ^ ( av < bv ) ); - -} - -/*------------------------------------------------------------------------= ---- -| Returns 1 if the single-precision floating-point values `a' and `b' cann= ot -| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The -| comparison is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -int float32_unordered_quiet(float32 a, float32 b, float_status *status) -{ - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - if ( ( ( extractFloat32Exp( a ) =3D=3D 0xFF ) && extractFloat32Frac= ( a ) ) - || ( ( extractFloat32Exp( b ) =3D=3D 0xFF ) && extractFloat32Frac= ( b ) ) - ) { - if (float32_is_signaling_nan(a, status) - || float32_is_signaling_nan(b, status)) { - float_raise(float_flag_invalid, status); - } - return 1; - } - return 0; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, t= he -| largest integer with the same sign as `a' is returned. -*-------------------------------------------------------------------------= ---*/ - -int32_t float64_to_int32(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig; - a =3D float64_squash_input_denormal(a, status); - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( ( aExp =3D=3D 0x7FF ) && aSig ) aSign =3D 0; - if ( aExp ) aSig |=3D LIT64( 0x0010000000000000 ); - shiftCount =3D 0x42C - aExp; - if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32(aSign, aSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' = is -| returned. -*-------------------------------------------------------------------------= ---*/ - -int32_t float64_to_int32_round_to_zero(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, savedASig; - int32_t z; - a =3D float64_squash_input_denormal(a, status); - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( 0x41E < aExp ) { - if ( ( aExp =3D=3D 0x7FF ) && aSig ) aSign =3D 0; - goto invalid; - } - else if ( aExp < 0x3FF ) { - if (aExp || aSig) { - status->float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - aSig |=3D LIT64( 0x0010000000000000 ); - shiftCount =3D 0x433 - aExp; - savedASig =3D aSig; - aSig >>=3D shiftCount; - z =3D aSig; - if ( aSign ) z =3D - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise(float_flag_invalid, status); - return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<float_exception_flags |=3D float_flag_inexact; - } - return z; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 16-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' = is -| returned. -*-------------------------------------------------------------------------= ---*/ - -int16_t float64_to_int16_round_to_zero(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, savedASig; - int32_t z; - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( 0x40E < aExp ) { - if ( ( aExp =3D=3D 0x7FF ) && aSig ) { - aSign =3D 0; - } - goto invalid; - } - else if ( aExp < 0x3FF ) { - if ( aExp || aSig ) { - status->float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - aSig |=3D LIT64( 0x0010000000000000 ); - shiftCount =3D 0x433 - aExp; - savedASig =3D aSig; - aSig >>=3D shiftCount; - z =3D aSig; - if ( aSign ) { - z =3D - z; - } - if ( ( (int16_t)z < 0 ) ^ aSign ) { - invalid: - float_raise(float_flag_invalid, status); - return aSign ? (int32_t) 0xffff8000 : 0x7FFF; - } - if ( ( aSig<float_exception_flags |=3D float_flag_inexact; - } - return z; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, t= he -| largest integer with the same sign as `a' is returned. +| Standard for Binary Floating-Point Arithmetic. *-------------------------------------------------------------------------= ---*/ =20 -int64_t float64_to_int64(float64 a, float_status *status) +int float32_lt_quiet(float32 a, float32 b, float_status *status) { - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, aSigExtra; - a =3D float64_squash_input_denormal(a, status); + flag aSign, bSign; + uint32_t av, bv; + a =3D float32_squash_input_denormal(a, status); + b =3D float32_squash_input_denormal(b, status); =20 - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( aExp ) aSig |=3D LIT64( 0x0010000000000000 ); - shiftCount =3D 0x433 - aExp; - if ( shiftCount <=3D 0 ) { - if ( 0x43E < aExp ) { + if ( ( ( extractFloat32Exp( a ) =3D=3D 0xFF ) && extractFloat32Frac= ( a ) ) + || ( ( extractFloat32Exp( b ) =3D=3D 0xFF ) && extractFloat32Frac= ( b ) ) + ) { + if (float32_is_signaling_nan(a, status) + || float32_is_signaling_nan(b, status)) { float_raise(float_flag_invalid, status); - if ( ! aSign - || ( ( aExp =3D=3D 0x7FF ) - && ( aSig !=3D LIT64( 0x0010000000000000 ) ) ) - ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (int64_t) LIT64( 0x8000000000000000 ); } - aSigExtra =3D 0; - aSig <<=3D - shiftCount; - } - else { - shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra ); + return 0; } - return roundAndPackInt64(aSign, aSig, aSigExtra, status); + aSign =3D extractFloat32Sign( a ); + bSign =3D extractFloat32Sign( b ); + av =3D float32_val(a); + bv =3D float32_val(b); + if ( aSign !=3D bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 = ) !=3D 0 ); + return ( av !=3D bv ) && ( aSign ^ ( av < bv ) ); =20 } =20 /*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' = is -| returned. +| Returns 1 if the single-precision floating-point values `a' and `b' cann= ot +| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The +| comparison is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. *-------------------------------------------------------------------------= ---*/ =20 -int64_t float64_to_int64_round_to_zero(float64 a, float_status *status) +int float32_unordered_quiet(float32 a, float32 b, float_status *status) { - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig; - int64_t z; - a =3D float64_squash_input_denormal(a, status); + a =3D float32_squash_input_denormal(a, status); + b =3D float32_squash_input_denormal(b, status); =20 - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( aExp ) aSig |=3D LIT64( 0x0010000000000000 ); - shiftCount =3D aExp - 0x433; - if ( 0 <=3D shiftCount ) { - if ( 0x43E <=3D aExp ) { - if ( float64_val(a) !=3D LIT64( 0xC3E0000000000000 ) ) { - float_raise(float_flag_invalid, status); - if ( ! aSign - || ( ( aExp =3D=3D 0x7FF ) - && ( aSig !=3D LIT64( 0x0010000000000000 ) ) ) - ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - z =3D aSig<float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - z =3D aSig>>( - shiftCount ); - if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) { - status->float_exception_flags |=3D float_flag_inexact; + if ( ( ( extractFloat32Exp( a ) =3D=3D 0xFF ) && extractFloat32Frac= ( a ) ) + || ( ( extractFloat32Exp( b ) =3D=3D 0xFF ) && extractFloat32Frac= ( b ) ) + ) { + if (float32_is_signaling_nan(a, status) + || float32_is_signaling_nan(b, status)) { + float_raise(float_flag_invalid, status); } + return 1; } - if ( aSign ) z =3D - z; - return z; - + return 0; } =20 + /*------------------------------------------------------------------------= ---- | Returns the result of converting the double-precision floating-point val= ue | `a' to the single-precision floating-point format. The conversion is @@ -7049,252 +6716,7 @@ float64 uint32_to_float64(uint32_t a, float_status = *status) return int64_to_float64(a, status); } =20 -uint32_t float32_to_uint32(float32 a, float_status *status) -{ - int64_t v; - uint32_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float32_to_int64(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffffffff) { - res =3D 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint32_t float32_to_uint32_round_to_zero(float32 a, float_status *status) -{ - int64_t v; - uint32_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float32_to_int64_round_to_zero(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffffffff) { - res =3D 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -int16_t float32_to_int16(float32 a, float_status *status) -{ - int32_t v; - int16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float32_to_int32(a, status); - if (v < -0x8000) { - res =3D -0x8000; - } else if (v > 0x7fff) { - res =3D 0x7fff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float32_to_uint16(float32 a, float_status *status) -{ - int32_t v; - uint16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float32_to_int32(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffff) { - res =3D 0xffff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float32_to_uint16_round_to_zero(float32 a, float_status *status) -{ - int64_t v; - uint16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float32_to_int64_round_to_zero(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffff) { - res =3D 0xffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint32_t float64_to_uint32(float64 a, float_status *status) -{ - uint64_t v; - uint32_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float64_to_uint64(a, status); - if (v > 0xffffffff) { - res =3D 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint32_t float64_to_uint32_round_to_zero(float64 a, float_status *status) -{ - uint64_t v; - uint32_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float64_to_uint64_round_to_zero(a, status); - if (v > 0xffffffff) { - res =3D 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -int16_t float64_to_int16(float64 a, float_status *status) -{ - int64_t v; - int16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float64_to_int32(a, status); - if (v < -0x8000) { - res =3D -0x8000; - } else if (v > 0x7fff) { - res =3D 0x7fff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float64_to_uint16(float64 a, float_status *status) -{ - int64_t v; - uint16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float64_to_int32(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffff) { - res =3D 0xffff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float64_to_uint16_round_to_zero(float64 a, float_status *status) -{ - int64_t v; - uint16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float64_to_int64_round_to_zero(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffff) { - res =3D 0xffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. If the conversion overflows, the -| largest unsigned integer is returned. If 'a' is negative, the value is -| rounded and zero is returned; negative values that do not round to zero -| will raise the inexact exception. -*-------------------------------------------------------------------------= ---*/ - -uint64_t float64_to_uint64(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, aSigExtra; - a =3D float64_squash_input_denormal(a, status); - - aSig =3D extractFloat64Frac(a); - aExp =3D extractFloat64Exp(a); - aSign =3D extractFloat64Sign(a); - if (aSign && (aExp > 1022)) { - float_raise(float_flag_invalid, status); - if (float64_is_any_nan(a)) { - return LIT64(0xFFFFFFFFFFFFFFFF); - } else { - return 0; - } - } - if (aExp) { - aSig |=3D LIT64(0x0010000000000000); - } - shiftCount =3D 0x433 - aExp; - if (shiftCount <=3D 0) { - if (0x43E < aExp) { - float_raise(float_flag_invalid, status); - return LIT64(0xFFFFFFFFFFFFFFFF); - } - aSigExtra =3D 0; - aSig <<=3D -shiftCount; - } else { - shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra); - } - return roundAndPackUint64(aSign, aSig, aSigExtra, status); -} =20 -uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *status) -{ - signed char current_rounding_mode =3D status->float_rounding_mode; - set_float_rounding_mode(float_round_to_zero, status); - uint64_t v =3D float64_to_uint64(a, status); - set_float_rounding_mode(current_rounding_mode, status); - return v; -} =20 #define COMPARE(s, nan_exp) = \ static inline int float ## s ## _compare_internal(float ## s a, float ## s= b,\ diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 483803ff35..860f480af8 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -341,6 +341,19 @@ float16 float32_to_float16(float32, flag, float_status= *status); float32 float16_to_float32(float16, flag, float_status *status); float16 float64_to_float16(float64 a, flag ieee, float_status *status); float64 float16_to_float64(float16 a, flag ieee, float_status *status); +int16_t float16_to_int16(float16, float_status *status); +uint16_t float16_to_uint16(float16 a, float_status *status); +int16_t float16_to_int16_round_to_zero(float16, float_status *status); +uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status); +int32_t float16_to_int32(float16, float_status *status); +uint32_t float16_to_uint32(float16 a, float_status *status); +int32_t float16_to_int32_round_to_zero(float16, float_status *status); +uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status); +int64_t float16_to_int64(float16, float_status *status); +uint64_t float16_to_uint64(float16 a, float_status *status); +int64_t float16_to_int64_round_to_zero(float16, float_status *status); +uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); +float16 int16_to_float16(int16_t a, float_status *status); =20 /*------------------------------------------------------------------------= ---- | Software half-precision operations. --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512998005724175.60656383386652; Mon, 11 Dec 2017 05:13:25 -0800 (PST) Received: from localhost ([::1]:52867 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONtb-0004j7-Q3 for importer@patchew.org; Mon, 11 Dec 2017 08:13:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55031) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONn5-0005KN-Tm for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONn3-0006Aa-Gb for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:39 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:34301) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONn3-00069w-6d for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:37 -0500 Received: by mail-wr0-x243.google.com with SMTP id y21so17531994wrc.1 for ; Mon, 11 Dec 2017 05:06:37 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 2sm16272649wre.17.2017.12.11.05.06.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 05:06:34 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 936D93E0D26; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=iLulQbh+zCpfdAk5sN6+a/SsAaDl1Wqx538JpGE1FBU=; b=HKR3gQvsuvoBTLWDmb0oirZW93NQBvq4N9+ClbUGgUpbj27WFTlMtkTLZUQ4tH7Vs5 vNtDTPtDwHIyhdmmQVPT+NA1Ta3Ll4lifeVkv0cISAghZy470bJ0CA6K1H/7F3UtHEvZ ju1WWUsfqNiCtk5s+7qBSh1jTLDe3CWrEJrfg= 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=iLulQbh+zCpfdAk5sN6+a/SsAaDl1Wqx538JpGE1FBU=; b=t9lcm0XEOMSRGMwHie7YZk1QgqUCF7WsTOWnYQbIanXE3S8kZg4vJ6XylKO/wiLNKB 74BdfaX0C36ufj/jYfg7ghEVjbkIZv1MA4p9UFZjTfeVyu+zkhOIVrMDXX99D+T/IRCn x6ch53z2StoCFyuP65qCK3qC+9dsDYAROGBeK5NxgXMEKaPoh+M1iJib0uT4t2LREND7 lLXQ46zDNmx5zoxuPJK6tebOBazD2K8z8FWAW7d2bek4BT9N13e5C44y5SIT3a3QbOBl nxapaEolQVPUwDaVRs95xkXLI9CetMNLZiJ5jbjmyI1n8bGLx0IDjD0PG4L4BzPqWuET fFRg== X-Gm-Message-State: AKGB3mJ7aTcEuArAWXjzJY9JISKIpewQoIaOXf4e8uAH0CFsufUOwWAw crrLYpRZ8eFj6snVLjxMLBXT+Q== X-Google-Smtp-Source: ACJfBov0t8RqpJFB9DSmKId3/5rJXlQYWYIoN5Z+C5HH/3T+mHYrNFLxa5LmOqZr4goiK1bu8fZO3Q== X-Received: by 10.223.176.113 with SMTP id g46mr333830wra.267.1512997595854; Mon, 11 Dec 2017 05:06:35 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:57:02 +0000 Message-Id: <20171211125705.16120-17-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::243 Subject: [Qemu-devel] [PATCH v1 16/19] fpu/softfloat: re-factor int/uint to float 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 These are considerably simpler as the lower order integers can just use the higher order conversion function. As the decomposed fractional part is a full 64 bit rounding and inexact handling comes from the pack functions. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- fpu/softfloat.c | 358 +++++++++++++++++++++++++-------------------= ---- include/fpu/softfloat.h | 30 ++-- 2 files changed, 195 insertions(+), 193 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index d7858bdae5..1a7f1cab10 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1409,17 +1409,18 @@ FLOAT_TO_INT(64, 64) =20 #undef FLOAT_TO_INT =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the floating-point value -| `a' to the unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| unsigned integer is returned. Otherwise, if the conversion overflows, t= he -| largest unsigned integer is returned. If the 'a' is negative, the result -| is rounded and zero is returned; values that do not round to zero will -| raise the inexact exception flag. -*-------------------------------------------------------------------------= ---*/ +/* + * Returns the result of converting the floating-point value `a' to + * the unsigned integer format. The conversion is performed according + * to the IEC/IEEE Standard for Binary Floating-Point + * Arithmetic---which means in particular that the conversion is + * rounded according to the current rounding mode. If `a' is a NaN, + * the largest unsigned integer is returned. Otherwise, if the + * conversion overflows, the largest unsigned integer is returned. If + * the 'a' is negative, the result is rounded and zero is returned; + * values that do not round to zero will raise the inexact exception + * flag. + */ =20 static uint64_t uint64_pack_decomposed(decomposed_parts p, float_status *s) { @@ -1433,6 +1434,7 @@ static uint64_t uint64_pack_decomposed(decomposed_par= ts p, float_status *s) return 0; case float_class_normal: if (p.sign) { + s->float_exception_flags |=3D float_flag_invalid; return 0; } if (p.exp < DECOMPOSED_BINARY_POINT) { @@ -1440,6 +1442,7 @@ static uint64_t uint64_pack_decomposed(decomposed_par= ts p, float_status *s) } else if (p.exp < 64) { return p.frac << (p.exp - DECOMPOSED_BINARY_POINT); } else { + s->float_exception_flags |=3D float_flag_invalid; return UINT64_MAX; } default: @@ -1450,13 +1453,21 @@ static uint64_t uint64_pack_decomposed(decomposed_p= arts p, float_status *s) static uint16_t uint16_pack_decomposed(decomposed_parts p, float_status *s) { uint64_t r =3D uint64_pack_decomposed(p, s); - return r > UINT16_MAX ? UINT16_MAX : r; + if (r > UINT16_MAX) { + s->float_exception_flags |=3D float_flag_invalid; + r =3D UINT16_MAX; + } + return r; } =20 static uint32_t uint32_pack_decomposed(decomposed_parts p, float_status *s) { uint64_t r =3D uint64_pack_decomposed(p, s); - return r > UINT32_MAX ? UINT32_MAX : r; + if (r > UINT32_MAX) { + s->float_exception_flags |=3D float_flag_invalid; + r =3D UINT32_MAX; + } + return r; } =20 #define FLOAT_TO_UINT(fsz, isz) \ @@ -1489,6 +1500,168 @@ FLOAT_TO_UINT(64, 64) =20 #undef FLOAT_TO_UINT =20 +/* + * Integer to float conversions + * + * Returns the result of converting the two's complement integer `a' + * to the floating-point format. The conversion is performed according + * to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts int_to_float(int64_t a, float_status *status) +{ + decomposed_parts r; + if (a =3D=3D 0) { + r.cls =3D float_class_zero; + } else if (a =3D=3D (1ULL << 63)) { + r.cls =3D float_class_normal; + r.sign =3D true; + r.frac =3D DECOMPOSED_IMPLICIT_BIT; + r.exp =3D 63; + } else { + uint64_t f; + if (a < 0) { + f =3D -a; + r.sign =3D true; + } else { + f =3D a; + r.sign =3D false; + } + int shift =3D clz64(f) - 1; + r.cls =3D float_class_normal; + r.exp =3D (DECOMPOSED_BINARY_POINT - shift); + r.frac =3D f << shift; + } + + return r; +} + +float16 int64_to_float16(int64_t a, float_status *status) +{ + decomposed_parts pa =3D int_to_float(a, status); + return float16_round_pack_canonical(pa, status); +} + +float16 int32_to_float16(int32_t a, float_status *status) +{ + return int64_to_float16((int64_t) a, status); +} + +float16 int16_to_float16(int16_t a, float_status *status) +{ + return int64_to_float16((int64_t) a, status); +} + +float32 int64_to_float32(int64_t a, float_status *status) +{ + decomposed_parts pa =3D int_to_float(a, status); + return float32_round_pack_canonical(pa, status); +} + +float32 int32_to_float32(int32_t a, float_status *status) +{ + return int64_to_float32((int64_t) a, status); +} + +float32 int16_to_float32(int16_t a, float_status *status) +{ + return int64_to_float32((int64_t) a, status); +} + +float64 int64_to_float64(int64_t a, float_status *status) +{ + decomposed_parts pa =3D int_to_float(a, status); + return float64_round_pack_canonical(pa, status); +} + +float64 int32_to_float64(int32_t a, float_status *status) +{ + return int64_to_float64((int64_t) a, status); +} + +float64 int16_to_float64(int16_t a, float_status *status) +{ + return int64_to_float64((int64_t) a, status); +} + + +/* + * Unsigned Integer to float conversions + * + * Returns the result of converting the unsigned integer `a' to the + * floating-point format. The conversion is performed according to the + * IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts uint_to_float(uint64_t a, float_status *status) +{ + decomposed_parts r; + if (a =3D=3D 0) { + r.cls =3D float_class_zero; + } else { + int spare_bits =3D clz64(a) - 1; + r.sign =3D false; + r.cls =3D float_class_normal; + r.exp =3D DECOMPOSED_BINARY_POINT - spare_bits; + if (spare_bits < 0) { + shift64RightJamming(a, -spare_bits, &a); + r.frac =3D a; + } else { + r.frac =3D a << spare_bits; + } + } + + return r; +} + +float16 uint64_to_float16(uint64_t a, float_status *status) +{ + decomposed_parts pa =3D uint_to_float(a, status); + return float16_round_pack_canonical(pa, status); +} + +float16 uint32_to_float16(uint32_t a, float_status *status) +{ + return uint64_to_float16((uint64_t) a, status); +} + +float16 uint16_to_float16(uint16_t a, float_status *status) +{ + return uint64_to_float16((uint64_t) a, status); +} + +float32 uint64_to_float32(uint64_t a, float_status *status) +{ + decomposed_parts pa =3D uint_to_float(a, status); + return float32_round_pack_canonical(pa, status); +} + +float32 uint32_to_float32(uint32_t a, float_status *status) +{ + return uint64_to_float32((uint64_t) a, status); +} + +float32 uint16_to_float32(uint16_t a, float_status *status) +{ + return uint64_to_float32((uint64_t) a, status); +} + +float64 uint64_to_float64(uint64_t a, float_status *status) +{ + decomposed_parts pa =3D uint_to_float(a, status); + return float64_round_pack_canonical(pa, status); +} + +float64 uint32_to_float64(uint32_t a, float_status *status) +{ + return uint64_to_float64((uint64_t) a, status); +} + +float64 uint16_to_float64(uint16_t a, float_status *status) +{ + return uint64_to_float64((uint64_t) a, status); +} + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -2580,43 +2753,6 @@ static float128 normalizeRoundAndPackFloat128(flag z= Sign, int32_t zExp, =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the single-precision floating-point format. The conversion is perfor= med -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 int32_to_float32(int32_t a, float_status *status) -{ - flag zSign; - - if ( a =3D=3D 0 ) return float32_zero; - if ( a =3D=3D (int32_t) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); - zSign =3D ( a < 0 ); - return normalizeRoundAndPackFloat32(zSign, 0x9C, zSign ? -a : a, statu= s); -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the double-precision floating-point format. The conversion is perfor= med -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 int32_to_float64(int32_t a, float_status *status) -{ - flag zSign; - uint32_t absA; - int8_t shiftCount; - uint64_t zSig; - - if ( a =3D=3D 0 ) return float64_zero; - zSign =3D ( a < 0 ); - absA =3D zSign ? - a : a; - shiftCount =3D countLeadingZeros32( absA ) + 21; - zSig =3D absA; - return packFloat64( zSign, 0x432 - shiftCount, zSig<=3D 0) { - return packFloat32(0, 0x95 - shiftcount, a << shiftcount); - } - /* Otherwise we need to do a round-and-pack. roundAndPackFloat32() - * expects the binary point between bits 30 and 29, hence the + 7. - */ - shiftcount +=3D 7; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<=3D shiftcount; - } - - return roundAndPackFloat32(0, 0x9c - shiftcount, a, status); -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the 64-bit unsigned integer `a' -| to the double-precision floating-point format. The conversion is perfor= med -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 uint64_to_float64(uint64_t a, float_status *status) -{ - int exp =3D 0x43C; - int shiftcount; - - if (a =3D=3D 0) { - return float64_zero; - } - - shiftcount =3D countLeadingZeros64(a) - 1; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<=3D shiftcount; - } - return roundAndPackFloat64(0, exp - shiftcount, a, status); -} - /*------------------------------------------------------------------------= ---- | Returns the result of converting the 64-bit unsigned integer `a' | to the quadruple-precision floating-point format. The conversion is per= formed @@ -6705,19 +6732,6 @@ int float128_unordered_quiet(float128 a, float128 b,= float_status *status) return 0; } =20 -/* misc functions */ -float32 uint32_to_float32(uint32_t a, float_status *status) -{ - return int64_to_float32(a, status); -} - -float64 uint32_to_float64(uint32_t a, float_status *status) -{ - return int64_to_float64(a, status); -} - - - #define COMPARE(s, nan_exp) = \ static inline int float ## s ## _compare_internal(float ## s a, float ## s= b,\ int is_quiet, float_status *status) = \ diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 860f480af8..8ebde83251 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -299,9 +299,13 @@ enum { /*------------------------------------------------------------------------= ---- | Software IEC/IEEE integer-to-floating-point conversion routines. *-------------------------------------------------------------------------= ---*/ +float32 int16_to_float32(int16_t, float_status *status); float32 int32_to_float32(int32_t, float_status *status); +float64 int16_to_float64(int16_t, float_status *status); float64 int32_to_float64(int32_t, float_status *status); +float32 uint16_to_float32(uint16_t, float_status *status); float32 uint32_to_float32(uint32_t, float_status *status); +float64 uint16_to_float64(uint16_t, float_status *status); float64 uint32_to_float64(uint32_t, float_status *status); floatx80 int32_to_floatx80(int32_t, float_status *status); float128 int32_to_float128(int32_t, float_status *status); @@ -313,27 +317,6 @@ float32 uint64_to_float32(uint64_t, float_status *stat= us); float64 uint64_to_float64(uint64_t, float_status *status); float128 uint64_to_float128(uint64_t, float_status *status); =20 -/* We provide the int16 versions for symmetry of API with float-to-int */ -static inline float32 int16_to_float32(int16_t v, float_status *status) -{ - return int32_to_float32(v, status); -} - -static inline float32 uint16_to_float32(uint16_t v, float_status *status) -{ - return uint32_to_float32(v, status); -} - -static inline float64 int16_to_float64(int16_t v, float_status *status) -{ - return int32_to_float64(v, status); -} - -static inline float64 uint16_to_float64(uint16_t v, float_status *status) -{ - return uint32_to_float64(v, status); -} - /*------------------------------------------------------------------------= ---- | Software half-precision conversion routines. *-------------------------------------------------------------------------= ---*/ @@ -354,6 +337,11 @@ uint64_t float16_to_uint64(float16 a, float_status *st= atus); int64_t float16_to_int64_round_to_zero(float16, float_status *status); uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); float16 int16_to_float16(int16_t a, float_status *status); +float16 int32_to_float16(int32_t a, float_status *status); +float16 int64_to_float16(int64_t a, float_status *status); +float16 uint16_to_float16(uint16_t a, float_status *status); +float16 uint32_to_float16(uint32_t a, float_status *status); +float16 uint64_to_float16(uint64_t a, float_status *status); =20 /*------------------------------------------------------------------------= ---- | Software half-precision operations. --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997684433804.6814854875854; Mon, 11 Dec 2017 05:08:04 -0800 (PST) Received: from localhost ([::1]:52668 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONoQ-0006Bn-PX for importer@patchew.org; Mon, 11 Dec 2017 08:08:02 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51644) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONe8-0002So-3i for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONe7-0007nb-1y for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:24 -0500 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:46918) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONe6-0007mV-Oj for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:22 -0500 Received: by mail-wm0-x243.google.com with SMTP id r78so14298667wme.5 for ; Mon, 11 Dec 2017 04:57:22 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id s195sm9557491wmb.33.2017.12.11.04.57.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:18 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id A59283E0F56; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=lZsn0E0fKsWEEcIFtvDvOYzz27C6Ibj9Yt+0VPbKhro=; b=J9EhZU0Ew7zU3S1t5G8kTBJx/NUWJX1S6MIBNq2yYDnUeHSkMJWww8TytlA01sqgoZ qdi7zeoju2VrWeZslYfbt6/Bg9Ammc7D8+Z3zCoTPfuQHW0dxgVJ8lhQ/yY25XlNEnpD 0AMKtNWmbSSBuaPpUpsxS6fED4FcFznuFhHzw= 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=lZsn0E0fKsWEEcIFtvDvOYzz27C6Ibj9Yt+0VPbKhro=; b=DbcvzNb+3kKhN2ae+Pe2iKpIlYvkIQgWB/TEDEJGtQI7J2mpRg6mk/YcE2/U+4l10Z kIpzN+390hP6hiLw6Fzfi++ETafR4WjsfukQ/qpEl6CkWl/P7qtPrCI7q/D83I0v3D5M gOdu1cX+6+NjzXhVyFIae9/B7mXRNO5OwyZz97sa0WjzidyO7ELKJ80com5o6sW5ffP5 0FwTO7MKPYGZaKlmOeJEIUXMPBxwLOJpTt2Ppg4xf5FMGz0+9910y9etiQnJ3bclL1H/ 0wuJ2F/1IOEmGCrl7voSXxhGoZtDY9mC+X3MzLGztHRVTqVaZ8P5EyMLnBvqCKfcz7Zu BtSw== X-Gm-Message-State: AKGB3mIEUWWS5KYApUA6GB/HIEs8yuEqJhvPGt6fO8f4nXKxKT6rWqCS QNcPgRa9SZjSLDiZXPnXmEHdomGOHrk= X-Google-Smtp-Source: ACJfBottokfBepRTCk5cP08xYW69+H6lMHjscFmBZRl/5Nz91Yq2h5hYqs4+taKJRlH3B0+ETxugLA== X-Received: by 10.28.130.15 with SMTP id e15mr833504wmd.52.1512997041548; Mon, 11 Dec 2017 04:57:21 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:57:03 +0000 Message-Id: <20171211125705.16120-18-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::243 Subject: [Qemu-devel] [PATCH v1 17/19] fpu/softfloat: re-factor scalbn 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 This is one of the simpler manipulations you could make to a floating point number. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- fpu/softfloat.c | 104 +++++++++++++++-----------------------------= ---- include/fpu/softfloat.h | 1 + 2 files changed, 32 insertions(+), 73 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 1a7f1cab10..b7ea56dfa5 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1662,6 +1662,37 @@ float64 uint16_to_float64(uint16_t a, float_status *= status) return uint64_to_float64((uint64_t) a, status); } =20 +/* Multiply A by 2 raised to the power N. */ +static decomposed_parts scalbn_decomposed(decomposed_parts a, int n, + float_status *s) +{ + if (a.cls =3D=3D float_class_normal) { + a.exp +=3D n; + } + return a; +} + +float16 float16_scalbn(float16 a, int n, float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pr =3D scalbn_decomposed(pa, n, status); + return float16_round_pack_canonical(pr, status); +} + +float32 float32_scalbn(float32 a, int n, float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pr =3D scalbn_decomposed(pa, n, status); + return float32_round_pack_canonical(pr, status); +} + +float64 float64_scalbn(float64 a, int n, float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pr =3D scalbn_decomposed(pa, n, status); + return float64_round_pack_canonical(pr, status); +} + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -6991,79 +7022,6 @@ MINMAX(32) MINMAX(64) =20 =20 -/* Multiply A by 2 raised to the power N. */ -float32 float32_scalbn(float32 a, int n, float_status *status) -{ - flag aSign; - int16_t aExp; - uint32_t aSig; - - a =3D float32_squash_input_denormal(a, status); - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - - if ( aExp =3D=3D 0xFF ) { - if ( aSig ) { - return propagateFloat32NaN(a, a, status); - } - return a; - } - if (aExp !=3D 0) { - aSig |=3D 0x00800000; - } else if (aSig =3D=3D 0) { - return a; - } else { - aExp++; - } - - if (n > 0x200) { - n =3D 0x200; - } else if (n < -0x200) { - n =3D -0x200; - } - - aExp +=3D n - 1; - aSig <<=3D 7; - return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status); -} - -float64 float64_scalbn(float64 a, int n, float_status *status) -{ - flag aSign; - int16_t aExp; - uint64_t aSig; - - a =3D float64_squash_input_denormal(a, status); - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - - if ( aExp =3D=3D 0x7FF ) { - if ( aSig ) { - return propagateFloat64NaN(a, a, status); - } - return a; - } - if (aExp !=3D 0) { - aSig |=3D LIT64( 0x0010000000000000 ); - } else if (aSig =3D=3D 0) { - return a; - } else { - aExp++; - } - - if (n > 0x1000) { - n =3D 0x1000; - } else if (n < -0x1000) { - n =3D -0x1000; - } - - aExp +=3D n - 1; - aSig <<=3D 10; - return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status); -} - floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) { flag aSign; diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 8ebde83251..c1224aab8c 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -353,6 +353,7 @@ float16 float16_sub(float16, float16, float_status *sta= tus); float16 float16_mul(float16, float16, float_status *status); float16 float16_muladd(float16, float16, float16, int, float_status *statu= s); float16 float16_div(float16, float16, float_status *status); +float16 float16_scalbn(float16, int, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512997723478383.2968175229785; Mon, 11 Dec 2017 05:08:43 -0800 (PST) Received: from localhost ([::1]:52700 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONp0-0007xw-La for importer@patchew.org; Mon, 11 Dec 2017 08:08:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55033) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONn5-0005KQ-UC for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONn4-0006BT-7K for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:39 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:41797) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONn3-0006AI-Th for qemu-devel@nongnu.org; Mon, 11 Dec 2017 08:06:38 -0500 Received: by mail-wr0-x242.google.com with SMTP id z18so17510781wrb.8 for ; Mon, 11 Dec 2017 05:06:37 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id r14sm15447434wra.71.2017.12.11.05.06.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 05:06:34 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id B78AC3E1059; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=+uZGALX/x/xsxWW578zb4ZzlC+JEia9ZYfI/M+V+akI=; b=QA1fknCB8Ue7/AnD+F4fJwAnriXvAeiLVicbGttG6Gl1Cnge2EbnpxkHFdWzyn7OOJ joiypVD6GaleslVjblhHk/aJiO9BZht87RtA3SV9jbl+sFgO5reuep6Ast/cS5wJe5df 3Op1qUCOY0BIFqlAKepeGoPMcGo4v+Sc84ato= 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=+uZGALX/x/xsxWW578zb4ZzlC+JEia9ZYfI/M+V+akI=; b=nny4uU8Rz+qP/k2RtB6pAh0izP4k3OvKUGWXGSGQD6qEDvxlyyupHjM7tk0RFUe4CR 7r4lS2l7iRUIXYC+c15zufpy0WoBK1D072eclDgOAaUsIh8Wz0Vohp/L85+79BSFA5q6 2YtEZejINwM+ZNUEYJARD12Sqt9AmG3n/spchgCZCdcgFfdRw+9vJSQHxeZwkQZOmbHU q6lHaH0/NIpaVnQFHngmnDDtcFDrbvQ+HgweunhB3gNPCsIVue2LnMPyuFDrV+blut6f 2PshTLeF/L7LlDmb9kAHrsIEkvqZ4QgCW/IfQQ/+AEt89/v1y5aF4o3O1OULlATFu+Vz wpVg== X-Gm-Message-State: AKGB3mL79WIFTkA5tc0y4KkRgwbk/NaG+cUB/2DfHDQiGEDqXRCgASmy fc7n/fhb6gqzbLkheeTK7Nhikw== X-Google-Smtp-Source: ACJfBotjMnqhruHAX5bxzelHF6kn7CmCantSSS6sa9/StQa28AG3vEOCai9F7WEw7NScQ6rsV9h+Og== X-Received: by 10.223.134.116 with SMTP id 49mr356356wrw.85.1512997596657; Mon, 11 Dec 2017 05:06:36 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:57:04 +0000 Message-Id: <20171211125705.16120-19-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::242 Subject: [Qemu-devel] [PATCH v1 18/19] fpu/softfloat: re-factor minmax 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Let's do the same re-factor treatment for minmax functions. I still use the MACRO trick to expand but now all the checking code is common. Signed-off-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 242 ++++++++++++++++++++++++++------------------= ---- include/fpu/softfloat.h | 6 ++ 2 files changed, 137 insertions(+), 111 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index b7ea56dfa5..5eba996932 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1662,6 +1662,137 @@ float64 uint16_to_float64(uint16_t a, float_status = *status) return uint64_to_float64((uint64_t) a, status); } =20 +/* Float Min/Max */ +/* min() and max() functions. These can't be implemented as + * 'compare and pick one input' because that would mishandle + * NaNs and +0 vs -0. + * + * minnum() and maxnum() functions. These are similar to the min() + * and max() functions but if one of the arguments is a QNaN and + * the other is numerical then the numerical argument is returned. + * SNaNs will get quietened before being returned. + * minnum() and maxnum correspond to the IEEE 754-2008 minNum() + * and maxNum() operations. min() and max() are the typical min/max + * semantics provided by many CPUs which predate that specification. + * + * minnummag() and maxnummag() functions correspond to minNumMag() + * and minNumMag() from the IEEE-754 2008. + */ +static decomposed_parts minmax_decomposed(decomposed_parts a, + decomposed_parts b, + bool ismin, bool ieee, bool isma= g, + float_status *s) +{ + if (a.cls >=3D float_class_qnan + || + b.cls >=3D float_class_qnan) + { + if (ieee) { + /* Takes two floating-point values `a' and `b', one of + * which is a NaN, and returns the appropriate NaN + * result. If either `a' or `b' is a signaling NaN, + * the invalid exception is raised. + */ + if (a.cls =3D=3D float_class_snan || b.cls =3D=3D float_cl= ass_snan) { + s->float_exception_flags |=3D float_flag_invalid; + if (s->default_nan_mode) { + a.cls =3D float_class_msnan; + return a; + } + } else if (a.cls >=3D float_class_qnan + && + b.cls < float_class_qnan) { + return b; + } else if (b.cls >=3D float_class_qnan + && + a.cls < float_class_qnan) { + return a; + } + } + return pick_nan_parts(a, b, s); + } + + /* Handle zero cases */ + if (a.cls =3D=3D float_class_zero || b.cls =3D=3D float_class_zero= ) { + if (a.cls =3D=3D float_class_normal) { + if (a.sign) { + return ismin ? a : b; + } else { + return ismin ? b : a; + } + } else if (b.cls =3D=3D float_class_normal) { + if (b.sign) { + return ismin ? b : a; + } else { + return ismin ? a : b; + } + } + } + + if (ismag) { + /* Magnitude, ignore sign */ + bool a_less; + if (a.exp =3D=3D b.exp) { + a_less =3D a.frac < b.frac; + } else { + a_less =3D a.exp < b.exp; + } + return a_less =3D=3D ismin ? a : b; + } + if (a.sign !=3D b.sign) { + if (ismin) { + return a.sign ? a : b; + } else { + return a.sign ? b : a; + } + } else { + bool a_less; + if (a.exp =3D=3D b.exp) { + a_less =3D a.frac < b.frac; + } else { + a_less =3D a.exp < b.exp; + } + if (ismin) { + return a.sign ^ a_less ? a : b; + } else { + return a.sign ^ a_less ? b : a; + } + } +} + +#define MINMAX(sz, name, ismin, isiee, ismag) \ +float ## sz float ## sz ## _ ## name(float ## sz a, float ## sz b, float_s= tatus *s) \ +{ \ + decomposed_parts pa =3D float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb =3D float ## sz ## _unpack_canonical(b, s); \ + decomposed_parts pr =3D minmax_decomposed(pa, pb, ismin, isiee, ismag,= s); \ + \ + return float ## sz ## _round_pack_canonical(pr, s); \ +} + +MINMAX(16, min, true, false, false) +MINMAX(16, minnum, true, true, false) +MINMAX(16, minnummag, true, true, true) +MINMAX(16, max, false, false, false) +MINMAX(16, maxnum, false, true, false) +MINMAX(16, maxnummag, false, true, true) + +MINMAX(32, min, true, false, false) +MINMAX(32, minnum, true, true, false) +MINMAX(32, minnummag, true, true, true) +MINMAX(32, max, false, false, false) +MINMAX(32, maxnum, false, true, false) +MINMAX(32, maxnummag, false, true, true) + +MINMAX(64, min, true, false, false) +MINMAX(64, minnum, true, true, false) +MINMAX(64, minnummag, true, true, true) +MINMAX(64, max, false, false, false) +MINMAX(64, maxnum, false, true, false) +MINMAX(64, maxnummag, false, true, true) + +#undef MINMAX + /* Multiply A by 2 raised to the power N. */ static decomposed_parts scalbn_decomposed(decomposed_parts a, int n, float_status *s) @@ -6911,117 +7042,6 @@ int float128_compare_quiet(float128 a, float128 b, = float_status *status) return float128_compare_internal(a, b, 1, status); } =20 -/* min() and max() functions. These can't be implemented as - * 'compare and pick one input' because that would mishandle - * NaNs and +0 vs -0. - * - * minnum() and maxnum() functions. These are similar to the min() - * and max() functions but if one of the arguments is a QNaN and - * the other is numerical then the numerical argument is returned. - * SNaNs will get quietened before being returned. - * minnum() and maxnum correspond to the IEEE 754-2008 minNum() - * and maxNum() operations. min() and max() are the typical min/max - * semantics provided by many CPUs which predate that specification. - * - * minnummag() and maxnummag() functions correspond to minNumMag() - * and minNumMag() from the IEEE-754 2008. - */ -#define MINMAX(s) \ -static inline float ## s float ## s ## _minmax(float ## s a, float ## s b,= \ - int ismin, int isieee, \ - int ismag, \ - float_status *status) \ -{ \ - flag aSign, bSign; \ - uint ## s ## _t av, bv, aav, abv; \ - a =3D float ## s ## _squash_input_denormal(a, status); \ - b =3D float ## s ## _squash_input_denormal(b, status); \ - if (float ## s ## _is_any_nan(a) || \ - float ## s ## _is_any_nan(b)) { \ - if (isieee) { \ - if (float ## s ## _is_signaling_nan(a, status) || \ - float ## s ## _is_signaling_nan(b, status)) { \ - return propagateFloat ## s ## NaN(a, b, status); \ - } else if (float ## s ## _is_quiet_nan(a, status) && \ - !float ## s ##_is_any_nan(b)) { \ - return b; \ - } else if (float ## s ## _is_quiet_nan(b, status) && \ - !float ## s ## _is_any_nan(a)) { \ - return a; \ - } \ - } \ - return propagateFloat ## s ## NaN(a, b, status); \ - } \ - aSign =3D extractFloat ## s ## Sign(a); \ - bSign =3D extractFloat ## s ## Sign(b); \ - av =3D float ## s ## _val(a); \ - bv =3D float ## s ## _val(b); \ - if (ismag) { \ - aav =3D float ## s ## _abs(av); \ - abv =3D float ## s ## _abs(bv); \ - if (aav !=3D abv) { \ - if (ismin) { \ - return (aav < abv) ? a : b; \ - } else { \ - return (aav < abv) ? b : a; \ - } \ - } \ - } \ - if (aSign !=3D bSign) { \ - if (ismin) { \ - return aSign ? a : b; \ - } else { \ - return aSign ? b : a; \ - } \ - } else { \ - if (ismin) { \ - return (aSign ^ (av < bv)) ? a : b; \ - } else { \ - return (aSign ^ (av < bv)) ? b : a; \ - } \ - } \ -} \ - \ -float ## s float ## s ## _min(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 1, 0, 0, status); \ -} \ - \ -float ## s float ## s ## _max(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 0, 0, 0, status); \ -} \ - \ -float ## s float ## s ## _minnum(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 1, 1, 0, status); \ -} \ - \ -float ## s float ## s ## _maxnum(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 0, 1, 0, status); \ -} \ - \ -float ## s float ## s ## _minnummag(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 1, 1, 1, status); \ -} \ - \ -float ## s float ## s ## _maxnummag(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 0, 1, 1, status); \ -} - -MINMAX(32) -MINMAX(64) - - floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) { flag aSign; diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index c1224aab8c..ba248ffa39 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -354,6 +354,12 @@ float16 float16_mul(float16, float16, float_status *st= atus); float16 float16_muladd(float16, float16, float16, int, float_status *statu= s); float16 float16_div(float16, float16, float_status *status); float16 float16_scalbn(float16, int, float_status *status); +float16 float16_min(float16, float16, float_status *status); +float16 float16_max(float16, float16, float_status *status); +float16 float16_minnum(float16, float16, float_status *status); +float16 float16_maxnum(float16, float16, float_status *status); +float16 float16_minnummag(float16, float16, float_status *status); +float16 float16_maxnummag(float16, float16, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); --=20 2.15.1 From nobody Thu May 2 17:59:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 15129978769968.30152901588258; Mon, 11 Dec 2017 05:11:16 -0800 (PST) Received: from localhost ([::1]:52732 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONrX-0001ls-Aq for importer@patchew.org; Mon, 11 Dec 2017 08:11:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51667) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONe9-0002UQ-F1 for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eONe8-0007ol-6T for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:25 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:41737) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eONe7-0007o1-Tb for qemu-devel@nongnu.org; Mon, 11 Dec 2017 07:57:24 -0500 Received: by mail-wr0-x244.google.com with SMTP id z18so17479337wrb.8 for ; Mon, 11 Dec 2017 04:57:23 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id l3sm17758139wrg.2.2017.12.11.04.57.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 04:57:18 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id C97233E122C; Mon, 11 Dec 2017 12:57:06 +0000 (GMT) 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=T6rRmFgNcU7BCPuXiNHLXdJhOz6C1zxyD5Wfblt1xto=; b=Uq9Ysd326VlxZqBR0xEfmU6+oxNjN14XgK3iZgokuNRq2zcAoXEL5hvufb3ZDOpSeM SDkTFkrzSlYzCCOk0fBDg6++yi7lAS+w7Gq048GCLsA7tMCtNBIocbM8Urfqi2Edv6Uf p4B4iye4F94h4I1p5ZwsPJd/ZFPvsu0X/qfTc= 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=T6rRmFgNcU7BCPuXiNHLXdJhOz6C1zxyD5Wfblt1xto=; b=uYM9v7kdA/QrQSOT9IBVbuTNGk2aoumTRV/XixJ0MDZYJzvS2WRdvb+usX6Jfc7BLb YU1OvTxNoms+r+QGzp+xeWB+ZAnce1vXeXdPXHMc6l/9o3OiwflPYnNV8yVVZIsu+p3d JeCheyZYvQY0VNJ9ITQo3vmqLpjjzXvg0pUxqaM0VsjJ2RQqnYf1EOcGuTaa2sO2o7M/ P6WOmnFJNrSeRRLLRrVoaIJfejI0i3bwcB0cc6vcNMQLR+75afamNTZWAaUMX+63EgC0 xe2UOC9/SJN0V119dMQIJsNCnLld7LNNcF1bb8OjtfVFor1SoxGKvNYlHEdl3zeViOQN Qlcw== X-Gm-Message-State: AKGB3mI5H/wrZcN1OqjRdgHsgi3At1pslFQKiQLlEKj/iAhdLL1x/+03 EvH0CwlC0a/VXmduA3im36uukw== X-Google-Smtp-Source: ACJfBovhPQ3DXkM3vnLYFs4XPPjCFyAUYaNmL48rduC4WZ62MZZbaQtmBWKEfG3wUNY5Ey87k9vOlw== X-Received: by 10.223.190.135 with SMTP id i7mr311595wrh.91.1512997042713; Mon, 11 Dec 2017 04:57:22 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com, aleksandar.markovic@imgtec.com Date: Mon, 11 Dec 2017 12:57:05 +0000 Message-Id: <20171211125705.16120-20-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171211125705.16120-1-alex.bennee@linaro.org> References: <20171211125705.16120-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v1 19/19] fpu/softfloat: re-factor compare 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=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Signed-off-by: Alex Benn=C3=A9e --- fpu/softfloat.c | 135 +++++++++++++++++++++++++++++---------------= ---- include/fpu/softfloat.h | 2 + 2 files changed, 83 insertions(+), 54 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 5eba996932..31b437e000 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1793,6 +1793,87 @@ MINMAX(64, maxnummag, false, true, true) =20 #undef MINMAX =20 +/* Floating point compare */ +static int compare_decomposed(decomposed_parts a, decomposed_parts b, + bool is_quiet, float_status *s) +{ + if (a.cls >=3D float_class_qnan + || + b.cls >=3D float_class_qnan) { + if (!is_quiet || + a.cls =3D=3D float_class_snan || + b.cls =3D=3D float_class_snan) { + s->float_exception_flags |=3D float_flag_invalid; + } + return float_relation_unordered; + } + + if (a.cls =3D=3D float_class_zero || b.cls =3D=3D float_class_zero) { + if (a.cls =3D=3D float_class_normal) { + return a.sign ? float_relation_less : float_relation_greater; + } else if (b.cls =3D=3D float_class_normal) { + return b.sign ? float_relation_greater : float_relation_less; + } else if (a.cls =3D=3D b.cls) { + return float_relation_equal; + } + } + + /* The only infinity we need to explicitly worry about is + * comparing two together, otherwise the max_exp/sign details are + * enough to compare to normal numbers + */ + if (a.cls =3D=3D float_class_inf && b.cls =3D=3D float_class_inf) { + if (a.sign !=3D b.sign) { + return a.sign ? float_relation_less : float_relation_greater; + } else { + return float_relation_equal; + } + } + + if (a.sign !=3D b.sign) { + return a.sign ? float_relation_less : float_relation_greater; + } + + if (a.exp =3D=3D b.exp) { + if (a.frac =3D=3D b.frac) { + return float_relation_equal; + } + if (a.sign) { + return a.frac > b.frac ? + float_relation_less : float_relation_greater; + } else { + return a.frac > b.frac ? + float_relation_greater : float_relation_less; + } + } else { + if (a.sign) { + return a.exp > b.exp ? float_relation_less : float_relation_gr= eater; + } else { + return a.exp > b.exp ? float_relation_greater : float_relation= _less; + } + } +} + +#define COMPARE(sz) \ +int float ## sz ## _compare(float ## sz a, float ## sz b, float_status *s)= \ +{ \ + decomposed_parts pa =3D float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb =3D float ## sz ## _unpack_canonical(b, s); \ + return compare_decomposed(pa, pb, false, s); \ +} \ +int float ## sz ## _compare_quiet(float ## sz a, float ## sz b, float_stat= us *s) \ +{ \ + decomposed_parts pa =3D float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb =3D float ## sz ## _unpack_canonical(b, s); \ + return compare_decomposed(pa, pb, true, s); \ +} + +COMPARE(16) +COMPARE(32) +COMPARE(64) + +#undef COMPARE + /* Multiply A by 2 raised to the power N. */ static decomposed_parts scalbn_decomposed(decomposed_parts a, int n, float_status *s) @@ -6894,60 +6975,6 @@ int float128_unordered_quiet(float128 a, float128 b,= float_status *status) return 0; } =20 -#define COMPARE(s, nan_exp) = \ -static inline int float ## s ## _compare_internal(float ## s a, float ## s= b,\ - int is_quiet, float_status *status) = \ -{ = \ - flag aSign, bSign; = \ - uint ## s ## _t av, bv; = \ - a =3D float ## s ## _squash_input_denormal(a, status); = \ - b =3D float ## s ## _squash_input_denormal(b, status); = \ - = \ - if (( ( extractFloat ## s ## Exp( a ) =3D=3D nan_exp ) && = \ - extractFloat ## s ## Frac( a ) ) || = \ - ( ( extractFloat ## s ## Exp( b ) =3D=3D nan_exp ) && = \ - extractFloat ## s ## Frac( b ) )) { = \ - if (!is_quiet || = \ - float ## s ## _is_signaling_nan(a, status) || = \ - float ## s ## _is_signaling_nan(b, status)) { \ - float_raise(float_flag_invalid, status); = \ - } = \ - return float_relation_unordered; = \ - } = \ - aSign =3D extractFloat ## s ## Sign( a ); = \ - bSign =3D extractFloat ## s ## Sign( b ); = \ - av =3D float ## s ## _val(a); = \ - bv =3D float ## s ## _val(b); = \ - if ( aSign !=3D bSign ) { = \ - if ( (uint ## s ## _t) ( ( av | bv )<<1 ) =3D=3D 0 ) { = \ - /* zero case */ = \ - return float_relation_equal; = \ - } else { = \ - return 1 - (2 * aSign); = \ - } = \ - } else { = \ - if (av =3D=3D bv) { = \ - return float_relation_equal; = \ - } else { = \ - return 1 - 2 * (aSign ^ ( av < bv )); = \ - } = \ - } = \ -} = \ - = \ -int float ## s ## _compare(float ## s a, float ## s b, float_status *statu= s) \ -{ = \ - return float ## s ## _compare_internal(a, b, 0, status); = \ -} = \ - = \ -int float ## s ## _compare_quiet(float ## s a, float ## s b, = \ - float_status *status) = \ -{ = \ - return float ## s ## _compare_internal(a, b, 1, status); = \ -} - -COMPARE(32, 0xff) -COMPARE(64, 0x7ff) - static inline int floatx80_compare_internal(floatx80 a, floatx80 b, int is_quiet, float_status *st= atus) { diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index ba248ffa39..a5232bcc87 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -360,6 +360,8 @@ float16 float16_minnum(float16, float16, float_status *= status); float16 float16_maxnum(float16, float16, float_status *status); float16 float16_minnummag(float16, float16, float_status *status); float16 float16_maxnummag(float16, float16, float_status *status); +int float16_compare(float16, float16, float_status *status); +int float16_compare_quiet(float16, float16, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); --=20 2.15.1