From patchwork Mon Dec 11 12:56:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121395 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2757476qgn; Mon, 11 Dec 2017 05:00:31 -0800 (PST) X-Google-Smtp-Source: ACJfBouUYOk7ISA90Ja6o0LYGq4EWhQIffFPzTiJJU5bX2bFZmLVUfFiXndFz7zP+TDv2U5rCaf3 X-Received: by 10.37.58.7 with SMTP id h7mr181519yba.284.1512997231135; Mon, 11 Dec 2017 05:00:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997231; cv=none; d=google.com; s=arc-20160816; b=RDhP68SNFuwNvdC6kc1ZoPwZBaBGMvyO2idXgBo4fMx5cYqYmnoaxm6BqE7AfRcwNP SKlCmhVOUPFSkFNVjhx9V8BNPo/Hhq4l6hhBVuifqD4uy7CQoK4KjPQGq8NHfdD7TI7g uLOqcHBHpJBLwyahzQ5ssAQNLATH0yC2IikBWvjQ8O0aW3/LlL16dFjELt16NCUyhRCn fluEPVUOLGevvk2TFWy/k4tfjc7uEQDjfzVLZySxXLLv8uf0S2d0I5da6s/sIj18C9oY OLIqPlXDJfL/ziZk1lzGJRNt/GSyQXZJuIjSo4xwfVV+IRqI7rsVLnI2myBpZmmzaG23 WwGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=kFWWImcJFakK6Q/MS9IUPme+eMbtlWRk0/W9mj8nEvI=; b=VUj61xqNZ9+PuI+CoJOyOUduZUeyqymK/M6+JykfqJ4nW0JpTQqnY7y39kUAHBQgMY 1Vl70JL65jn2GIWhYPyP2UX/PPyu3gKKYwwC9qwfkKuzl1PYSdZc8njPC5+o8uLHbjOv KgcPyNMMRPyps4AAAb4rrz/8MlYUUq3ytux74wA0WFa9hoVSRGmmc6AEsKW4pDFOrakQ fe5rHgIFDLvCKSD5ZRpZJTTPy/rxaRj58SH/pLpSG9xPCk9laIwxln3ykPYNBB70I2pg p9PnoY/XC9GuWUgunAfJM4shMNx+Yjtw8D3WdbZyEtsdjZhyQekNrA6RWYnlmS5w8hGb 0JWw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ea6sGEAV; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id l14si3041738ywi.554.2017.12.11.05.00.31 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:00:31 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ea6sGEAV; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52595 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONh8-0004ju-L7 for patch@linaro.org; Mon, 11 Dec 2017 08:00:30 -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) 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-Received: by 10.223.176.113 with SMTP id g46mr300933wra.267.1512997027866; Mon, 11 Dec 2017 04:57:07 -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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This will be required when expanding the MINMAX() macro for 16 bit/half-precision operations. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- fpu/softfloat.c | 15 +++++++++++++++ include/fpu/softfloat.h | 1 + 2 files changed, 16 insertions(+) -- 2.15.1 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 zExp, return packFloat16(zSign, zExp, zSig >> 13); } +/*---------------------------------------------------------------------------- +| 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 value. +*----------------------------------------------------------------------------*/ +float16 float16_squash_input_denormal(float16 a, float_status *status) +{ + if (status->flush_inputs_to_zero) { + if (extractFloat16Exp(a) == 0 && extractFloat16Frac(a) != 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 value. *----------------------------------------------------------------------------*/ +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); From patchwork Mon Dec 11 12:56:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121391 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2754486qgn; Mon, 11 Dec 2017 04:57:38 -0800 (PST) X-Google-Smtp-Source: ACJfBotnrAFsXGv1/WlHuF3ewCqK+YjaCsxGWZOEy+7fUbdSy4ON/WDEIBTelMS+yJVHDP5nev0E X-Received: by 10.13.210.69 with SMTP id u66mr199569ywd.126.1512997058572; Mon, 11 Dec 2017 04:57:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997058; cv=none; d=google.com; s=arc-20160816; b=jkvhGJRlxmtxuBwFVG/MOpHGell2JQG9/HbC+T2AuGYe56UBzUYBJuYZ29vOh6MbRd 8u4v9/uiVnj/tlRlLYCvbJX4Gm2D01hE9wRpP/RTX11Xw9z+408zCU1yiYvRhgvL+gOq +lV7G61RQObjkm4EaxYm2W8E9qgbVW5uqgf/zSNQSbqOuvMHOu6nxAP+ybU+3YmWTfbU b39Cij3DWH92HOrCQ7h+3ivkhkY7CS5141zK3x3wQA4EZEdCjZu/RR2wC+sfLWl9A1n4 nhkWlmBJ74TWnw/TKnIAgFw/2rOAnAMSK1zSC94x4QGyIGeYe0igMnxW0nwN6hC6DyoW 3X2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=u5wQ9RSdeDG1Nh66eJT3Ak6Ya8mFr9eGwuAxMU+ctEc=; b=oJCWRL1AI5zcyDhLtPpEiGlg6Fea+eSV2jyd0XYDVJKdevmZUQc3uxvHyxQyjisKqz tv97UQqEfVDW1rJTKlt5yyRsURF+a0MbGlgBffTz1KGPTi3XW9NvA0l87xdVQOaN8QcL GF5C0RxF/7/dVXSkPi5Scnv4HMs+k9/eIwISOtlWnfYUHobKdnlwDNFpGtQeAEvaM+o+ KIbEoB3W2pmMTZgUIz7ivD+T2T3A1jNzy0iKOIBzJ+nuJBQEtepO2/q8lpcE59oBnFUn 8faqayvNBSWW7D7hzuTU9EvQJ0ikE/dY1fb/IlEx/Q/EzGRBGYN4LpfcTXDj8N68v1rt NPfQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=D3hLtmfs; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id t65si2927084ywa.52.2017.12.11.04.57.38 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 04:57:38 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=D3hLtmfs; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52582 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONeL-0002KF-Vd for patch@linaro.org; Mon, 11 Dec 2017 07:57:38 -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) 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-Received: by 10.28.54.207 with SMTP id y76mr800617wmh.94.1512997028895; 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 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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This will be required when expanding the MINMAX() macro for 16 bit/half-precision operations. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- include/fpu/softfloat.h | 7 +++++++ 1 file changed, 7 insertions(+) -- 2.15.1 Reviewed-by: Philippe Mathieu-Daudé 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) == 0; } +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. *----------------------------------------------------------------------------*/ From patchwork Mon Dec 11 12:56:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121393 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2756738qgn; Mon, 11 Dec 2017 05:00:01 -0800 (PST) X-Google-Smtp-Source: ACJfBosTSyoqB3bdZllQ7Mj1glziiPU5VhECpWJIuD2E3fdRY7t3iN/+m1X+I1Fu+4kjhOyj7DWM X-Received: by 10.129.50.66 with SMTP id y63mr196138ywy.490.1512997201504; Mon, 11 Dec 2017 05:00:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997201; cv=none; d=google.com; s=arc-20160816; b=sAFqyWamDQaTaxDielmLsIx0zhxndy6vxP04UpPJ3SMskR5CqfrtOConYddzEBXPSs HChw2fXTT3mEX0iaZ36TUmwprOG4QdZ/kQdfujyJhW2tLNseyUCW+BURnul6IaA1rF0v 41OVvvjOPJosV9Bj/qG9WvJ1vk4iUzyzT2o9WTlY9eIY6Pk7DN0IKmQuf3vZfIO6WqY9 8JilgWHDPrCO5N4pthCclueCFUn57y8ntALs7CnKc5bj1fWSEr9Guwj7ahdAvpo2O+xm NrHbqwfD4pHv474Bat7ZVmIpErl2OfJTa3IZpik/U48JRZku4b3LwmEUzElCM9puH0O2 oTbA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=WZvri1dDkG2IakN/Qfkr3MWLAtg0qnWiEiEX++bbsGw=; b=AkBHXihCJiv+YgjVlIRsSXlNgf6kYprzPUkiIA+DI0DXMsyjTVtgcclm29DEahttqL 4ennyYMwksiKR9QB7F9guz0blTkzvMsurRzKqTwkJ+0OL2QNXEZwgB7QiYFz8zGAKXFD nzCuDUCrVWbFUK5p6qR0Qx3f1TjTlvvjExD4EhEHTU3wB8vByuIwRUhwOFKV3HOyF1Oy 2tkgSSzZOCV72NPkHTwSBE5eN9XzwE1JarljSm1WEVBvE2ASJYy67LyCcv5qwdeafgdN xV4UYF6ihCKoEWq6EDLsnfoLNIJ61ktpGNFwfgWC1kXK7ocJZmr5jd78UdH4cz2ceTKL P0cg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=GMegaiGg; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id i4si2856161ywm.559.2017.12.11.05.00.01 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:00:01 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=GMegaiGg; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52587 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONge-0003UO-VJ for patch@linaro.org; Mon, 11 Dec 2017 08:00:01 -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) 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-Received: by 10.223.148.199 with SMTP id 65mr332551wrr.14.1512997030192; Mon, 11 Dec 2017 04:57:10 -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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Alex Bennée --- include/fpu/softfloat.h | 9 +++++++++ 1 file changed, 9 insertions(+) -- 2.15.1 Reviewed-by: Richard Henderson 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. *----------------------------------------------------------------------------*/ From patchwork Mon Dec 11 12:56:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121402 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2762412qgn; Mon, 11 Dec 2017 05:03:38 -0800 (PST) X-Google-Smtp-Source: ACJfBouJx7+1uO7Rw+NdubxnnUlhTfo3sX5RsuLxUl/FcYZU8Hs0JEDsCxrTZe17GAPedF8iQYhw X-Received: by 10.13.207.4 with SMTP id r4mr191801ywd.493.1512997418626; Mon, 11 Dec 2017 05:03:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997418; cv=none; d=google.com; s=arc-20160816; b=ydMSzXkvxhbffqTv+6+N3G1P2PJub7GqZ6GUa1kJ1cWfzigWzRfBYaUF/GMVAqWZdx EX4j3fvVpUS/wiwqnk6LS/GzdrPtbtGr79q45TExAoaNPSeO4DDr1DG/FFPJrQ9eQTCc JmoQphux4rDUij5dTWi80hnm43Jldq9Nso/rTNVnsEl9cvSVmYySZM4HEuCfUD9cliOS bafAI14QUSfnkMVXK6SoyuvppG43t19gW+SmPW0hUwDKlnn/UkuheOEXjco3E48jFitq 8l0y2Hsz0JXfJ27XQbZpTbwbvIQF25K8zGNapBEG82rWuMxuFPzGjzt+MBgouLdNIzAe D6mQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=X3hgaRG54kX7m+io7AI45XFgBi4t8Rc9hxlfJtpvpb0=; b=atPLEjaY4I7/aU8gIsRHgQKUANGacpErZhi2+QwAVaIepc3j525Byr0iLJBmQzfddq lHO/wzlVe6j9PE2tBexiM4401WhHFTDWbeXGvk6jH5VZMoQkgaRHSqCvK2Pioun/uHw/ 0/pn51mqMhXhXcrlKnJ/DcCHlLy5Roexn3mt1VTewMXqXTRvZYuxYPTKQ6kLrqrz7zhg J1NURlJGRUDU9OA5bKqTNeZRpiQf9tZ8+X1+KDD+JmnRw1MwYJ6b7cJXWtvw4avEO0ki euElcYOk5Na5qRVLO89SxWPOnUBPpjofD1ZFDn/+LQDYZoxEmZOppWIlTYHliyslWLND tuGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=V7RGqFiw; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id h21si2953998ywc.684.2017.12.11.05.03.38 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:03:38 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=V7RGqFiw; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52616 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONkA-0000GX-55 for patch@linaro.org; Mon, 11 Dec 2017 08:03:38 -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) 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-Received: by 10.223.171.177 with SMTP id s46mr315433wrc.194.1512997030937; Mon, 11 Dec 2017 04:57:10 -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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Alex Bennée --- include/fpu/softfloat.h | 5 +++++ 1 file changed, 5 insertions(+) -- 2.15.1 Reviewed-by: Richard Henderson 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); } +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. *----------------------------------------------------------------------------*/ From patchwork Mon Dec 11 12:56:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121397 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2757516qgn; Mon, 11 Dec 2017 05:00:32 -0800 (PST) X-Google-Smtp-Source: ACJfBouYSNz0FX30n2CuGcxCWH0sE603vknzRpXsWAQ0LFUuudQKJvcVZzvjQIUDRJC6PQmvBr5L X-Received: by 10.13.233.198 with SMTP id s189mr189919ywe.267.1512997232448; Mon, 11 Dec 2017 05:00:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997232; cv=none; d=google.com; s=arc-20160816; b=h63Vdj0pXNf+2nEp+n9ibxaHPeOA/kOLQjfgBQyXxmeiefynrzpkor3+ahz3JshQTQ nR0E7PwHPx8UotCoqwyLh/Ks0uPd2b3IclM+7V5lb3ySm8cWl8XGy6EO6qtcJ+OC+lMJ +jW0Cq02pRS2J6s4G3DloocKBwUDNo+pQ3+bzWw4f9waDyW4fp5vmxOd7+jKKYga+bSd qnJQMsDnmj2o3eRiD+88yAFv+xB3+/9E8u1zstJXu4cgFvTZ06FjeukBcz1ayU5ZJ/8L 85zDa+fF//Pozh0iAnwFL5l+TjOKXc40o9O9aHA1WhSSVagOZGHda1ekGw4F5HCxZg5a RKow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=wP46SW2yKAaBmdenl9zzdRFHNYQbxZPYsnCJ88KO1hI=; b=a2eOEcbLWxV9KTekoTsGQZjFlXh5/TfK+LA7d7pr2+0gnJ++KNWzZd1ZW1nijLQOgf 4wVHZd7Nw0y4WQ5ar+JVwCc66uHOQJu/Y1531jGBH3vh0Ska+A6RqcpWyLHkq1/Fyyi4 aDib1x0yPtYt9xlI6bAmbbeTXOIi1TVvwHHIWJbID4C1a9slO2CUIJLHC4BmIu0+hIVF /waNlRueXHEGWSRHOi2u3a7oJE54vt6aSR1v2obMyJYgnwUZ/zn0qxq9wzVfHI7M6Uq9 X+2IB3awlVitHG2UoneVhJHInAELr+SDwDcYfKTAFGWFLv8/kIFARZgIeQcoI0fdnFqo +gbg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=SR2T/vLK; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id u79si2987699ywu.365.2017.12.11.05.00.32 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:00:32 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=SR2T/vLK; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52597 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONh9-0004kb-U8 for patch@linaro.org; Mon, 11 Dec 2017 08:00:31 -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) 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-Received: by 10.223.149.6 with SMTP id 6mr314677wrs.112.1512997032444; Mon, 11 Dec 2017 04:57:12 -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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- include/fpu/softfloat.h | 7 +++++++ 1 file changed, 7 insertions(+) -- 2.15.1 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)); } +#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. *----------------------------------------------------------------------------*/ From patchwork Mon Dec 11 12:56:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121392 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2755960qgn; Mon, 11 Dec 2017 04:59:14 -0800 (PST) X-Google-Smtp-Source: ACJfBovK1/S9D94yEyj8R/+8FNUbrO0nRaVdnzCKVrAsLFM3wY+paPckbEY3PlO1i3o+JawcoK30 X-Received: by 10.129.164.13 with SMTP id b13mr188109ywh.137.1512997154087; Mon, 11 Dec 2017 04:59:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997154; cv=none; d=google.com; s=arc-20160816; b=RGI1giyJDakTbAnPCm86lphsEJdICcSJj1E0folFMqmFGLOOZ2+ohtndTBml7jkOl3 yHQOntIZizECFnFZxc/j5x+Y+gJ8fYH1GzJqAsvnS90h0KEKm1PgjJkaulQO06WdVQMM bEdVUd2rYrR5XrXChJZh7wt3Uy1pHx/FINZNFEm3uPNHF5y6iqvdTQLVmENCS+VyhVxG B++g04bzcZiVX/E7yCclB2VPWonOmjpnI1oPXa/ZVSgMEqvbGuOhM7GH0/fovbjeqe3K lRGP0PE9keMzv4THTLcXfYNQq2WPx5v3xGn53oEtPi2e3VAX7jjtTpfiejfdRHrd+YCp LsVg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=a8qJvGNOHj73yUicqTGoW6jItVWTSgReiBPPFz2yrLk=; b=KETvwc6neBwedLXUAhgYwnIlaqjd+WYWfQjpOOP6slGRbvi2KZfbY8DkUQOid5B/a+ egWWIlDBZlc/mFqVzY82tg6oyHvbDc90oMgdD2XxeKPNKPEQhOgNupBVn2c4xxXEUjBp RSUSk1xkWoztgGEevRUpZNl/TEMsEkvh1b0w3enLmvXdZVHZujEDuWuXu+lx23tpVD4F K9TR58HISXj9DhO30JZlPc8o9uTv76eTqQqzLYRD5zmbY5RBEC7NkpOObnvvOZopd4aK kg2UiPQflXpGKbchObSXfU1IuF2REbHMIWEO7b/sMFPqMRl/JyENpx2i2Nrg0pdWWp97 ufhw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Ktv/wxD1; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id t16si2875878ybb.34.2017.12.11.04.59.13 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 04:59:14 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Ktv/wxD1; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52590 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONft-0003dt-FM for patch@linaro.org; Mon, 11 Dec 2017 07:59:13 -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) 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-Received: by 10.223.158.203 with SMTP id b11mr346185wrf.82.1512997033243; 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 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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- v2 - added return for propageFloat --- fpu/softfloat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) -- 2.15.1 Reviewed-by: Richard Henderson 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, float_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(float ## 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; \ } \ } \ From patchwork Mon Dec 11 12:56:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121400 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2761792qgn; Mon, 11 Dec 2017 05:03:13 -0800 (PST) X-Google-Smtp-Source: ACJfBovt2Kb8aBjelPROOV9fpMa5S7zTmPvRJq8av02Xt9vU0PA9eYgljrTRRWQCyyGtTXc4uHwn X-Received: by 10.37.102.75 with SMTP id z11mr189803ybm.500.1512997393773; Mon, 11 Dec 2017 05:03:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997393; cv=none; d=google.com; s=arc-20160816; b=FZQ+nZs6AifnwsN5p6GXPHbR4Gp+jyQXqlq0D+cbLI+LpGNFPlzhOxrxahTSmjvh5I qP9W192RXDF7Dj3fNdNa2sepqbUqeKJuoX7aUCH4KhQ8jhoueF3VaTXS6B0qmcNUyk3C ZzC9Sru7ud/iJV1iPzDkHSt5ycF/6Jsl6LLbPFIVUFTpAHibb3MY099cd22dqFRCsM2t j/md7EAbJKr8PFl2ibdf/4p03U5JjyEGlAXLd2a+k/ImtKzzp9fDm6P0y35oMhNHtyFx +TpiXH7DadalcXHyzAR1zz2EjIU7erluvBImwCNkb4cwZKGZqviS0Bk2o4cJycwepqw9 xguQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=FzwTmZYzQddLlG5oQWYZVSPcWE3+WT8pXshd4eSan+k=; b=THTgcAmINU8zikgmzjbU1O9JhqPzc4cVT/8+KHQpCfA5r/Nb1Mwb45154rfYs/BXu9 6mIWFFHQan5WZdLHBaIlTS2T+ak0juvSoEbyeKzGyxJriPxDIbhODFKV2M9czeQC91OW eKTBRs1umJkluvKl9Jj2Na1xo42MIMqiI+N+gm7D/bnFYGxxHsaARb6gEpti6QOxfCvI HLARiTjUx1EPL9APivZOzErzDEoZjWLC+ub2vSp0p6L1KIiU3kAhzIjvZCGqYcxjrEPi eSptHrdcMzN+4A0N6wWDZ4yRQwrWuxWJJbLQ1Zu3//fX9YmLxRI+H3dqtQ4kxSDXQVgd Du2A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=KS3Qj0Jn; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id h81si2984753ybc.735.2017.12.11.05.03.13 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:03:13 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=KS3Qj0Jn; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52610 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONjl-0006OQ-9H for patch@linaro.org; Mon, 11 Dec 2017 08:03:13 -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) 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-Received: by 10.223.181.132 with SMTP id c4mr319251wre.42.1512997036638; 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 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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Mention the pseudo-code fragment from which this is based and correct the spelling of signalling. Signed-off-by: Alex Bennée --- fpu/softfloat-specialize.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) -- 2.15.1 Reviewed-by: Richard Henderson 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) #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; From patchwork Mon Dec 11 12:56:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121405 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2767399qgn; Mon, 11 Dec 2017 05:07:24 -0800 (PST) X-Google-Smtp-Source: ACJfBosPc64tzvptbGO7TGCobNcacjIEZquPFOkOlowkWu0bMSJhNMv5TPwmv9E4pgSUyN+j+bXS X-Received: by 10.37.132.138 with SMTP id v10mr210675ybk.228.1512997644298; Mon, 11 Dec 2017 05:07:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997644; cv=none; d=google.com; s=arc-20160816; b=KKTm+bniGwRm8Ngf1mVuJj4XcDg4f8cWBePz39l44+HdGxE5Ng6MQ0hEJ8eb/fJEkA 1XuMiR1dxt47lNgEkC8GCCcZDYVs4/SrIkcMpxDoTMEkCpzisIaXsBN3zN+s+nTjqLkF UTJRtLW6c5lOCx36cGuLTydHIHa7cqPkxqd1lNOIsLbtPHgAF0pw6DlbnCoT4jtm5y5B qlNoB7CWqDrVSwd9cTowqLuxO414ezoYI7YkPj3CASnYKOmi8YaxdGFc96eaObjWrNSC 1InOd0Lt5DBO3xNXwdbkd2EJa85B5slFoaX4/ayWhNcqyiBInni0Ebfg1aaYsoNreg1p WSPw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=b6zTeLeoJwXTa0YonO9q4Wjz9CylVVC+D6KJ/p8yPj8=; b=YoFysmUKqpKYZJiAIoNPqPh+5wUoMkEmSmNZBE5mVfcq61Sq0oFBKqlaIfxUFFFy61 4MAHLSt41HR0L3GEJ59g97h/dHu8k3cH8mVihiD0rWzZetQwjRlEHdmk+i/U0bnXPVra g1b+eMwrOLDFR3jx86qRAAISUxwiDmjMcjcyk8FXPpAl1G4QsD/Be9qxEpRrwP6WZvsK Nm85Gm6o9R9VkNcYbfBADLl8TA9dNaiLzRHp1vuOT2zTFhUgSeTyaeLzkdSctwsMbSUs MLqN8V1pc3ckAw3j63qHe0yeThJwr7+z97MdUjMtMp5QROfpObxxksguuNmCu3KJfJ6F 5imw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=LNuw23Ah; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id r133si2915041ywr.494.2017.12.11.05.07.24 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:07:24 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=LNuw23Ah; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52667 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONnn-0005cL-O9 for patch@linaro.org; Mon, 11 Dec 2017 08:07:23 -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) 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-Received: by 10.223.158.147 with SMTP id a19mr312760wrf.179.1512997035709; Mon, 11 Dec 2017 04:57:15 -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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This is pure code-motion during re-factoring as the helpers will be needed earlier. Signed-off-by: Alex Bennée --- fpu/softfloat.c | 119 +++++++++++++++++++++++++------------------------------- 1 file changed, 53 insertions(+), 66 deletions(-) -- 2.15.1 Reviewed-by: Richard Henderson 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; } +/*---------------------------------------------------------------------------- +| 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; } -/*---------------------------------------------------------------------------- -| 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 value. @@ -492,39 +512,6 @@ static float32 } -/*---------------------------------------------------------------------------- -| 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 value. From patchwork Mon Dec 11 12:56:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121401 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2762341qgn; Mon, 11 Dec 2017 05:03:36 -0800 (PST) X-Google-Smtp-Source: ACJfBos26UW35wtVm2EltRLpPqwy74zwerdQI0iW5W4oSmECqE9DMyXjW97eCDyX/klYO76oH3SE X-Received: by 10.37.188.146 with SMTP id e18mr206453ybk.31.1512997416451; Mon, 11 Dec 2017 05:03:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997416; cv=none; d=google.com; s=arc-20160816; b=Q31IOjKiGDsy8K1D2s1rVnMLrPY6YHLw+Ihwv438DG6V7OnrBQaV3RQxHZnxUqeEW5 ZTlUesRUR00p7g+TNQBFFaTnR9KPmHu4M0ia3JC7/MrJZc56hfxz483UHd1mO+4inVlX YvDgEWGfqj8F/t3r1bQ3YCfjAEvxn7lZPu1yEI5Sf2q5DRtbRrDiUHSbE13CbyWcPdej vW1hIXGUrgIYSRMRy/fc5llMEAgJ7u6u1Lh6dDJCieUD3ixA9Ooh9IEB7sTBOu4xD9V3 wYDRIDH14uTe+Q8SpXZhB1f8cUHliFEoGwAovzUL8HQBHvy20g+m14u6o5lL5B9rdfUF kJJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=XPya0JZDgDrSn8vFhXRH6qNNUTXHPncbbdbXFArQOvM=; b=oeKuLfwp3oxxKhiLJropcztC8du+ifcVfkYG97DnG204Acv9Az5qvonc7q0DXYPJhC h0fsQ2el92hbpD0WjCDvYnZNDRJJozKD+OdzGS8VlyQjMO5O0JEEYanqrqMc5g497uEV V0xI9l48ypgwWFGL5jT5eiI9j76mT/ipkd9+efOBNnaZpXq1QaybnOl8XZd6gVMjvDiD 11aXDEgtAtG86bYBNa474isEUJ8j5buQAHLpoOayvvGTObtyYMEMEZQ8BuYM6EvGKHd/ G4oqin12pFJ8m/cAOpx6+anG5U4Kwz/YZtVk+O0AYi5m3JvQ6BQ1He6AGC1r/fUorCiO m04w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=EVv5w8UL; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id g193si1121322ybf.201.2017.12.11.05.03.36 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:03:36 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=EVv5w8UL; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52615 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONk7-0000Fj-Ut for patch@linaro.org; Mon, 11 Dec 2017 08:03:36 -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) 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-Received: by 10.223.139.199 with SMTP id w7mr323225wra.282.1512997038000; 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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" These structures pave the way for generic softfloat helper routines that will operate on fully decomposed numbers. Signed-off-by: Alex Bennée --- fpu/softfloat.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) -- 2.15.1 Signed-off-by: Richard Henderson 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" /* 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 = F, \ + .frac_lsb = 1ull << (F), \ + .frac_lsbm1 = 1ull << ((F) - 1), \ + .round_mask = (1ull << (F)) - 1, \ + .roundeven_mask = (2ull << (F)) - 1 + +static const decomposed_params float16_params = { + .exp_bias = 0x0f, + .exp_max = 0x1f, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 10) +}; + +static const decomposed_params float32_params = { + .exp_bias = 0x7f, + .exp_max = 0xff, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 23) +}; + +static const decomposed_params float64_params = { + .exp_bias = 0x3ff, + .exp_max = 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 From patchwork Mon Dec 11 12:56:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121407 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2769665qgn; Mon, 11 Dec 2017 05:09:18 -0800 (PST) X-Google-Smtp-Source: ACJfBot5wmqzzeh/OQ7mTRUYWhnQ0stBgzlybWyyXsE1qVfOXmLcG29W+PY3XIX/vbEBVBoOMTZZ X-Received: by 10.37.108.4 with SMTP id h4mr205373ybc.109.1512997758563; Mon, 11 Dec 2017 05:09:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997758; cv=none; d=google.com; s=arc-20160816; b=QnY2Eit5otZ2O/dZnBDGSIgzCGQq6ceQpEnAH3YAToPEuvAKjY3eXiev4wFWsHnhH9 rIg+GM4LhROgC8VYNyHs72JZBZ47U1R2efMIy/YDfgYCvA5zWdqiGNTOH/en06vW9CAG 5S0t9VX5HA+xIo80B0jno8oKN8x1Pr3+TNcD1rRluEsflV31ELL29NRqzHDl0Sdx0nQO xMkk9wuCMcZgOJsEQJ1QrBva+ujXtyJOPymxtLrGOrdlYj+yU/LPb6ppUEJnBld+fDtC rOzuzCDCmnaAaIsqMn61lk9DO5iLeU2OBtT3dzOHfXHImyu1dsaaJUmxwt6CtLe/vHl0 rXlg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=6lbSkk1s/XmLHb3qec1ZISyhVguMCAgA2iNd6IeTJZQ=; b=oPJY1cKQbd9mrUS57NjZeHKk/9ndpPCdy996yJL86Ir+fM3Fn0Ax+gx/l9aIXrc9Uo wqq2L0bVEnD+ulb/plbUKSVBQo93dpODbREwySCPWd+d4MDtnL9BQ6uibOMPrN6PxywV dCEU4vame/mPzhlDbgpLfnsXO2JT09R07c/dMR8HWFy1gBSIPb4iiP6jBAKz/6Cf5Ain 2chYdNzx7N2/XOPtABuzxMVVGKUh+8UxasoTcNujvn7Ulw+FdtMRzUiqUhrmREXWXGmW aLlE9TPxA+b+TD6FULqt0Ji3lftieH0MEnNyNUcR/DxIi4SSq8YZqTDVVVGOsSXcqh0B VGsg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=VeVeo6md; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id z72si2894762ywa.798.2017.12.11.05.09.18 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:09:18 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=VeVeo6md; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52708 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONpd-0000Ci-VK for patch@linaro.org; Mon, 11 Dec 2017 08:09:18 -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) 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-Received: by 10.223.130.205 with SMTP id 71mr312545wrc.101.1512997038714; 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 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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- fpu/softfloat.c | 903 +++++++++++++++++++++++++----------------------- include/fpu/softfloat.h | 4 + 2 files changed, 480 insertions(+), 427 deletions(-) -- 2.15.1 Signed-off-by: Richard Henderson 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 = { FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 52) }; +/* Unpack a float16 to parts, but do not canonicalize. */ +static inline decomposed_parts float16_unpack_raw(float16 f) +{ + return (decomposed_parts){ + .cls = float_class_unclassified, + .sign = extract32(f, 15, 1), + .exp = extract32(f, 10, 5), + .frac = 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 = float_class_unclassified, + .sign = extract32(f, 31, 1), + .exp = extract32(f, 23, 8), + .frac = 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 = float_class_unclassified, + .sign = extract64(f, 63, 1), + .exp = extract64(f, 52, 11), + .frac = 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 = p.frac; + ret = deposit32(ret, 10, 5, p.exp); + ret = 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 = p.frac; + ret = deposit32(ret, 23, 8, p.exp); + ret = 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 = p.frac; + ret = deposit64(ret, 52, 11, p.exp); + ret = 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 == parm->exp_max) { + if (part.frac == 0) { + part.cls = float_class_inf; + } else { +#ifdef NO_SIGNALING_NANS + part.cls = float_class_qnan; +#else + int64_t msb = part.frac << (parm->frac_shift + 2); + if ((msb < 0) == status->snan_bit_is_one) { + part.cls = float_class_snan; + } else { + part.cls = float_class_qnan; + } +#endif + } + } else if (part.exp == 0) { + if (likely(part.frac == 0)) { + part.cls = float_class_zero; + } else if (status->flush_inputs_to_zero) { + float_raise(float_flag_input_denormal, status); + part.cls = float_class_zero; + part.frac = 0; + } else { + int shift = clz64(part.frac) - 1; + part.cls = float_class_normal; + part.exp = parm->frac_shift - parm->exp_bias - shift + 1; + part.frac <<= shift; + } + } else { + part.cls = float_class_normal; + part.exp -= parm->exp_bias; + part.frac = DECOMPOSED_IMPLICIT_BIT + (part.frac << parm->frac_shift); + } + return part; +} + +/* Round and uncanonicalize a floating-point number by parts. + There are FRAC_SHIFT bits that may require rounding at the bottom + of the fraction; these bits will be removed. The exponent will be + biased 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 = parm->frac_lsbm1; + const uint64_t round_mask = parm->round_mask; + const uint64_t roundeven_mask = parm->roundeven_mask; + const int exp_max = parm->exp_max; + const int frac_shift = parm->frac_shift; + uint64_t frac, inc; + int exp, flags = 0; + bool overflow_norm; + + frac = p.frac; + exp = p.exp; + + switch (p.cls) { + case float_class_normal: + switch (s->float_rounding_mode) { + case float_round_nearest_even: + overflow_norm = false; + inc = ((frac & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0); + break; + case float_round_ties_away: + overflow_norm = false; + inc = frac_lsbm1; + break; + case float_round_to_zero: + overflow_norm = true; + inc = 0; + break; + case float_round_up: + inc = p.sign ? 0 : round_mask; + overflow_norm = p.sign; + break; + case float_round_down: + inc = p.sign ? round_mask : 0; + overflow_norm = !p.sign; + break; + default: + g_assert_not_reached(); + } + + exp += parm->exp_bias; + if (likely(exp > 0)) { + if (frac & round_mask) { + flags |= float_flag_inexact; + frac += inc; + if (frac & DECOMPOSED_OVERFLOW_BIT) { + frac >>= 1; + exp++; + } + } + frac >>= frac_shift; + + if (unlikely(exp >= exp_max)) { + flags |= float_flag_overflow | float_flag_inexact; + if (overflow_norm) { + exp = exp_max - 1; + frac = -1; + } else { + p.cls = float_class_inf; + goto do_inf; + } + } + } else if (s->flush_to_zero) { + flags |= float_flag_output_denormal; + p.cls = float_class_zero; + goto do_zero; + } else { + bool is_tiny = (s->float_detect_tininess + == 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 == float_round_nearest_even) { + inc = ((frac & roundeven_mask) != frac_lsbm1 + ? frac_lsbm1 : 0); + } + flags |= float_flag_inexact; + frac += inc; + } + + exp = (frac & DECOMPOSED_IMPLICIT_BIT ? 1 : 0); + frac >>= frac_shift; + + if (is_tiny && (flags & float_flag_inexact)) { + flags |= float_flag_underflow; + } + if (exp == 0 && frac == 0) { + p.cls = float_class_zero; + } + } + break; + + case float_class_zero: + do_zero: + exp = 0; + frac = 0; + break; + + case float_class_inf: + do_inf: + exp = exp_max; + frac = 0; + break; + + case float_class_qnan: + case float_class_snan: + exp = exp_max; + break; + + default: + g_assert_not_reached(); + } + + float_raise(flags, s); + p.exp = exp; + p.frac = 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_status *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 = 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_status *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 = 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_status *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 = decomposed_round_canonical(p, s, &float64_params); + return float64_pack_raw(p); + } +} + +static decomposed_parts pick_nan_parts(decomposed_parts a, decomposed_parts b, + float_status *s) +{ + if (a.cls == float_class_snan || b.cls == float_class_snan) { + s->float_exception_flags |= float_flag_invalid; + } + + if (s->default_nan_mode) { + a.cls = float_class_dnan; + } else { + if (pickNaN(a.cls == float_class_qnan, + a.cls == float_class_snan, + b.cls == float_class_qnan, + b.cls == float_class_snan, + a.frac > b.frac + || (a.frac == b.frac && a.sign < b.sign))) { + a = b; + } + a.cls = 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_parts b, + bool subtract, float_status *s) +{ + bool a_sign = a.sign; + bool b_sign = b.sign ^ subtract; + + if (a_sign != b_sign) { + /* Subtraction */ + + if (a.cls == float_class_normal && b.cls == float_class_normal) { + int a_exp = a.exp; + int b_exp = b.exp; + uint64_t a_frac = a.frac; + uint64_t b_frac = b.frac; + + if (a_exp > b_exp || (a_exp == b_exp && a_frac >= b_frac)) { + shift64RightJamming(b_frac, a_exp - b_exp, &b_frac); + a_frac = a_frac - b_frac; + } else { + shift64RightJamming(a_frac, b_exp - a_exp, &a_frac); + a_frac = b_frac - a_frac; + a_exp = b_exp; + a_sign ^= 1; + } + + if (a_frac == 0) { + a.cls = float_class_zero; + a.sign = s->float_rounding_mode == float_round_down; + } else { + int shift = clz64(a_frac) - 1; + a.frac = a_frac << shift; + a.exp = a_exp - shift; + a.sign = a_sign; + } + return a; + } + if (a.cls >= float_class_qnan + || + b.cls >= float_class_qnan) + { + return pick_nan_parts(a, b, s); + } + if (a.cls == float_class_inf) { + if (b.cls == float_class_inf) { + float_raise(float_flag_invalid, s); + a.cls = float_class_dnan; + } + return a; + } + if (a.cls == float_class_zero && b.cls == float_class_zero) { + a.sign = s->float_rounding_mode == float_round_down; + return a; + } + if (a.cls == float_class_zero || b.cls == float_class_inf) { + b.sign = a_sign ^ 1; + return b; + } + if (b.cls == float_class_zero) { + return a; + } + } else { + /* Addition */ + if (a.cls == float_class_normal && b.cls == float_class_normal) { + int a_exp = a.exp; + int b_exp = b.exp; + uint64_t a_frac = a.frac; + uint64_t b_frac = 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 = b_exp; + } + a_frac += b_frac; + if (a_frac & DECOMPOSED_OVERFLOW_BIT) { + a_frac >>= 1; + a_exp += 1; + } + + a.exp = a_exp; + a.frac = a_frac; + return a; + } + if (a.cls >= float_class_qnan + || + b.cls >= float_class_qnan) { + return pick_nan_parts(a, b, s); + } + if (a.cls == float_class_inf || b.cls == float_class_zero) { + return a; + } + if (b.cls == float_class_inf || a.cls == float_class_zero) { + b.sign = b_sign; + return b; + } + } + g_assert_not_reached(); +} + +/* + * Returns the result of adding or subtracting the floating-point + * values `a' and `b'. The operation is performed according to the + * IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +float16 float16_add(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pb = float16_unpack_canonical(b, status); + decomposed_parts pr = 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 = float32_unpack_canonical(a, status); + decomposed_parts pb = float32_unpack_canonical(b, status); + decomposed_parts pr = 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 = float64_unpack_canonical(a, status); + decomposed_parts pb = float64_unpack_canonical(b, status); + decomposed_parts pr = 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 = float16_unpack_canonical(a, status); + decomposed_parts pb = float16_unpack_canonical(b, status); + decomposed_parts pr = 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 = float32_unpack_canonical(a, status); + decomposed_parts pb = float32_unpack_canonical(b, status); + decomposed_parts pr = 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 = float64_unpack_canonical(a, status); + decomposed_parts pb = float64_unpack_canonical(b, status); + decomposed_parts pr = add_decomposed(pa, pb, true, status); + + return float64_round_pack_canonical(pr, status); +} /*---------------------------------------------------------------------------- | 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_status *status) } -/*---------------------------------------------------------------------------- -| 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 = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - expDiff = aExp - bExp; - aSig <<= 6; - bSig <<= 6; - if ( 0 < expDiff ) { - if ( aExp == 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= 0x20000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= 0x20000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - zExp = bExp; - } - else { - if ( aExp == 0xFF ) { - if (aSig | bSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( aExp == 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 = 0x40000000 + aSig + bSig; - zExp = aExp; - goto roundAndPack; - } - aSig |= 0x20000000; - zSig = ( aSig + bSig )<<1; - --zExp; - if ( (int32_t) zSig < 0 ) { - zSig = 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 = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - expDiff = aExp - bExp; - aSig <<= 7; - bSig <<= 7; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0xFF ) { - if (aSig | bSig) { - return propagateFloat32NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat32(status->float_rounding_mode == float_round_down, 0, 0); - bExpBigger: - if ( bExp == 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign ^ 1, 0xFF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= 0x40000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - bSig |= 0x40000000; - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= 0x40000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - aSig |= 0x40000000; - aBigger: - zSig = aSig - bSig; - zExp = 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 = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign == bSign ) { - return addFloat32Sigs(a, b, aSign, status); - } - else { - return subFloat32Sigs(a, b, aSign, status); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting 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_sub(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign; - a = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign == bSign ) { - return subFloat32Sigs(a, b, aSign, status); - } - else { - return addFloat32Sigs(a, b, aSign, status); - } - -} /*---------------------------------------------------------------------------- | Returns the result of multiplying the single-precision floating-point values @@ -3876,219 +4138,6 @@ float64 float64_trunc_to_int(float64 a, float_status *status) return res; } -/*---------------------------------------------------------------------------- -| 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 = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - expDiff = aExp - bExp; - aSig <<= 9; - bSig <<= 9; - if ( 0 < expDiff ) { - if ( aExp == 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= LIT64( 0x2000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= LIT64( 0x2000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - zExp = bExp; - } - else { - if ( aExp == 0x7FF ) { - if (aSig | bSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( aExp == 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 = LIT64( 0x4000000000000000 ) + aSig + bSig; - zExp = aExp; - goto roundAndPack; - } - aSig |= LIT64( 0x2000000000000000 ); - zSig = ( aSig + bSig )<<1; - --zExp; - if ( (int64_t) zSig < 0 ) { - zSig = 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 = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - expDiff = aExp - bExp; - aSig <<= 10; - bSig <<= 10; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FF ) { - if (aSig | bSig) { - return propagateFloat64NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat64(status->float_rounding_mode == float_round_down, 0, 0); - bExpBigger: - if ( bExp == 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign ^ 1, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= LIT64( 0x4000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - bSig |= LIT64( 0x4000000000000000 ); - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= LIT64( 0x4000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - aSig |= LIT64( 0x4000000000000000 ); - aBigger: - zSig = aSig - bSig; - zExp = 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 = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign == bSign ) { - return addFloat64Sigs(a, b, aSign, status); - } - else { - return subFloat64Sigs(a, b, aSign, status); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting 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_sub(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign; - a = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign == bSign ) { - return subFloat64Sigs(a, b, aSign, status); - } - else { - return addFloat64Sigs(a, b, aSign, status); - } - -} /*---------------------------------------------------------------------------- | Returns the result of multiplying the double-precision floating-point values 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); From patchwork Mon Dec 11 12:56:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121411 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2771613qgn; Mon, 11 Dec 2017 05:10:58 -0800 (PST) X-Google-Smtp-Source: ACJfBotE4Q6gzX9fpjRzhzYcilxeaaWhDJG/IOfhcxhnZ7CkFboaW/6WDz3oeVKNITyWznEXykVA X-Received: by 10.37.234.9 with SMTP id p9mr245857ybd.82.1512997858043; Mon, 11 Dec 2017 05:10:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997858; cv=none; d=google.com; s=arc-20160816; b=SqY466sW80NS/aDRLR+CyKQOj/TiwK9vzDT5AvStfcim/0uAPt5Q1sHRYnRG3MRr9i xqTlY2P8YXsaxmrrfl4WPXA/PbH9wcHAQ//D2jsxiv9HNJjd+WHiD2F/dL+VwV52i2Et pvAmZmmWBevie8+Op6GwIy6ixiqxIMEaxtHjisFx0mCfo95kX64nYSciQa3sPYMD8X5K Qy7lZNO4cQFo+TRvRr6wleuCkPcL5KquRiIuq721epbeDyEiBsFgSpTOJ++vCkvKv1ax cxkc7SWj9PfilmKt68mcimoJh39K32/caK4UeVWHB3vpttnbelsLnvX7+LQj9u3tx3XZ u3kQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=LLNgZdVyhPcAlMxeRXALcg0XHGk4OuhYNQ8keGJgIiw=; b=uABCOx9ElXjsNMgNKt0G+DI6t+PtFeFo+NAz7CXWpfADsG+bYwml50MbY40tyT50P2 SHu4yvNSBuTaeUO2H6F1sBVYifUIy8ssmabAIppTXj02fh54T6Zf9ZZRVRp3VeznBFOG LGYUaB2NwS7GOcgzJwjVJPG9QwaDDmHxnSqTmjjvdIOWxzPxGUqZOIgS7aovboYd+dal rWFmoF6fB212etdg6GOeAlVoEDefPl6jfOkq/hdvggMOkV/Dmz7RoKE4+zQ1mRMenDbB CiAuWJiqRUQmfyMrnHII6zsKB9kykxiKo1mkSK+6C6wNCYFVo4l8NUOwnaXT83xmg4tm jtnQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=bqK9VhOI; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id m5si2966712ywe.672.2017.12.11.05.10.57 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:10:58 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=bqK9VhOI; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52725 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONrF-0000zv-Ga for patch@linaro.org; Mon, 11 Dec 2017 08:10:57 -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) 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-Received: by 10.223.135.121 with SMTP id 54mr370455wrz.160.1512997595161; Mon, 11 Dec 2017 05:06:35 -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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- fpu/softfloat.c | 207 ++++++++++++++++++------------------------------ include/fpu/softfloat.h | 1 + 2 files changed, 80 insertions(+), 128 deletions(-) -- 2.15.1 Signed-off-by: Richard Henderson 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); } +/* + * 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_parts b, + float_status *s) +{ + bool sign = a.sign ^ b.sign; + + if (a.cls == float_class_normal && b.cls == float_class_normal) { + uint64_t hi, lo; + int exp = 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 += 1; + } + + /* Re-use a */ + a.exp = exp; + a.sign = sign; + a.frac = lo; + return a; + } + /* handle all the NaN cases */ + if (a.cls >= float_class_qnan || b.cls >= float_class_qnan) { + return pick_nan_parts(a, b, s); + } + /* Inf * Zero == NaN */ + if (((1 << a.cls) | (1 << b.cls)) == + ((1 << float_class_inf) | (1 << float_class_zero))) { + s->float_exception_flags |= float_flag_invalid; + a.cls = float_class_dnan; + a.sign = sign; + return a; + } + /* Multiply by 0 or Inf */ + if (a.cls == float_class_inf || a.cls == float_class_zero) { + a.sign = sign; + return a; + } + if (b.cls == float_class_inf || b.cls == float_class_zero) { + b.sign = sign; + return b; + } + g_assert_not_reached(); +} + +float16 float16_mul(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pb = float16_unpack_canonical(b, status); + decomposed_parts pr = 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 = float32_unpack_canonical(a, status); + decomposed_parts pb = float32_unpack_canonical(b, status); + decomposed_parts pr = 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 = float64_unpack_canonical(a, status); + decomposed_parts pb = float64_unpack_canonical(b, status); + decomposed_parts pr = 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) } -/*---------------------------------------------------------------------------- -| Returns the result of multiplying 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_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 = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - bSign = extractFloat32Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0xFF ) { - if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { - return propagateFloat32NaN(a, b, status); - } - if ( ( bExp | bSig ) == 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp == 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - if ( ( aExp | aSig ) == 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x7F; - aSig = ( aSig | 0x00800000 )<<7; - bSig = ( bSig | 0x00800000 )<<8; - shift64RightJamming( ( (uint64_t) aSig ) * bSig, 32, &zSig64 ); - zSig = zSig64; - if ( 0 <= (int32_t) ( zSig<<1 ) ) { - zSig <<= 1; - --zExp; - } - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} /*---------------------------------------------------------------------------- | 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; } - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying 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_mul(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig0, zSig1; - - a = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - bSign = extractFloat64Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FF ) { - if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { - return propagateFloat64NaN(a, b, status); - } - if ( ( bExp | bSig ) == 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp == 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - if ( ( aExp | aSig ) == 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x3FF; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - zSig0 |= ( zSig1 != 0 ); - if ( 0 <= (int64_t) ( zSig0<<1 ) ) { - zSig0 <<= 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); float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); +float16 float16_mul(float16, float16, float_status *status); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); From patchwork Mon Dec 11 12:56:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121413 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2775888qgn; Mon, 11 Dec 2017 05:14:34 -0800 (PST) X-Google-Smtp-Source: ACJfBosAzAPhtkNZDwFiinr8kEsiYYEPuu18sZuqXi8g2J84WlMl5oB2MLSlEXmGBLEvf/vIW81H X-Received: by 10.129.173.73 with SMTP id l9mr244248ywk.313.1512998074365; Mon, 11 Dec 2017 05:14:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512998074; cv=none; d=google.com; s=arc-20160816; b=WJ3+fPr1ra6Ow1Wsi7eq1+kY4X4fUih+dC7m8eNfvWxZP/FaXmmRmaMYTQQFlsUU7A 00y90XYpMyzjAPGWAOjFOuzU1XaiiXudtSZjaSGvAbOKYzJjqM3+196YD3VdwEMDAbx8 fxk9pA3uApMIW9Aa2/TAW5xXTQ49XPIeAadh/7JnAsanRPiW8nfgFZoKSXN2RFTFQDL3 2xRx1aERHjF4bb5Mlkrykfs5rL5PfDfPETysjO2Sn5qjSB27qEL5dvPD5hxlpG24HU6E sKbF4dppTSzV9KoJY48WY4ADojH+5Ol9TnqcFlZ2HcWE5qeNOrLUOlHrMqWmMBnRtJ5m acJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=I7dngJ0yPM3FsvpuZ+nIa2f1Icnze4NIyWUeSiroSUg=; b=E+8Tk/aFw2iRBv5IsyP/4KkNN0UyKLnXGV1VaXR7cisEKQ+2cgCZGrqp0cEVosBHsf x0RyC83LxXblQGBlRr63fYyg8tsvfLNpPO6tWOfvxXJNAlaIjjMbCiOEHmH2eO7aGfaH 22bcNmlyc1wsUM8+LA5lpzRVXwj4zcK8d6ye+F8jMpC6IPsytENJ3fe/taH2o+7iRcBk S9x8ixWTrlLDfAqcYgPZDRwso/pgTnh8H1+7hyGQsAuQM3WneSmxjGKKLU3ZHsNxKRZo tSQMZoL6GULddl05926YMevU6+uzM7WeVCmxalzczcpo9Ji5Q1Z+wue5+yEZOM81Sl7R 94cg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=f6RJreK0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id v130si2920565ywa.182.2017.12.11.05.14.34 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:14:34 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=f6RJreK0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52869 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONuj-0005Ds-SF for patch@linaro.org; Mon, 11 Dec 2017 08:14:33 -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) 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-Received: by 10.223.176.113 with SMTP id g46mr333922wra.267.1512997597474; 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 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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- fpu/softfloat-macros.h | 44 +++++++++ fpu/softfloat.c | 235 ++++++++++++++++++------------------------------ include/fpu/softfloat.h | 1 + 3 files changed, 134 insertions(+), 146 deletions(-) -- 2.15.1 Signed-off-by: Richard Henderson 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, uint64_t a1, uint64_t b ) } +/* 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 = (uint32_t)d; + d1 = d >> 32; + + r1 = n1 % d1; + q1 = n1 / d1; + m = q1 * d0; + r1 = (r1 << 32) | (n0 >> 32); + if (r1 < m) { + q1 -= 1; + r1 += d; + if (r1 >= d) { + if (r1 < m) { + q1 -= 1; + r1 += d; + } + } + } + r1 -= m; + + r0 = r1 % d1; + q0 = r1 / d1; + m = q0 * d0; + r0 = (r0 << 32) | (uint32_t)n0; + if (r0 < m) { + q0 -= 1; + r0 += d; + if (r0 >= d) { + if (r0 < m) { + q0 -= 1; + r0 += d; + } + } + } + r0 -= m; + + /* Return remainder in LSB */ + return (q1 << 32) | q0 | (r0 != 0); +} + /*---------------------------------------------------------------------------- | Returns an approximation to the square root of the 32-bit significand given | 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); } +/* + * 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_parts b, + float_status *s) +{ + bool sign = a.sign ^ b.sign; + + if (a.cls == float_class_normal && b.cls == float_class_normal) { + uint64_t temp_lo, temp_hi; + int exp = a.exp - b.exp; + if (a.frac < b.frac) { + exp -= 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 = div128To64(temp_lo, temp_hi, b.frac); + a.sign = sign; + a.exp = exp; + return a; + } + /* handle all the NaN cases */ + if (a.cls >= float_class_qnan || b.cls >= float_class_qnan) { + return pick_nan_parts(a, b, s); + } + /* 0/0 or Inf/Inf */ + if (a.cls == b.cls + && + (a.cls == float_class_inf || a.cls == float_class_zero)) { + s->float_exception_flags |= float_flag_invalid; + a.cls = float_class_dnan; + return a; + } + /* Div 0 => Inf */ + if (b.cls == float_class_zero) { + s->float_exception_flags |= float_flag_divbyzero; + a.cls = float_class_inf; + a.sign = sign; + return a; + } + /* Inf / x or 0 / x */ + if (a.cls == float_class_inf || a.cls == float_class_zero) { + a.sign = sign; + return a; + } + /* Div by Inf */ + if (b.cls == float_class_inf) { + a.cls = float_class_zero; + a.sign = sign; + return a; + } + g_assert_not_reached(); +} + +float16 float16_div(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pb = float16_unpack_canonical(b, status); + decomposed_parts pr = 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 = float32_unpack_canonical(a, status); + decomposed_parts pb = float32_unpack_canonical(b, status); + decomposed_parts pr = 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 = float64_unpack_canonical(a, status); + decomposed_parts pb = float64_unpack_canonical(b, status); + decomposed_parts pr = 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) -/*---------------------------------------------------------------------------- -| 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 = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - bSign = extractFloat32Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - if ( bExp == 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 == 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 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 == 0 ) { - if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x7D; - aSig = ( aSig | 0x00800000 )<<7; - bSig = ( bSig | 0x00800000 )<<8; - if ( bSig <= ( aSig + aSig ) ) { - aSig >>= 1; - ++zExp; - } - zSig = ( ( (uint64_t) aSig )<<32 ) / bSig; - if ( ( zSig & 0x3F ) == 0 ) { - zSig |= ( (uint64_t) bSig * zSig != ( (uint64_t) aSig )<<32 ); - } - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} /*---------------------------------------------------------------------------- | 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; } -/*---------------------------------------------------------------------------- -| 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 = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - bSign = extractFloat64Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - if ( bExp == 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 == 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 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 == 0 ) { - if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x3FD; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - if ( bSig <= ( aSig + aSig ) ) { - aSig >>= 1; - ++zExp; - } - zSig = estimateDiv128To64( aSig, 0, bSig ); - if ( ( zSig & 0x1FF ) <= 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 |= ( rem1 != 0 ); - } - return roundAndPackFloat64(zSign, zExp, zSig, status); - -} /*---------------------------------------------------------------------------- | 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); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); From patchwork Mon Dec 11 12:56:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121399 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2760440qgn; Mon, 11 Dec 2017 05:02:17 -0800 (PST) X-Google-Smtp-Source: ACJfBot2lzdeMRcLkTiq8vYZf+/dk41qQ/NJ1KGgtCURrI3mstMDHrtBd/65D5iIJg+jLYcsnO6u X-Received: by 10.37.81.6 with SMTP id f6mr202238ybb.62.1512997337233; Mon, 11 Dec 2017 05:02:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997337; cv=none; d=google.com; s=arc-20160816; b=VQHyBa1keBOWBPhpSoORj/stFKH5YLtWxE40jiUWR26Dh8o1cdoctKwL4dREVIlO9y 5O2swAYutlE7+eqHZtpZhzJKnzdzjS50M82TdJulUXJpIVGTIFenfz9uugFq0yOC9mVK oGDEFqZqhVpW0ob75C2EXuPPxeqZL3gQ7M2w3cGPJuPXrCpW/4mjCd3OJVWLCH93sPTI ZtUaS2N7blFlpXYkzV3/aI6MG6Eu3XJ9g/1eFDWuh2qLI+v+TXYYCEgDxNrqJZ8Qs+0x NsTrAJFGOWne9/L9smoj9a4A89wLRRdDHhwvsmDeI6ADbfgTDcfJQMOV3IAYwKoL7jlg Kc8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=5t1m3meS4KvstcFcWlNP1dTrxEuOocu5zOe+N5EdqD8=; b=aN3YlcihksGPFwF2wJIjyh8uJvhGfEyUJRnJxSZs8SuYxQP0qVBpys1ol4xqcYmkRs qAiNYJKNo3URKYfJNIBWcKAnJLelqKnuHEiOWMTUGsn7aIs7Dm8JTZByaB/SbRb2RVkX 9kHTSR+dNB+aJhljUWm4hZUL5fhCvhnCOvUbyEwQNAKg20wWRXSFnAhbGGYlmQV9mbJE +SmQL2Yu0RarqcMZkf7Y/MQG58+ttWHsjQI9gDUv2W+rxBye/08B/SI80j6sN4mgYx91 wXKxg2nJ/W/Q4I7QS/OyOR6IltrAZ/aXgxsHU/fHqujoXjfkmJYnMIjemKQntSuInBXS vfUg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=S62GJzBs; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id k5si2850672ybm.46.2017.12.11.05.02.17 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:02:17 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=S62GJzBs; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52612 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONiq-0006Rq-Mf for patch@linaro.org; Mon, 11 Dec 2017 08:02:16 -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) 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-Received: by 10.223.139.149 with SMTP id o21mr289568wra.87.1512997040539; 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 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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- fpu/softfloat-specialize.h | 104 ------- fpu/softfloat.c | 756 +++++++++++++++++---------------------------- include/fpu/softfloat.h | 1 + 3 files changed, 286 insertions(+), 575 deletions(-) -- 2.15.1 Signed-off-by: Richard Henderson 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) } } -/*---------------------------------------------------------------------------- -| 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 = float32_is_quiet_nan(a, status); - aIsSignalingNaN = float32_is_signaling_nan(a, status); - bIsQuietNaN = float32_is_quiet_nan(b, status); - bIsSignalingNaN = float32_is_signaling_nan(b, status); - cIsQuietNaN = float32_is_quiet_nan(c, status); - cIsSignalingNaN = float32_is_signaling_nan(c, status); - - if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { - float_raise(float_flag_invalid, status); - } - - which = 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) } } -/*---------------------------------------------------------------------------- -| 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 = float64_is_quiet_nan(a, status); - aIsSignalingNaN = float64_is_signaling_nan(a, status); - bIsQuietNaN = float64_is_quiet_nan(b, status); - bIsSignalingNaN = float64_is_signaling_nan(b, status); - cIsQuietNaN = float64_is_quiet_nan(c, status); - cIsSignalingNaN = float64_is_signaling_nan(c, status); - - if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { - float_raise(float_flag_invalid, status); - } - - which = 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_parts a, decomposed_parts b, return a; } +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 == float_class_snan + || + b.cls == float_class_snan + || + c.cls == float_class_snan) { + s->float_exception_flags |= float_flag_invalid; + } + + if (s->default_nan_mode) { + a.cls = float_class_dnan; + } else { + switch (pickNaNMulAdd(a.cls == float_class_qnan, + a.cls == float_class_snan, + b.cls == float_class_qnan, + b.cls == float_class_snan, + c.cls == float_class_qnan, + c.cls == float_class_snan, + inf_zero, s)) { + case 0: + break; + case 1: + a = b; + break; + case 2: + a = c; + break; + case 3: + a.cls = float_class_dnan; + return a; + default: + g_assert_not_reached(); + } + + a.cls = float_class_msnan; + } + return a; +} + /* * Returns the result of adding the absolute values of the @@ -809,6 +853,247 @@ float64 float64_mul(float64 a, float64 b, float_status *status) return float64_round_pack_canonical(pr, status); } +/* + * 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 = ((1 << a.cls) | (1 << b.cls)) == + ((1 << float_class_inf) | (1 << float_class_zero)); + bool p_sign; + bool sign_flip = 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 >= float_class_qnan || + b.cls >= float_class_qnan || + c.cls >= float_class_qnan) { + return pick_nan_muladd_parts(a, b, c, inf_zero, s); + } + + if (inf_zero) { + s->float_exception_flags |= float_flag_invalid; + a.cls = float_class_dnan; + return a; + } + + if (flags & float_muladd_negate_c) { + c.sign ^= 1; + } + + p_sign = a.sign ^ b.sign; + + if (flags & float_muladd_negate_product) { + p_sign ^= 1; + } + + if (a.cls == float_class_inf || b.cls == float_class_inf) { + p_class = float_class_inf; + } else if (a.cls == float_class_zero || b.cls == float_class_zero) { + p_class = float_class_zero; + } else { + p_class = float_class_normal; + } + + if (c.cls == float_class_inf) { + if (p_class == float_class_inf && p_sign != c.sign) { + s->float_exception_flags |= float_flag_invalid; + a.cls = float_class_dnan; + } else { + a.cls = float_class_inf; + a.sign = c.sign ^ sign_flip; + } + return a; + } + + if (p_class == float_class_inf) { + a.cls = float_class_inf; + a.sign = p_sign ^ sign_flip; + return a; + } + + if (p_class == float_class_zero) { + if (c.cls == float_class_zero) { + if (p_sign != c.sign) { + p_sign = s->float_rounding_mode == float_round_down; + } + c.sign = p_sign; + } else if (flags & float_muladd_halve_result) { + c.exp -= 1; + } + c.sign ^= sign_flip; + return c; + } + + /* a & b should be normals now... */ + assert(a.cls == float_class_normal && + b.cls == float_class_normal); + + p_exp = a.exp + b.exp; + + /* Multiply of 2 62-bit numbers produces a (2*62) == 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 += 1; + } + + /* + add/sub */ + if (c.cls == float_class_zero) { + /* move binary point back to 62 */ + shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, &hi, &lo); + } else { + int exp_diff = p_exp - c.exp; + if (p_sign == c.sign) { + /* Addition */ + if (exp_diff <= 0) { + shift128RightJamming(hi, lo, + DECOMPOSED_BINARY_POINT - exp_diff, + &hi, &lo); + lo += c.frac; + p_exp = c.exp; + } else { + uint64_t c_hi, c_lo; + /* shift c to the same binary point as the product (124) */ + c_hi = c.frac >> 2; + c_lo = 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 += 1; + } + + } else { + /* Subtraction */ + uint64_t c_hi, c_lo; + /* make C binary point match product at bit 124 */ + c_hi = c.frac >> 2; + c_lo = 0; + + if (exp_diff <= 0) { + shift128RightJamming(hi, lo, -exp_diff, &hi, &lo); + if (exp_diff == 0 + && + (hi > c_hi || (hi == c_hi && lo >= c_lo))) { + sub128(hi, lo, c_hi, c_lo, &hi, &lo); + } else { + sub128(c_hi, c_lo, hi, lo, &hi, &lo); + p_sign ^= 1; + p_exp = 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 == 0 && lo == 0) { + a.cls = float_class_zero; + a.sign = s->float_rounding_mode == float_round_down; + a.sign ^= sign_flip; + return a; + } else { + int shift; + if (hi != 0) { + shift = clz64(hi); + } else { + shift = 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 -= 1; + if (shift >= 64) { + lo = lo << (shift - 64); + } else { + hi = (hi << shift) | (lo >> (64 - shift)); + lo = hi | ((lo << shift) != 0); + } + p_exp -= shift - 2; + } + } + } + + if (flags & float_muladd_halve_result) { + p_exp -= 1; + } + + /* finally prepare our result */ + a.cls = float_class_normal; + a.sign = p_sign ^ sign_flip; + a.exp = p_exp; + a.frac = lo; + + return a; +} + +float16 float16_muladd(float16 a, float16 b, float16 c, int flags, + float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pb = float16_unpack_canonical(b, status); + decomposed_parts pc = float16_unpack_canonical(c, status); + decomposed_parts pr = 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 = float32_unpack_canonical(a, status); + decomposed_parts pb = float32_unpack_canonical(b, status); + decomposed_parts pc = float32_unpack_canonical(c, status); + decomposed_parts pr = 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 = float64_unpack_canonical(a, status); + decomposed_parts pb = float64_unpack_canonical(b, status); + decomposed_parts pc = float64_unpack_canonical(c, status); + decomposed_parts pr = 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_status *status) return normalizeRoundAndPackFloat32(aSign ^ zSign, bExp, aSig, status); } -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the single-precision 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.) -*----------------------------------------------------------------------------*/ - -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 = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - c = float32_squash_input_denormal(c, status); - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - bSig = extractFloat32Frac(b); - bExp = extractFloat32Exp(b); - bSign = extractFloat32Sign(b); - cSig = extractFloat32Frac(c); - cExp = extractFloat32Exp(c); - cSign = extractFloat32Sign(c); - - infzero = ((aExp == 0 && aSig == 0 && bExp == 0xff && bSig == 0) || - (aExp == 0xff && aSig == 0 && bExp == 0 && bSig == 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 == 0xff) && aSig) || - ((bExp == 0xff) && bSig) || - ((cExp == 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 ^= 1; - } - - signflip = (flags & float_muladd_negate_result) ? 1 : 0; - - /* Work out the sign and type of the product */ - pSign = aSign ^ bSign; - if (flags & float_muladd_negate_product) { - pSign ^= 1; - } - pInf = (aExp == 0xff) || (bExp == 0xff); - pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0); - - if (cExp == 0xff) { - if (pInf && (pSign ^ cSign)) { - /* addition of opposite-signed infinities => InvalidOperation */ - 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 == 0) { - if (cSig == 0) { - /* Adding two exact zeroes */ - if (pSign == cSign) { - zSign = pSign; - } else if (status->float_rounding_mode == float_round_down) { - zSign = 1; - } else { - zSign = 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 == 0) { - normalizeFloat32Subnormal(cSig, &cExp, &cSig); - } - /* Subtract one to halve, and one again because roundAndPackFloat32 - * wants one less than the true exponent. - */ - cExp -= 2; - cSig = (cSig | 0x00800000) << 7; - return roundAndPackFloat32(cSign ^ signflip, cExp, cSig, status); - } - return packFloat32(cSign ^ signflip, cExp, cSig); - } - - if (aExp == 0) { - normalizeFloat32Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 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 = aExp + bExp - 0x7e; - aSig = (aSig | 0x00800000) << 7; - bSig = (bSig | 0x00800000) << 8; - pSig64 = (uint64_t)aSig * bSig; - if ((int64_t)(pSig64 << 1) >= 0) { - pSig64 <<= 1; - pExp--; - } - - zSign = pSign ^ signflip; - - /* Now pSig64 is the significand of the multiply, with the explicit bit in - * position 62. - */ - if (cExp == 0) { - if (!cSig) { - /* Throw out the special case of c being an exact zero now */ - shift64RightJamming(pSig64, 32, &pSig64); - pSig = pSig64; - if (flags & float_muladd_halve_result) { - pExp--; - } - return roundAndPackFloat32(zSign, pExp - 1, - pSig, status); - } - normalizeFloat32Subnormal(cSig, &cExp, &cSig); - } - - cSig64 = (uint64_t)cSig << (62 - 23); - cSig64 |= LIT64(0x4000000000000000); - expDiff = pExp - cExp; - - if (pSign == cSign) { - /* Addition */ - if (expDiff > 0) { - /* scale c to match p */ - shift64RightJamming(cSig64, expDiff, &cSig64); - zExp = pExp; - } else if (expDiff < 0) { - /* scale p to match c */ - shift64RightJamming(pSig64, -expDiff, &pSig64); - zExp = cExp; - } else { - /* no scaling needed */ - zExp = cExp; - } - /* Add significands and make sure explicit bit ends up in posn 62 */ - zSig64 = pSig64 + cSig64; - if ((int64_t)zSig64 < 0) { - shift64RightJamming(zSig64, 1, &zSig64); - } else { - zExp--; - } - } else { - /* Subtraction */ - if (expDiff > 0) { - shift64RightJamming(cSig64, expDiff, &cSig64); - zSig64 = pSig64 - cSig64; - zExp = pExp; - } else if (expDiff < 0) { - shift64RightJamming(pSig64, -expDiff, &pSig64); - zSig64 = cSig64 - pSig64; - zExp = cExp; - zSign ^= 1; - } else { - zExp = pExp; - if (cSig64 < pSig64) { - zSig64 = pSig64 - cSig64; - } else if (pSig64 < cSig64) { - zSig64 = cSig64 - pSig64; - zSign ^= 1; - } else { - /* Exact zero */ - zSign = signflip; - if (status->float_rounding_mode == float_round_down) { - zSign ^= 1; - } - return packFloat32(zSign, 0, 0); - } - } - --zExp; - /* Normalize to put the explicit bit back into bit 62. */ - shiftcount = countLeadingZeros64(zSig64) - 1; - zSig64 <<= shiftcount; - zExp -= shiftcount; - } - if (flags & float_muladd_halve_result) { - zExp--; - } - - shift64RightJamming(zSig64, 32, &zSig64); - return roundAndPackFloat32(zSign, zExp, zSig64, status); -} - /*---------------------------------------------------------------------------- | Returns the square root of the single-precision floating-point value `a'. @@ -4262,252 +4322,6 @@ float64 float64_rem(float64 a, float64 b, float_status *status) } -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the double-precision 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.) -*----------------------------------------------------------------------------*/ - -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 = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - c = float64_squash_input_denormal(c, status); - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - bSig = extractFloat64Frac(b); - bExp = extractFloat64Exp(b); - bSign = extractFloat64Sign(b); - cSig = extractFloat64Frac(c); - cExp = extractFloat64Exp(c); - cSign = extractFloat64Sign(c); - - infzero = ((aExp == 0 && aSig == 0 && bExp == 0x7ff && bSig == 0) || - (aExp == 0x7ff && aSig == 0 && bExp == 0 && bSig == 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 == 0x7ff) && aSig) || - ((bExp == 0x7ff) && bSig) || - ((cExp == 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 ^= 1; - } - - signflip = (flags & float_muladd_negate_result) ? 1 : 0; - - /* Work out the sign and type of the product */ - pSign = aSign ^ bSign; - if (flags & float_muladd_negate_product) { - pSign ^= 1; - } - pInf = (aExp == 0x7ff) || (bExp == 0x7ff); - pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0); - - if (cExp == 0x7ff) { - if (pInf && (pSign ^ cSign)) { - /* addition of opposite-signed infinities => InvalidOperation */ - 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 == 0) { - if (cSig == 0) { - /* Adding two exact zeroes */ - if (pSign == cSign) { - zSign = pSign; - } else if (status->float_rounding_mode == float_round_down) { - zSign = 1; - } else { - zSign = 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 == 0) { - normalizeFloat64Subnormal(cSig, &cExp, &cSig); - } - /* Subtract one to halve, and one again because roundAndPackFloat64 - * wants one less than the true exponent. - */ - cExp -= 2; - cSig = (cSig | 0x0010000000000000ULL) << 10; - return roundAndPackFloat64(cSign ^ signflip, cExp, cSig, status); - } - return packFloat64(cSign ^ signflip, cExp, cSig); - } - - if (aExp == 0) { - normalizeFloat64Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 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 = aExp + bExp - 0x3fe; - aSig = (aSig | LIT64(0x0010000000000000))<<10; - bSig = (bSig | LIT64(0x0010000000000000))<<11; - mul64To128(aSig, bSig, &pSig0, &pSig1); - if ((int64_t)(pSig0 << 1) >= 0) { - shortShift128Left(pSig0, pSig1, 1, &pSig0, &pSig1); - pExp--; - } - - zSign = pSign ^ signflip; - - /* Now [pSig0:pSig1] is the significand of the multiply, with the explicit - * bit in position 126. - */ - if (cExp == 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 = cSig << (126 - 64 - 52); - cSig1 = 0; - cSig0 |= LIT64(0x4000000000000000); - expDiff = pExp - cExp; - - if (pSign == cSign) { - /* Addition */ - if (expDiff > 0) { - /* scale c to match p */ - shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); - zExp = pExp; - } else if (expDiff < 0) { - /* scale p to match c */ - shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); - zExp = cExp; - } else { - /* no scaling needed */ - zExp = 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 = pExp; - } else if (expDiff < 0) { - shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); - sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); - zExp = cExp; - zSign ^= 1; - } else { - zExp = 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 ^= 1; - } else { - /* Exact zero */ - zSign = signflip; - if (status->float_rounding_mode == float_round_down) { - zSign ^= 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 = countLeadingZeros64(zSig0) - 1; - shortShift128Left(zSig0, zSig1, shiftcount, &zSig0, &zSig1); - if (zSig1) { - zSig0 |= 1; - } - zExp -= shiftcount; - } else { - shiftcount = countLeadingZeros64(zSig1); - if (shiftcount == 0) { - zSig0 = (zSig1 >> 1) | (zSig1 & 1); - zExp -= 63; - } else { - shiftcount--; - zSig0 = zSig1 << shiftcount; - zExp -= (shiftcount + 64); - } - } - if (flags & float_muladd_halve_result) { - zExp--; - } - return roundAndPackFloat64(zSign, zExp, zSig0, status); - } -} /*---------------------------------------------------------------------------- | 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 *status); float16 float16_div(float16, float16, float_status *status); int float16_is_quiet_nan(float16, float_status *status); From patchwork Mon Dec 11 12:57:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121404 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2765854qgn; Mon, 11 Dec 2017 05:06:13 -0800 (PST) X-Google-Smtp-Source: ACJfBov5TtKGW8xd2U+Kn5q5TpeQSwb/V7k9L/OBg85ozExJfNAoaPg4NGUQAlKTG3BGkMtEbHN6 X-Received: by 10.37.199.193 with SMTP id w184mr197358ybe.107.1512997573230; Mon, 11 Dec 2017 05:06:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997573; cv=none; d=google.com; s=arc-20160816; b=FZEu8RbHxxItSwLNjBwhulVdicaQ+0fMsz3KachHWM9o/iFcVEtHFNst6JLreuQy8k HFL9GjD0h6S8c0yFrCcCiSYUZ4Nx2U3Zu8pzCpJ/sk09jl0q8Apkjfpyy17P4KyCQbEI VTLmiRqpwAhRloAvBYKOrqsZnTsen/LXN7qNW6o/nj+14fQVY+tV7PA8VAoRUu4qYlNz /E/JeRLT5jU4FblouTHJefN2s18C/c3wtLkRXQjRa1nxMmoIirp+0NDkh6WjkWG2nSxn VvBNkHMO5US1dfRe3vc82d8kHHc9hY3DuzjBlCwm48hvsiFdsemxtAQ1MeBFvpdARUFv N1Cg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=TqLZ4logtnH/8CEr18id48c5CLf/Gq62Mao5MSosRfE=; b=ZCw0aRrBW9d0y+eNGT6Cnk36Qdu3a9HlCFA968Olp0W2k1BMGVbURIgqiWiBembVU7 dIDTJmBd8rKzAPRuknpJzDKt3nCyDIifABrcv7hmNinNgt5FpuqrZGts6btZbMwIuMPu wCLWssdqm2KHJuDWMb6anigv4oIrS5e7Jh9YZ586KucGPVwbeZWd6dy1lYKNd4YEWUG2 yJ5bdk769+eXcnVpTLQYxa5KyyWG8UMXdTF5dNBL7nP3gwVuO6XVRxiyRI+ok0o1nyHo GdHM40p6WaYqv+IOW85S0YrhKEPkYovl/7Th6Pzs0rNwm4p/qfN3kQJNAxCP1+OI/V3r 02lQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=NnY5uvU0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id t202si2934806ywg.226.2017.12.11.05.06.13 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:06:13 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=NnY5uvU0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52623 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONme-000363-NF for patch@linaro.org; Mon, 11 Dec 2017 08:06:12 -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) 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-Received: by 10.28.62.5 with SMTP id l5mr713402wma.47.1512997039758; Mon, 11 Dec 2017 04:57:19 -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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- fpu/softfloat.c | 304 ++++++++++++++++++++---------------------------- include/fpu/softfloat.h | 1 + 2 files changed, 130 insertions(+), 175 deletions(-) -- 2.15.1 Signed-off-by: Richard Henderson 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_status *status) return float64_round_pack_canonical(pr, status); } +/* + * 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 = s->default_nan_mode ? float_class_dnan : float_class_msnan; + s->float_exception_flags |= 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 >= DECOMPOSED_BINARY_POINT) { + /* already integral */ + break; + } + if (a.exp < 0) { + bool one; + /* all fractional */ + s->float_exception_flags |= float_flag_inexact; + switch (rounding_mode) { + case float_round_nearest_even: + one = a.exp == -1 && a.frac > DECOMPOSED_IMPLICIT_BIT; + break; + case float_round_ties_away: + one = a.exp == -1 && a.frac >= DECOMPOSED_IMPLICIT_BIT; + break; + case float_round_to_zero: + one = false; + break; + case float_round_up: + one = !a.sign; + break; + case float_round_down: + one = a.sign; + break; + default: + g_assert_not_reached(); + } + + if (one) { + a.frac = DECOMPOSED_IMPLICIT_BIT; + a.exp = 0; + } else { + a.cls = float_class_zero; + } + } else { + uint64_t frac_lsb, frac_lsbm1, round_mask, roundeven_mask, inc; + + frac_lsb = DECOMPOSED_IMPLICIT_BIT >> a.exp; + frac_lsbm1 = frac_lsb >> 1; + roundeven_mask = (frac_lsb - 1) | frac_lsb; + round_mask = roundeven_mask >> 1; + + switch (rounding_mode) { + case float_round_nearest_even: + inc = ((a.frac & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0); + break; + case float_round_ties_away: + inc = frac_lsbm1; + break; + case float_round_to_zero: + inc = 0; + break; + case float_round_up: + inc = a.sign ? 0 : round_mask; + break; + case float_round_down: + inc = a.sign ? round_mask : 0; + break; + default: + g_assert_not_reached(); + } + + if (a.frac & round_mask) { + s->float_exception_flags |= float_flag_inexact; + a.frac += inc; + a.frac &= ~round_mask; + if (a.frac & DECOMPOSED_OVERFLOW_BIT) { + a.frac >>= 1; + a.exp++; + } + } + } + break; + default: + g_assert_not_reached(); + } + return a; +} + +float16 float16_round_to_int(float16 a, float_status *s) +{ + decomposed_parts pa = float16_unpack_canonical(a, s); + decomposed_parts pr = 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 = float32_unpack_canonical(a, s); + decomposed_parts pr = 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 = float64_unpack_canonical(a, s); + decomposed_parts pr = 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 = float64_unpack_canonical(a, s); + decomposed_parts pr = 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) } -/*---------------------------------------------------------------------------- -| 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 = float32_squash_input_denormal(a, status); - - aExp = extractFloat32Exp( a ); - if ( 0x96 <= aExp ) { - if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { - return propagateFloat32NaN(a, a, status); - } - return a; - } - if ( aExp <= 0x7E ) { - if ( (uint32_t) ( float32_val(a)<<1 ) == 0 ) return a; - status->float_exception_flags |= float_flag_inexact; - aSign = extractFloat32Sign( a ); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { - return packFloat32( aSign, 0x7F, 0 ); - } - break; - case float_round_ties_away: - if (aExp == 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 = 1; - lastBitMask <<= 0x96 - aExp; - roundBitsMask = lastBitMask - 1; - z = float32_val(a); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - z += lastBitMask>>1; - if ((z & roundBitsMask) == 0) { - z &= ~lastBitMask; - } - break; - case float_round_ties_away: - z += lastBitMask >> 1; - break; - case float_round_to_zero: - break; - case float_round_up: - if (!extractFloat32Sign(make_float32(z))) { - z += roundBitsMask; - } - break; - case float_round_down: - if (extractFloat32Sign(make_float32(z))) { - z += roundBitsMask; - } - break; - default: - abort(); - } - z &= ~ roundBitsMask; - if (z != float32_val(a)) { - status->float_exception_flags |= float_flag_inexact; - } - return make_float32(z); - -} - - /*---------------------------------------------------------------------------- @@ -4140,99 +4187,6 @@ float128 float64_to_float128(float64 a, float_status *status) } -/*---------------------------------------------------------------------------- -| 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 = float64_squash_input_denormal(a, status); - - aExp = extractFloat64Exp( a ); - if ( 0x433 <= aExp ) { - if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { - return propagateFloat64NaN(a, a, status); - } - return a; - } - if ( aExp < 0x3FF ) { - if ( (uint64_t) ( float64_val(a)<<1 ) == 0 ) return a; - status->float_exception_flags |= float_flag_inexact; - aSign = extractFloat64Sign( a ); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { - return packFloat64( aSign, 0x3FF, 0 ); - } - break; - case float_round_ties_away: - if (aExp == 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( 0x3FF0000000000000 )); - } - return packFloat64( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x433 - aExp; - roundBitsMask = lastBitMask - 1; - z = float64_val(a); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - z += lastBitMask >> 1; - if ((z & roundBitsMask) == 0) { - z &= ~lastBitMask; - } - break; - case float_round_ties_away: - z += lastBitMask >> 1; - break; - case float_round_to_zero: - break; - case float_round_up: - if (!extractFloat64Sign(make_float64(z))) { - z += roundBitsMask; - } - break; - case float_round_down: - if (extractFloat64Sign(make_float64(z))) { - z += roundBitsMask; - } - break; - default: - abort(); - } - z &= ~ roundBitsMask; - if (z != float64_val(a)) { - status->float_exception_flags |= float_flag_inexact; - } - return make_float64(z); - -} - -float64 float64_trunc_to_int(float64 a, float_status *status) -{ - int oldmode; - float64 res; - oldmode = status->float_rounding_mode; - status->float_rounding_mode = float_round_to_zero; - res = float64_round_to_int(a, status); - status->float_rounding_mode = oldmode; - return res; -} - /*---------------------------------------------------------------------------- | 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. *----------------------------------------------------------------------------*/ +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); From patchwork Mon Dec 11 12:57:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121403 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2764896qgn; Mon, 11 Dec 2017 05:05:28 -0800 (PST) X-Google-Smtp-Source: ACJfBouw1rLnvWTCVQuZHgS26oajn+3jwdkrjt8UnYq57L3JZ28pOKIMi954/MtOvCtB1jNDiTg7 X-Received: by 10.129.72.16 with SMTP id v16mr228036ywa.340.1512997528311; Mon, 11 Dec 2017 05:05:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997528; cv=none; d=google.com; s=arc-20160816; b=ALj2J9DWRdN4PpALkEsqOQyVLo8xSzwyHjt4llZ6lWvxZHky1v1+4vYb6ZUGd7H0Ur NyL/IuJ5LiLKDrQskKL0Cz4GrIKu9i5BJRbwrdf4rPBz0jSj+2wkV8Gi4IcUwZAb9wtU 0ucB1PHXUTvygOwax7GJ7rOOxth0vGmwNd8SuYoiGLsYRoHJkwklt/JF02IGuufWUWw9 uLuqeiHr5LEt6hyLqVzJd2dPQRwkh693BdEqfOrjSqhYBQmaWgj7HMHz7GdM+RkE22sB 5Cp+p+ai+VZ14KcAWlv2aUK39bNjfou+Pj31ebRpgl5lwD7FLitLH3yeU0ERhyLXPHNY mQLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=DnduGGMDDtkT6xEtdJHrrkG0FqNJROwpla/lkXr0lpI=; b=V7P+E+1v0BqvcYb1AbRyFJBks8Jhwpeis2u9/UQROVCmUJM4cj94vfUV9tGyBVGeCu Wrmia6oJhzXWSYi3H2+ws3zBfTEPDdq6dVbWNeX3ulqeHnSbpNW6T7nsV1bcVBTLKRQr xmyY9KRCMe9vhjaXHbdayj19cMgFPx9gbCm8ciPcn8jcusEpZwBCWa+N6RYZssZwh/O3 tSXIvhs+VIgsJecaMNE65nrOIsF7VOMScM8xp5MXN0mENFTBAD/O0SaWssKl8433CLb4 d0lqjp28dODL5mHtKbTIumlc0GqBY0ML4aO9cPZWW5xSJA8+nevZDoIKhUlkjTF6vyLm 6jeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=gAE+6ur7; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id 132si2912644ybs.517.2017.12.11.05.05.28 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:05:28 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=gAE+6ur7; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52625 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONlv-0003Es-MN for patch@linaro.org; Mon, 11 Dec 2017 08:05:27 -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) 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-Received: by 10.28.12.14 with SMTP id 14mr710564wmm.49.1512997043767; 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 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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- fpu/softfloat.c | 1000 ++++++++++------------------------------------- include/fpu/softfloat.h | 13 + 2 files changed, 224 insertions(+), 789 deletions(-) -- 2.15.1 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_status *s) return float64_round_pack_canonical(pr, s); } +/*---------------------------------------------------------------------------- +| 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, the +| 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 = p.frac >> (DECOMPOSED_BINARY_POINT - p.exp); + } else if (p.exp < 64) { + r = p.frac << (p.exp - DECOMPOSED_BINARY_POINT); + } else { + s->float_exception_flags |= float_flag_invalid; + r = 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 = int64_pack_decomposed(p, s); + if (r < INT16_MIN) { + s->float_exception_flags |= float_flag_invalid; + return INT16_MIN; + } else if (r > INT16_MAX) { + s->float_exception_flags |= float_flag_invalid; + return INT16_MAX; + } + return r; +} + +static int32_t int32_pack_decomposed(decomposed_parts p, float_status *s) +{ + int64_t r = int64_pack_decomposed(p, s); + if (r < INT32_MIN) { + s->float_exception_flags |= float_flag_invalid; + return INT32_MIN; + } else if (r > INT32_MAX) { + s->float_exception_flags |= 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_status *s) \ +{ \ + decomposed_parts pa = float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr = 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 = float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr = 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, the +| largest unsigned integer is returned. If the 'a' is negative, the result +| is rounded and zero is returned; values that do not round to zero will +| raise the inexact exception flag. +*----------------------------------------------------------------------------*/ + +static uint64_t 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 = 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 = 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_status *s) \ +{ \ + decomposed_parts pa = float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr = 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 = float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr = 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_status *status) return normalizeRoundAndPackFloat128(0, 0x406E, a, 0, status); } -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32_t float32_to_int32(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64; - - a = float32_squash_input_denormal(a, status); - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( ( aExp == 0xFF ) && aSig ) aSign = 0; - if ( aExp ) aSig |= 0x00800000; - shiftCount = 0xAF - aExp; - aSig64 = aSig; - aSig64 <<= 32; - if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64 ); - return roundAndPackInt32(aSign, aSig64, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int32_t float32_to_int32_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - int32_t z; - a = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0x9E; - if ( 0 <= shiftCount ) { - if ( float32_val(a) != 0xCF000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; - } - return (int32_t) 0x80000000; - } - else if ( aExp <= 0x7E ) { - if (aExp | aSig) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - aSig = ( aSig | 0x00800000 )<<8; - z = aSig>>( - shiftCount ); - if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { - status->float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `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 = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0x8E; - if ( 0 <= shiftCount ) { - if ( float32_val(a) != 0xC7000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return 0x7FFF; - } - } - return (int32_t) 0xffff8000; - } - else if ( aExp <= 0x7E ) { - if ( aExp | aSig ) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - shiftCount -= 0x10; - aSig = ( aSig | 0x00800000 )<<8; - z = aSig>>( - shiftCount ); - if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { - status->float_exception_flags |= float_flag_inexact; - } - if ( aSign ) { - z = - z; - } - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `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, the -| 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 = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = 0xBE - aExp; - if ( shiftCount < 0 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - if ( aExp ) aSig |= 0x00800000; - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); - return roundAndPackInt64(aSign, aSig64, aSigExtra, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| 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. -*----------------------------------------------------------------------------*/ - -uint64_t float32_to_uint64(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64, aSigExtra; - a = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = 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 = 0xBE - aExp; - if (aExp) { - aSig |= 0x00800000; - } - if (shiftCount < 0) { - float_raise(float_flag_invalid, status); - return LIT64(0xFFFFFFFFFFFFFFFF); - } - - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra); - return roundAndPackUint64(aSign, aSig64, aSigExtra, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. 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 flag. -*----------------------------------------------------------------------------*/ -uint64_t float32_to_uint64_round_to_zero(float32 a, float_status *status) -{ - signed char current_rounding_mode = status->float_rounding_mode; - set_float_rounding_mode(float_round_to_zero, status); - int64_t v = float32_to_uint64(a, status); - set_float_rounding_mode(current_rounding_mode, status); - return v; -} -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `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. -*----------------------------------------------------------------------------*/ - -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 = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0xBE; - if ( 0 <= shiftCount ) { - if ( float32_val(a) != 0xDF000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - else if ( aExp <= 0x7E ) { - if (aExp | aSig) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - aSig64 = aSig | 0x00800000; - aSig64 <<= 40; - z = aSig64>>( - shiftCount ); - if ( (uint64_t) ( aSig64<<( shiftCount & 63 ) ) ) { - status->float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} /*---------------------------------------------------------------------------- | Returns the result of converting the single-precision floating-point value @@ -3500,289 +3397,59 @@ int float32_le_quiet(float32 a, float32 b, float_status *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 = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 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 = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - av = float32_val(a); - bv = float32_val(b); - if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 ); - return ( av != bv ) && ( aSign ^ ( av < bv ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point values `a' and `b' cannot -| 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 = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 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 value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32_t float64_to_int32(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig; - a = float64_squash_input_denormal(a, status); - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; - if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x42C - aExp; - if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32(aSign, aSig, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int32_t 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 = float64_squash_input_denormal(a, status); - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( 0x41E < aExp ) { - if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FF ) { - if (aExp || aSig) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x433 - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = aSig; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise(float_flag_invalid, status); - return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<float_exception_flags |= float_flag_inexact; - } - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `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 = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( 0x40E < aExp ) { - if ( ( aExp == 0x7FF ) && aSig ) { - aSign = 0; - } - goto invalid; - } - else if ( aExp < 0x3FF ) { - if ( aExp || aSig ) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x433 - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = aSig; - if ( aSign ) { - z = - 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 |= float_flag_inexact; - } - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `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, the -| largest integer with the same sign as `a' is returned. +| Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -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 = float64_squash_input_denormal(a, status); + flag aSign, bSign; + uint32_t av, bv; + a = float32_squash_input_denormal(a, status); + b = float32_squash_input_denormal(b, status); - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x433 - aExp; - if ( shiftCount <= 0 ) { - if ( 0x43E < aExp ) { + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 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 == 0x7FF ) - && ( aSig != LIT64( 0x0010000000000000 ) ) ) - ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (int64_t) LIT64( 0x8000000000000000 ); } - aSigExtra = 0; - aSig <<= - shiftCount; - } - else { - shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra ); + return 0; } - return roundAndPackInt64(aSign, aSig, aSigExtra, status); + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + av = float32_val(a); + bv = float32_val(b); + if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 ); + return ( av != bv ) && ( aSign ^ ( av < bv ) ); } /*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `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' cannot +| 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. *----------------------------------------------------------------------------*/ -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 = float64_squash_input_denormal(a, status); + a = float32_squash_input_denormal(a, status); + b = float32_squash_input_denormal(b, status); - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); - shiftCount = aExp - 0x433; - if ( 0 <= shiftCount ) { - if ( 0x43E <= aExp ) { - if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) { - float_raise(float_flag_invalid, status); - if ( ! aSign - || ( ( aExp == 0x7FF ) - && ( aSig != LIT64( 0x0010000000000000 ) ) ) - ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - z = aSig<float_exception_flags |= float_flag_inexact; - } - return 0; - } - z = aSig>>( - shiftCount ); - if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) { - status->float_exception_flags |= float_flag_inexact; + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 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 = - z; - return z; - + return 0; } + /*---------------------------------------------------------------------------- | Returns the result of converting the double-precision floating-point value | `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); } -uint32_t float32_to_uint32(float32 a, float_status *status) -{ - int64_t v; - uint32_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float32_to_int64(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffffffff) { - res = 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 = get_float_exception_flags(status); - - v = float32_to_int64_round_to_zero(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffffffff) { - res = 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 = get_float_exception_flags(status); - - v = float32_to_int32(a, status); - if (v < -0x8000) { - res = -0x8000; - } else if (v > 0x7fff) { - res = 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 = get_float_exception_flags(status); - - v = float32_to_int32(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffff) { - res = 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 = get_float_exception_flags(status); - - v = float32_to_int64_round_to_zero(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffff) { - res = 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 = get_float_exception_flags(status); - - v = float64_to_uint64(a, status); - if (v > 0xffffffff) { - res = 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint32_t float64_to_uint32_round_to_zero(float64 a, float_status *status) -{ - uint64_t v; - uint32_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float64_to_uint64_round_to_zero(a, status); - if (v > 0xffffffff) { - res = 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -int16_t float64_to_int16(float64 a, float_status *status) -{ - int64_t v; - int16_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float64_to_int32(a, status); - if (v < -0x8000) { - res = -0x8000; - } else if (v > 0x7fff) { - res = 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 = get_float_exception_flags(status); - - v = float64_to_int32(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffff) { - res = 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 = get_float_exception_flags(status); - - v = float64_to_int64_round_to_zero(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffff) { - res = 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 value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. If the conversion overflows, the -| largest unsigned integer is returned. If 'a' is negative, the value is -| rounded and zero is returned; negative values that do not round to zero -| will raise the inexact exception. -*----------------------------------------------------------------------------*/ - -uint64_t float64_to_uint64(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, aSigExtra; - a = float64_squash_input_denormal(a, status); - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = 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 |= LIT64(0x0010000000000000); - } - shiftCount = 0x433 - aExp; - if (shiftCount <= 0) { - if (0x43E < aExp) { - float_raise(float_flag_invalid, status); - return LIT64(0xFFFFFFFFFFFFFFFF); - } - aSigExtra = 0; - aSig <<= -shiftCount; - } else { - shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra); - } - return roundAndPackUint64(aSign, aSig, aSigExtra, status); -} -uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *status) -{ - signed char current_rounding_mode = status->float_rounding_mode; - set_float_rounding_mode(float_round_to_zero, status); - uint64_t v = float64_to_uint64(a, status); - set_float_rounding_mode(current_rounding_mode, status); - return v; -} #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); /*---------------------------------------------------------------------------- | Software half-precision operations. From patchwork Mon Dec 11 12:57:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121412 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2773059qgn; Mon, 11 Dec 2017 05:12:14 -0800 (PST) X-Google-Smtp-Source: ACJfBou6yd+fga9/SmxV3liQ+TkUnnq1BLw5W+2QEuEJuNo2XHPlC4fuAI4F/vthDdpgHqejztv/ X-Received: by 10.13.226.209 with SMTP id l200mr242083ywe.103.1512997934090; Mon, 11 Dec 2017 05:12:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997934; cv=none; d=google.com; s=arc-20160816; b=JIDV7DPGO6c9sjqF3hZpXIbPaLc46+qLPIyxrLdWNHGVCxwIePTJW+om7V4m+6i7w/ sqEyYF3sm9QBkUfVD46ISx44r+Ybc+Pe/3hRpngiAmilCC7UHM9/OOvbuK1s+RgY7SJ+ cgJJVqBg59SHacJX4jy9ZwT//KC4LWY0gTXOij5GnRubW6SoAN84Nw9zj278WId9iqNg vq3n4zMZQiukAbZGJ1cepHNYKXOiAh5AuySl2YcyP/KUibo0LGoRL2nSL/kRMhD5ho2j oPJCwnek7s1HWOT+BjkhmSoK6uomDiSkYxifz8sxIV08zuYBQx70hc01DXT58QtvdJH3 57Pw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=iLulQbh+zCpfdAk5sN6+a/SsAaDl1Wqx538JpGE1FBU=; b=ItyUHbQZlrxsslP9IFALUWg/dTwNP4z9JJEOcBszFxgNqkrXqVDrr8xa82L3BZIcyy 8yY/1nn7HT4ZFuJ7BsIw4U+z+tECNEciv61RVeJ7Db7EzsNektkZatYVUf6wCC1JhMzM pmHhJcrZknj8tMTl/jruZqqMJGh7W5BzKV7c1r/blF9+P9Tp3tZsaa4Itz/PlFMuoUAX 1skS7+rr+QG/k1sMfi0BzEZcYdSytpAPm5cvAnyPkOEdjrSZUNcN7cVTxI91x5BkmWfd CQ6qbyYOX/lFvLz7eurK17MogZLAJLwpoTmwrFRqmc/SVV6KXbsvYFelgb7ELmXjbkP/ omqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=HKR3gQvs; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id d65si3007837ybf.218.2017.12.11.05.12.13 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:12:14 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=HKR3gQvs; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52805 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONsT-0002Y1-Gv for patch@linaro.org; Mon, 11 Dec 2017 08:12:13 -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) 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-Received: by 10.223.176.113 with SMTP id g46mr333830wra.267.1512997595854; Mon, 11 Dec 2017 05:06:35 -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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- fpu/softfloat.c | 358 +++++++++++++++++++++++++----------------------- include/fpu/softfloat.h | 30 ++-- 2 files changed, 195 insertions(+), 193 deletions(-) -- 2.15.1 Reviewed-by: Richard Henderson 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) #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, 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. -*----------------------------------------------------------------------------*/ +/* + * Returns the result of converting the floating-point value `a' to + * the unsigned integer format. The conversion is performed according + * to the IEC/IEEE Standard for Binary Floating-Point + * Arithmetic---which means in particular that the conversion is + * rounded according to the current rounding mode. If `a' is a NaN, + * the largest unsigned integer is returned. Otherwise, if the + * conversion overflows, the largest unsigned integer is returned. If + * the 'a' is negative, the result is rounded and zero is returned; + * values that do not round to zero will raise the inexact exception + * flag. + */ static uint64_t uint64_pack_decomposed(decomposed_parts p, float_status *s) { @@ -1433,6 +1434,7 @@ static uint64_t uint64_pack_decomposed(decomposed_parts p, float_status *s) return 0; case float_class_normal: if (p.sign) { + s->float_exception_flags |= float_flag_invalid; return 0; } if (p.exp < DECOMPOSED_BINARY_POINT) { @@ -1440,6 +1442,7 @@ static uint64_t uint64_pack_decomposed(decomposed_parts p, float_status *s) } else if (p.exp < 64) { return p.frac << (p.exp - DECOMPOSED_BINARY_POINT); } else { + s->float_exception_flags |= float_flag_invalid; return UINT64_MAX; } default: @@ -1450,13 +1453,21 @@ static uint64_t uint64_pack_decomposed(decomposed_parts p, float_status *s) static uint16_t uint16_pack_decomposed(decomposed_parts p, float_status *s) { uint64_t r = uint64_pack_decomposed(p, s); - return r > UINT16_MAX ? UINT16_MAX : r; + if (r > UINT16_MAX) { + s->float_exception_flags |= float_flag_invalid; + r = UINT16_MAX; + } + return r; } static uint32_t uint32_pack_decomposed(decomposed_parts p, float_status *s) { uint64_t r = uint64_pack_decomposed(p, s); - return r > UINT32_MAX ? UINT32_MAX : r; + if (r > UINT32_MAX) { + s->float_exception_flags |= float_flag_invalid; + r = UINT32_MAX; + } + return r; } #define FLOAT_TO_UINT(fsz, isz) \ @@ -1489,6 +1500,168 @@ FLOAT_TO_UINT(64, 64) #undef FLOAT_TO_UINT +/* + * 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 == 0) { + r.cls = float_class_zero; + } else if (a == (1ULL << 63)) { + r.cls = float_class_normal; + r.sign = true; + r.frac = DECOMPOSED_IMPLICIT_BIT; + r.exp = 63; + } else { + uint64_t f; + if (a < 0) { + f = -a; + r.sign = true; + } else { + f = a; + r.sign = false; + } + int shift = clz64(f) - 1; + r.cls = float_class_normal; + r.exp = (DECOMPOSED_BINARY_POINT - shift); + r.frac = f << shift; + } + + return r; +} + +float16 int64_to_float16(int64_t a, float_status *status) +{ + decomposed_parts pa = 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 = 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 = 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 == 0) { + r.cls = float_class_zero; + } else { + int spare_bits = clz64(a) - 1; + r.sign = false; + r.cls = float_class_normal; + r.exp = DECOMPOSED_BINARY_POINT - spare_bits; + if (spare_bits < 0) { + shift64RightJamming(a, -spare_bits, &a); + r.frac = a; + } else { + r.frac = a << spare_bits; + } + } + + return r; +} + +float16 uint64_to_float16(uint64_t a, float_status *status) +{ + decomposed_parts pa = 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 = 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 = 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 zSign, int32_t zExp, } -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the single-precision floating-point format. The conversion is performed -| 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 == 0 ) return float32_zero; - if ( a == (int32_t) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); - zSign = ( a < 0 ); - return normalizeRoundAndPackFloat32(zSign, 0x9C, zSign ? -a : a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the double-precision floating-point format. The conversion is performed -| 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 == 0 ) return float64_zero; - zSign = ( a < 0 ); - absA = zSign ? - a : a; - shiftCount = countLeadingZeros32( absA ) + 21; - zSig = absA; - return packFloat64( zSign, 0x432 - shiftCount, zSig<= 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 += 7; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<= 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 performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 uint64_to_float64(uint64_t a, float_status *status) -{ - int exp = 0x43C; - int shiftcount; - - if (a == 0) { - return float64_zero; - } - - shiftcount = countLeadingZeros64(a) - 1; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<= 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 performed @@ -6705,19 +6732,6 @@ int float128_unordered_quiet(float128 a, float128 b, float_status *status) return 0; } -/* 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 *status); float64 uint64_to_float64(uint64_t, float_status *status); float128 uint64_to_float128(uint64_t, float_status *status); -/* 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 *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); +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); /*---------------------------------------------------------------------------- | Software half-precision operations. From patchwork Mon Dec 11 12:57:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121406 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2769074qgn; Mon, 11 Dec 2017 05:08:48 -0800 (PST) X-Google-Smtp-Source: ACJfBotaOBSiSm7tNlCkjR779Yfubelz+M774SkPfXnKr3VZLG17spJnpALy8z+hTmPoAjAvOJGw X-Received: by 10.37.160.200 with SMTP id i8mr220721ybm.118.1512997728722; Mon, 11 Dec 2017 05:08:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997728; cv=none; d=google.com; s=arc-20160816; b=qOa8gt9woOWa1FwkMP4VkWDLcMHss6morguoPoXAL7P/uwDckYH6wg4vSSjA3F1fBr jplL1dVxhciDy9ZTkI065bz9gUevCeSgAaEbEjIRwZ5IE+qdNwMSB+mbNWMjdx9ni0tR kn2ad361eHxVnKM+0rV89lmyybnQlw19TrEA5NPhUwqVOW1SVZ+ta2QIF0/sTi/cp8sI cOd1Q4/WbjtkxnHOZJspahw1GqTgspg3oiJCuGDuVjkKTbAN675rn9ixuT+aSa63nhDe 0LKHb1Ib0DY9TyJs76hu9HcYCRTvw4ZJfpPOBXFEMuqWots6f2f8yONoP2iyQ8UolkTH 3NpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=lZsn0E0fKsWEEcIFtvDvOYzz27C6Ibj9Yt+0VPbKhro=; b=XCnAIDjT0C5R0QBzt8VYXFe35vx4bm/jbQSpBuPpj46wMLJjmm6h4UA6pWcEVUnO4d bIbHl91dM8lW1koY3TkAmAYsim11KIcKnmMuwW/JEtflzbFyQLUKn64OuVzB3chEZIPh RRR9yWnXz/qDZWHQLYwGVmOD8NzDTiFOjHpCKjbV6PmSSxIDOC3joyrV4VxRsJ+8Cn+0 fInh4Og6XBxQR/q6DSHEfSrKLNbwwc4UaxyRV7xQDocfXOF1SNI3q21xj3mLOekoAPW0 8/JEUc7/1UyIBSLqM+NhaPRaamJMzHGt6qcd74p1altOwdRxEOvbQnSHUm9DxYpqUGxw T7Cg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=J9EhZU0E; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id f10si2996528ywh.121.2017.12.11.05.08.48 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:08:48 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=J9EhZU0E; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52668 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONpA-0006Bn-4J for patch@linaro.org; Mon, 11 Dec 2017 08:08:48 -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) 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-Received: by 10.28.130.15 with SMTP id e15mr833504wmd.52.1512997041548; Mon, 11 Dec 2017 04:57:21 -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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This is one of the simpler manipulations you could make to a floating point number. Signed-off-by: Alex Bennée --- fpu/softfloat.c | 104 +++++++++++++++--------------------------------- include/fpu/softfloat.h | 1 + 2 files changed, 32 insertions(+), 73 deletions(-) -- 2.15.1 Reviewed-by: Richard Henderson 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); } +/* 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 == float_class_normal) { + a.exp += n; + } + return a; +} + +float16 float16_scalbn(float16 a, int n, float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pr = 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 = float32_unpack_canonical(a, status); + decomposed_parts pr = 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 = float64_unpack_canonical(a, status); + decomposed_parts pr = 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) -/* 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 = float32_squash_input_denormal(a, status); - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - - if ( aExp == 0xFF ) { - if ( aSig ) { - return propagateFloat32NaN(a, a, status); - } - return a; - } - if (aExp != 0) { - aSig |= 0x00800000; - } else if (aSig == 0) { - return a; - } else { - aExp++; - } - - if (n > 0x200) { - n = 0x200; - } else if (n < -0x200) { - n = -0x200; - } - - aExp += n - 1; - aSig <<= 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 = float64_squash_input_denormal(a, status); - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - - if ( aExp == 0x7FF ) { - if ( aSig ) { - return propagateFloat64NaN(a, a, status); - } - return a; - } - if (aExp != 0) { - aSig |= LIT64( 0x0010000000000000 ); - } else if (aSig == 0) { - return a; - } else { - aExp++; - } - - if (n > 0x1000) { - n = 0x1000; - } else if (n < -0x1000) { - n = -0x1000; - } - - aExp += n - 1; - aSig <<= 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 *status); float16 float16_mul(float16, float16, float_status *status); float16 float16_muladd(float16, float16, float16, int, float_status *status); float16 float16_div(float16, float16, float_status *status); +float16 float16_scalbn(float16, int, float_status *status); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); From patchwork Mon Dec 11 12:57:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121408 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2769809qgn; Mon, 11 Dec 2017 05:09:25 -0800 (PST) X-Google-Smtp-Source: ACJfBos5VrobQldJwcT/Q3Amp7JxXk3Uu8BvVdCai2Oout7MZVrwyodCUmurt9XV36staBGSSnpy X-Received: by 10.37.185.142 with SMTP id r14mr205388ybg.431.1512997765897; Mon, 11 Dec 2017 05:09:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997765; cv=none; d=google.com; s=arc-20160816; b=LGTzUyDpNgezN29KtmCA+GOPrgWNBLUjDKrTLdim/VN47zpviys68suggn3LEyOSe+ jLG2IO7FcbmONZOmw6BZISYaHzvrtVPwXY+QaJjFK0dUDeWVzsUVk+b2iiANhr+DefvN e9OyFvOTj+3WEulwEAIO2ePbwNktbJSsTpTEcVSXhHPfgAzmf9spS7TDmOyd2/zMg6Wj 1lV7+pwo1Jk+YyOXqTYfKpKrrMmkam4UAXboxEkhMLDLX8vBjLlrj04rRez7/EJgmpMT cC/YCp/rx78H2tE3UCNzIEE7oivsV5oznmXok2Jnwi6c8obBaVUxzCu9J4KrfK5O2HkW yMYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=+uZGALX/x/xsxWW578zb4ZzlC+JEia9ZYfI/M+V+akI=; b=hHBwQPaxn3CNZJrsDwvptlKRsBtjJMBNht7XgWAeR+/xNfl4Y6+yhITr7qM9xd53Qo sKT79/pm4SuymsCpb5OBdC6RS3QDixTwE5OqgmQc6vUsRPBMORXGI0llQ5oS7DGIXUbY P+1fyCV7PjaZHW0lmIfGPgipIYiFKEc0UPYioDSW45q/g7BY0Z/bFojo/aPNfwmHw+Wz KP39q2Br17f2dHLuicYFW86fkAWDEQq4VoeS5Bjfhmc9Sv5Q5e7AN4H8UYrBSejt746k jndwRDvB6AvToj6kDt6Vlp9UNqjUAPt30mqtSh6pwqKYfl4/4IMKqjJyIEZ+EaVhWyH7 d9Ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=QA1fknCB; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id z127si2910617ybz.616.2017.12.11.05.09.25 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:09:25 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=QA1fknCB; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52700 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONpl-0007xw-8q for patch@linaro.org; Mon, 11 Dec 2017 08:09:25 -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) 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-Received: by 10.223.134.116 with SMTP id 49mr356356wrw.85.1512997596657; 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 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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- fpu/softfloat.c | 242 ++++++++++++++++++++++++++---------------------- include/fpu/softfloat.h | 6 ++ 2 files changed, 137 insertions(+), 111 deletions(-) -- 2.15.1 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); } +/* 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 ismag, + float_status *s) +{ + if (a.cls >= float_class_qnan + || + b.cls >= 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 == float_class_snan || b.cls == float_class_snan) { + s->float_exception_flags |= float_flag_invalid; + if (s->default_nan_mode) { + a.cls = float_class_msnan; + return a; + } + } else if (a.cls >= float_class_qnan + && + b.cls < float_class_qnan) { + return b; + } else if (b.cls >= float_class_qnan + && + a.cls < float_class_qnan) { + return a; + } + } + return pick_nan_parts(a, b, s); + } + + /* Handle zero cases */ + if (a.cls == float_class_zero || b.cls == float_class_zero) { + if (a.cls == float_class_normal) { + if (a.sign) { + return ismin ? a : b; + } else { + return ismin ? b : a; + } + } else if (b.cls == 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 == b.exp) { + a_less = a.frac < b.frac; + } else { + a_less = a.exp < b.exp; + } + return a_less == ismin ? a : b; + } + if (a.sign != b.sign) { + if (ismin) { + return a.sign ? a : b; + } else { + return a.sign ? b : a; + } + } else { + bool a_less; + if (a.exp == b.exp) { + a_less = a.frac < b.frac; + } else { + a_less = 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_status *s) \ +{ \ + decomposed_parts pa = float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb = float ## sz ## _unpack_canonical(b, s); \ + decomposed_parts pr = 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); } -/* 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 = float ## s ## _squash_input_denormal(a, status); \ - b = 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 = extractFloat ## s ## Sign(a); \ - bSign = extractFloat ## s ## Sign(b); \ - av = float ## s ## _val(a); \ - bv = float ## s ## _val(b); \ - if (ismag) { \ - aav = float ## s ## _abs(av); \ - abv = float ## s ## _abs(bv); \ - if (aav != abv) { \ - if (ismin) { \ - return (aav < abv) ? a : b; \ - } else { \ - return (aav < abv) ? b : a; \ - } \ - } \ - } \ - if (aSign != 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 *status); float16 float16_muladd(float16, float16, float16, int, float_status *status); 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); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); From patchwork Mon Dec 11 12:57:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 121410 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2770604qgn; Mon, 11 Dec 2017 05:10:04 -0800 (PST) X-Google-Smtp-Source: ACJfBouMLIHmrSChs9txuvoKS8V8lsDw2guorXV+bH0uhutLJj+w9vLSZhc0GzGUaASqIxEk56Ff X-Received: by 10.37.122.194 with SMTP id v185mr202881ybc.359.1512997804569; Mon, 11 Dec 2017 05:10:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512997804; cv=none; d=google.com; s=arc-20160816; b=qT7SWStbX3UotDiBGN/wI6GZ0UQrHyLLXJSFfgIvLqPqVvqwE4mZDMlGYpHJhTtzhs EpZCUp/DhlpVCPuEJJeDIwWJP1oNBQ9f3ViAQRI3Q0G2cXzWxpgrtRWf1aHXxJGqQ6RK yxH42tGoC789xYcIToY9HAHUeraHaykmDYRjYfRBR4f29F8vOXrQMb+9M0MQ2fputRys RXx1ouOD3Usjbo/1V/FD3G+Zp/7YMnWhmlcYav4Bq3KFsVM8dzbmuwj/DBHogULfaHq3 aA4UyBF9GPrW+JQ/Ulb+TGe1TSPAI2jptKF/Mok9uXqDtPCfeb4B6Hl23QfGJVA+rgXf L1CQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=T6rRmFgNcU7BCPuXiNHLXdJhOz6C1zxyD5Wfblt1xto=; b=TJlqE2CDlSX/VqeFFjTctef0P1nVEoG0Bi7+kZjPgTIMbOVq6MHi+f6bPviEk2wRTU IbZD/M+xiCFe19fPOKZ1uhSBvIvxBOVzQHOpXEIfqnp76xnsDMEI4bb6yGSykAIrDyam skpxAI4uvNAsm6/Wt/fKLUpYAk7MWKfm67rtFTah9HkZN2mZLgzLt/LFVI7y6mILZeWv O+4qD6hvkAOtjKQxxgPso3sI8DaUYYfPNuM525tVfnavrvJdFhI0bSCklcj/NmOWws7f bnSFLIgcBu00j7wql7hdIbVkm5pR+3DO/nTMLeOPnw81o8a65NXw/mCumBBz8CmXJrFJ t3mw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Uq9Ysd32; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id e188si3065143ywf.603.2017.12.11.05.10.04 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 11 Dec 2017 05:10:04 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Uq9Ysd32; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:52724 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eONqO-0000re-3C for patch@linaro.org; Mon, 11 Dec 2017 08:10:04 -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) 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-Received: by 10.223.190.135 with SMTP id i7mr311595wrh.91.1512997042713; 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 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) From: =?utf-8?q?Alex_Benn=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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Alex Bennée --- fpu/softfloat.c | 135 +++++++++++++++++++++++++++++------------------- include/fpu/softfloat.h | 2 + 2 files changed, 83 insertions(+), 54 deletions(-) -- 2.15.1 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) #undef MINMAX +/* Floating point compare */ +static int compare_decomposed(decomposed_parts a, decomposed_parts b, + bool is_quiet, float_status *s) +{ + if (a.cls >= float_class_qnan + || + b.cls >= float_class_qnan) { + if (!is_quiet || + a.cls == float_class_snan || + b.cls == float_class_snan) { + s->float_exception_flags |= float_flag_invalid; + } + return float_relation_unordered; + } + + if (a.cls == float_class_zero || b.cls == float_class_zero) { + if (a.cls == float_class_normal) { + return a.sign ? float_relation_less : float_relation_greater; + } else if (b.cls == float_class_normal) { + return b.sign ? float_relation_greater : float_relation_less; + } else if (a.cls == 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 == float_class_inf && b.cls == float_class_inf) { + if (a.sign != b.sign) { + return a.sign ? float_relation_less : float_relation_greater; + } else { + return float_relation_equal; + } + } + + if (a.sign != b.sign) { + return a.sign ? float_relation_less : float_relation_greater; + } + + if (a.exp == b.exp) { + if (a.frac == b.frac) { + return float_relation_equal; + } + if (a.sign) { + return a.frac > b.frac ? + float_relation_less : float_relation_greater; + } else { + return a.frac > b.frac ? + float_relation_greater : float_relation_less; + } + } else { + if (a.sign) { + return a.exp > b.exp ? float_relation_less : float_relation_greater; + } else { + return a.exp > b.exp ? float_relation_greater : float_relation_less; + } + } +} + +#define COMPARE(sz) \ +int float ## sz ## _compare(float ## sz a, float ## sz b, float_status *s) \ +{ \ + decomposed_parts pa = float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb = 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_status *s) \ +{ \ + decomposed_parts pa = float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb = 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; } -#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 = float ## s ## _squash_input_denormal(a, status); \ - b = float ## s ## _squash_input_denormal(b, status); \ - \ - if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) && \ - extractFloat ## s ## Frac( a ) ) || \ - ( ( extractFloat ## s ## Exp( b ) == 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 = extractFloat ## s ## Sign( a ); \ - bSign = extractFloat ## s ## Sign( b ); \ - av = float ## s ## _val(a); \ - bv = float ## s ## _val(b); \ - if ( aSign != bSign ) { \ - if ( (uint ## s ## _t) ( ( av | bv )<<1 ) == 0 ) { \ - /* zero case */ \ - return float_relation_equal; \ - } else { \ - return 1 - (2 * aSign); \ - } \ - } else { \ - if (av == bv) { \ - return float_relation_equal; \ - } else { \ - return 1 - 2 * (aSign ^ ( av < bv )); \ - } \ - } \ -} \ - \ -int float ## s ## _compare(float ## s a, float ## s b, float_status *status) \ -{ \ - 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 *status) { 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); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status);