From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515500844100258.5676967992796; Tue, 9 Jan 2018 04:27:24 -0800 (PST) Received: from localhost ([::1]:49490 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYszy-0001LC-Rg for importer@patchew.org; Tue, 09 Jan 2018 07:27:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51326) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvj-0006ZE-TC for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvf-0006DC-RR for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:22:59 -0500 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:41542) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvf-0006B4-Kc for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:22:55 -0500 Received: by mail-wm0-x242.google.com with SMTP id g75so20185512wme.0 for ; Tue, 09 Jan 2018 04:22:55 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id c19sm13595257wmd.5.2018.01.09.04.22.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:52 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 3DC173E02CB; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kFWWImcJFakK6Q/MS9IUPme+eMbtlWRk0/W9mj8nEvI=; b=LSBeNzBFSMOkvg+uBD+QTIrE9f9f2kW1EviQ25+C134s6EBN/gZCNcoAse18rUqK8J nhzZ7l1H4XOhlB5z+uXOHesV6NQgJ90PHCOjNPLiEgroUBz4UVjYyFhQAW+uREAebxKX 5qv7NbXQ4IrY8pAHGGGOp4LNlEi/8rrA/9Bvg= 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=f6RedqFVzPc8ucvwp6pyMuykm0iBhq+mQC9Wkm1fkYM7lCHij5w4V5/eYnjKSRlnqD V9yqlqVCT0Ue/d8darRu4V8pSgPPVis27AwTGN+Yt2d7GTca8ND8EGA1KB6BWkQ+9/ok Mjcz881eiwr6JdJ2LZfkquNVJcpucfJNHKtROhTAJe1PHLF7UotJjKCLFZne4EcCIi2L nXHZo/WaGOa9JO1V6L57caaVp+gvK4V3vyI3gRNl2zeAue23LwtHl2M2fzbAhBD80l/P AlvE2KUm4ZoelMhW0/7bKz7zNtAPMOlYzN7qD+jIUkWKOQxfhnu7++i0DP+JG8Tz9yjN qEYg== X-Gm-Message-State: AKGB3mK7sRWN6D1rk4fEMP+kjD7Rjf2yVY4xOvRB3QG7VvhXuj8eeHnX Me2qsdDgRhXHtvaABP48o4gzAA== X-Google-Smtp-Source: ACJfBosRc21boElsIvA+GHbE53RPcLeYl1naqIifSrif6aSbMPIJWcfayCT4k9csnwfsd+y5q0e0HA== X-Received: by 10.28.16.211 with SMTP id 202mr11602347wmq.49.1515500574330; Tue, 09 Jan 2018 04:22:54 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:33 +0000 Message-Id: <20180109122252.17670-2-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::242 Subject: [Qemu-devel] [PATCH v2 01/20] fpu/softfloat: implement float16_squash_input_denormal X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 This will be required when expanding the MINMAX() macro for 16 bit/half-precision operations. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson Reviewed-by: Peter Maydell --- fpu/softfloat.c | 15 +++++++++++++++ include/fpu/softfloat.h | 1 + 2 files changed, 16 insertions(+) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 433c5dad2d..3a4ab1355f 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3488,6 +3488,21 @@ static float16 roundAndPackFloat16(flag zSign, int z= Exp, return packFloat16(zSign, zExp, zSig >> 13); } =20 +/*------------------------------------------------------------------------= ---- +| If `a' is denormal and we are in flush-to-zero mode then set the +| input-denormal exception and return zero. Otherwise just return the valu= e. +*-------------------------------------------------------------------------= ---*/ +float16 float16_squash_input_denormal(float16 a, float_status *status) +{ + if (status->flush_inputs_to_zero) { + if (extractFloat16Exp(a) =3D=3D 0 && extractFloat16Frac(a) !=3D 0)= { + float_raise(float_flag_input_denormal, status); + return make_float16(float16_val(a) & 0x8000); + } + } + return a; +} + static void normalizeFloat16Subnormal(uint32_t aSig, int *zExpPtr, uint32_t *zSigPtr) { diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 0f96a0edd1..d5e99667b6 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -277,6 +277,7 @@ void float_raise(uint8_t flags, float_status *status); | If `a' is denormal and we are in flush-to-zero mode then set the | input-denormal exception and return zero. Otherwise just return the valu= e. *-------------------------------------------------------------------------= ---*/ +float16 float16_squash_input_denormal(float16 a, float_status *status); float32 float32_squash_input_denormal(float32 a, float_status *status); float64 float64_squash_input_denormal(float64 a, float_status *status); =20 --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515500692260959.806058183876; Tue, 9 Jan 2018 04:24:52 -0800 (PST) Received: from localhost ([::1]:49441 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsxX-0007ht-Cg for importer@patchew.org; Tue, 09 Jan 2018 07:24:51 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51332) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvj-0006ZI-UO for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvg-0006G7-Nt for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:22:59 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:47022) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvg-0006DR-H0 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:22:56 -0500 Received: by mail-wr0-x243.google.com with SMTP id g21so8109291wrb.13 for ; Tue, 09 Jan 2018 04:22:56 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id q7sm15216522wra.83.2018.01.09.04.22.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:54 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 4EB993E02F2; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=o9l4F51J3K/m7rAhNxcgl01/dGyeul6MP8/bT8/jNP4=; b=JqCn+PeIebEm3CYYjD+ITlLXQA1SE1mYgIBbYZbCF/FWYUFwdvFvarZHaPGYsXLfqt W0nb7sp+CCamkQgF+kc4qpdw2zyjGnFO7f10y5exnFFtnyugi+rEIf6eKnRzxveRTdC0 bEa4y2K3nofY4n3izciSWEtNnU6TfQ7bni5IM= 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=o9l4F51J3K/m7rAhNxcgl01/dGyeul6MP8/bT8/jNP4=; b=PaknmEO5BpulxbBU2MihhS9mUsJ8ldAZlbmSs1Ug8klLGpvPWmmRw4R5/2keuRrxy7 5BseBCYb+U7fKcKfo/MwC4305LVRfn94GBqNxJXfFDhp3ORwDkJRhcV80VMTOc47wbZF R9xMxEKGNX0h3tr6DZs0O2lQoL4SGDkeBPaf6UoM/PnTkjKQywd1lXz/ECEKDxE8KSZx 12Ru/smGLf8gpvF2YNfeM9u6AD+5emnF7otc1gcaLc1LhZEMrpUUnGtp3GUuOG1cnHPz 5CjVjWmw0bIwM44YPURlr37Yl3XaY+DwuNhk7vgmoaIgNxaE8AUsS9XUeFKJnnyv4HyU v9Dg== X-Gm-Message-State: AKGB3mI+/+CQvKCd4mBcXBCmKyqrGxfWXf7GPxtQ6K+ksNqAG33SttX/ jZVUeYeFw+DZSMdOTwbMvmdcOA== X-Google-Smtp-Source: ACJfBovr+9ZLPLxjm0/PGj1tfpC//XTuukQWtiLEo7nUTek0WTCou+WOfTjnuZz+ix9ncV9QrQRpTQ== X-Received: by 10.223.128.34 with SMTP id 31mr14505972wrk.248.1515500575299; Tue, 09 Jan 2018 04:22:55 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:34 +0000 Message-Id: <20180109122252.17670-3-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::243 Subject: [Qemu-devel] [PATCH v2 02/20] include/fpu/softfloat: remove USE_SOFTFLOAT_STRUCT_TYPES X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 It's not actively built and when enabled things fail to compile. I'm not sure the type-checking is really helping here. Seeing as we "own" our softfloat now lets remove the cruft. Signed-off-by: Alex Benn=C3=A9e --- include/fpu/softfloat.h | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index d5e99667b6..52af1412de 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -103,32 +103,6 @@ enum { /*------------------------------------------------------------------------= ---- | Software IEC/IEEE floating-point types. *-------------------------------------------------------------------------= ---*/ -/* Use structures for soft-float types. This prevents accidentally mixing - them with native int/float types. A sufficiently clever compiler and - sane ABI should be able to see though these structs. However - x86/gcc 3.x seems to struggle a bit, so leave them disabled by default.= */ -//#define USE_SOFTFLOAT_STRUCT_TYPES -#ifdef USE_SOFTFLOAT_STRUCT_TYPES -typedef struct { - uint16_t v; -} float16; -#define float16_val(x) (((float16)(x)).v) -#define make_float16(x) __extension__ ({ float16 f16_val =3D {x}; f16_val;= }) -#define const_float16(x) { x } -typedef struct { - uint32_t v; -} float32; -/* The cast ensures an error if the wrong type is passed. */ -#define float32_val(x) (((float32)(x)).v) -#define make_float32(x) __extension__ ({ float32 f32_val =3D {x}; f32_val;= }) -#define const_float32(x) { x } -typedef struct { - uint64_t v; -} float64; -#define float64_val(x) (((float64)(x)).v) -#define make_float64(x) __extension__ ({ float64 f64_val =3D {x}; f64_val;= }) -#define const_float64(x) { x } -#else typedef uint16_t float16; typedef uint32_t float32; typedef uint64_t float64; @@ -141,7 +115,6 @@ typedef uint64_t float64; #define const_float16(x) (x) #define const_float32(x) (x) #define const_float64(x) (x) -#endif typedef struct { uint64_t low; uint16_t high; --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515500693714566.135402459969; Tue, 9 Jan 2018 04:24:53 -0800 (PST) Received: from localhost ([::1]:49439 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsxV-0007gg-KI for importer@patchew.org; Tue, 09 Jan 2018 07:24:49 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51327) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvj-0006ZF-TK for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvh-0006J7-ME for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:22:59 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:40434) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvh-0006GN-Fh for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:22:57 -0500 Received: by mail-wr0-x244.google.com with SMTP id p17so13914631wre.7 for ; Tue, 09 Jan 2018 04:22:57 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 67sm17436758wmq.38.2018.01.09.04.22.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:54 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 60ACA3E2A7A; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=87/TgytgcRnsZ9ORu6HegwY7s5qXzy9GuhJ9dMbtH00=; b=iRaPK+FcwQ3v2rVbM7YX4acnfLIg9EpUuHJwGySsOLq2EAPmQi5OaY11p2e+vHamAh IGdh6nVLaECMPJ5biYrydtqF8QJLb16AZiFTU3/SupXS7vhY1KR76LMQO8W7WynWYQ0B vvmEaOOxhHBB9/4WXdJvRaGj9JNdq6mo7eqHM= 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=87/TgytgcRnsZ9ORu6HegwY7s5qXzy9GuhJ9dMbtH00=; b=k/Y67SXlVbYOrHXkdAfNYwChWqN68CkO3rDscgL9vji8FeJnettfrbXcHgGgaD9AFi cHdRyzon4ogM6+2QXq41OrsjIzFt0LfoiTCxTkuEP1z8eFhASOfhsJhPOWu6Kuz3fa0S 8YmLNIGTqWVwSjvCYyDV+PsIOiyDW0c0NcURu5rAxuZEMCOhvLVmc58VTohXKqaPWiUC HSBdjcrRlmikzyy8kwWuIhuknsMO/6MEWaVFlLv24V0WlIDpIAwFRKL4wy9HHC+ctrK4 KVHLvgc7QKBqHgA3yaI9kHZG4PvnJtTrCsLNhQtB5a+G1aVNcoGkI3Jv84EQF9uykHuN M7mg== X-Gm-Message-State: AKGB3mI38koaR6I//Ch7d0a3J+n91P04Zv6t9as7UWlyyTaIr5uYKK9m ysXMGf85wnJpSXkniBEuFAdlEQ== X-Google-Smtp-Source: ACJfBoteP8lxB2bPqX7OIeacauN0FeZrbj0YC89hGWmT6BF+4rFN8oV4OvxB6hgjJrxiZVvFvXuQYQ== X-Received: by 10.223.134.26 with SMTP id 26mr12417119wrv.218.1515500576407; Tue, 09 Jan 2018 04:22:56 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:35 +0000 Message-Id: <20180109122252.17670-4-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v2 03/20] include/fpu/softfloat: implement float16_abs helper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 This will be required when expanding the MINMAX() macro for 16 bit/half-precision operations. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Peter Maydell --- include/fpu/softfloat.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 52af1412de..cfc615008d 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -347,6 +347,13 @@ static inline int float16_is_zero_or_denormal(float16 = a) return (float16_val(a) & 0x7c00) =3D=3D 0; } =20 +static inline float16 float16_abs(float16 a) +{ + /* Note that abs does *not* handle NaN specially, nor does + * it flush denormal inputs to zero. + */ + return make_float16(float16_val(a) & 0x7fff); +} /*------------------------------------------------------------------------= ---- | The pattern for a default generated half-precision NaN. *-------------------------------------------------------------------------= ---*/ --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 151550100744726.81417605303568; Tue, 9 Jan 2018 04:30:07 -0800 (PST) Received: from localhost ([::1]:49525 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt2b-0003SS-Ri for importer@patchew.org; Tue, 09 Jan 2018 07:30:05 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51398) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvm-0006bI-0y for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvl-0006Uo-5L for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:02 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:33397) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvk-0006ST-Um for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:01 -0500 Received: by mail-wr0-x242.google.com with SMTP id p6so13914189wrd.0 for ; Tue, 09 Jan 2018 04:23:00 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id m6sm15767623wmd.37.2018.01.09.04.22.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:54 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 718E53E2A83; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KtfrcwYYHDPEWFKEmcYMWUVtcVxZcGJDHkDjYRTzgt8=; b=A4/erq9/7IcAm9xqIWXXoIMvolHeZ4dBWDxD++1kIC9Cq9uut94dJrc6ZUF40N3pCZ aQjQ11gjzjoHDlrH/DMmSxPlWOpS5HkJORGU001ltcMjt1pXRTzhi6ikOB/RZn/GIoc4 fkxNTMqAOewwZiNWTlvdUA5Q0nS5xq3xjDIk8= 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=KtfrcwYYHDPEWFKEmcYMWUVtcVxZcGJDHkDjYRTzgt8=; b=nQ0DWXdI0nhmzvO7Gv3p5Kj4imQhXmIJjjmL6skwi6thrUT/lM7LnWFxms59reFsz+ Zzop7UdRhNRL4LH3eRiX18lox1ZjI2GD5v2cpz/XIsQvx4iiCDTLz+kXHqF5J/oXAnAZ ZdUdDS69SkpIhDofMPCIaZAHICg4h4x6myt9yk959vmLfuc6VkObEjWRcLAzdDA6/emK fpu6Y+T8U3O+GXXkF5QsZ/UUiUT3avEmtGPvIBp9qSvZRDOMpSmlpqmMiFPxSWzgrvp1 D+PgiN8eGrsT7qrKsuLRCbSoLm7NsKI1G57kl9LCg3j2zFvpstdwyGGadjAALQ4FNDMl Opsw== X-Gm-Message-State: AKGB3mI1PG7UoCZuVZLm8n5ER4TZI/lsJUdZG2j48wtGpM4OmGSqQAjI 2IdocFw654VSbVRxck8LZ5Jd6Q== X-Google-Smtp-Source: ACJfBovFiOHHyLvHLZbKCzLYbkN+27kKTIKWj9g5xhqP91+gBHxtrJSMWYMUsmeN9eSp2QaerUZM/g== X-Received: by 10.223.187.8 with SMTP id r8mr6025777wrg.269.1515500579912; Tue, 09 Jan 2018 04:22:59 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:36 +0000 Message-Id: <20180109122252.17670-5-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::242 Subject: [Qemu-devel] [PATCH v2 04/20] include/fpu/softfloat: implement float16_chs helper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson Reviewed-by: Peter Maydell --- include/fpu/softfloat.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index cfc615008d..dc71b01dba 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -354,6 +354,15 @@ static inline float16 float16_abs(float16 a) */ return make_float16(float16_val(a) & 0x7fff); } + +static inline float16 float16_chs(float16 a) +{ + /* Note that chs does *not* handle NaN specially, nor does + * it flush denormal inputs to zero. + */ + return make_float16(float16_val(a) ^ 0x8000); +} + /*------------------------------------------------------------------------= ---- | The pattern for a default generated half-precision NaN. *-------------------------------------------------------------------------= ---*/ --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515500842548143.81480427208612; Tue, 9 Jan 2018 04:27:22 -0800 (PST) Received: from localhost ([::1]:49486 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYszx-0001IO-22 for importer@patchew.org; Tue, 09 Jan 2018 07:27:21 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51333) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvj-0006ZJ-Ui for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvi-0006MJ-JY for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:22:59 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:33397) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvi-0006Jb-Dd for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:22:58 -0500 Received: by mail-wr0-x243.google.com with SMTP id p6so13914069wrd.0 for ; Tue, 09 Jan 2018 04:22:58 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 20sm15039530wms.8.2018.01.09.04.22.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:54 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 823063E2B48; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kAN0+Gi2kG5Pzf3bBOa0T2FJ1NA02CRitdLzfGe1bDI=; b=etFwRA5BPKY4gsLUmRB4sZHEK1eCpbWqfrFbW32pBjLCRFtGD+6zwFERyZ5o0aSFyA 8Rw5LMztjIoa7eFmKsy9fEsQA6KAcpxvt938Roh7KmRZSPobnB4taXlSr79dE9Pw8J1u OR1umkKrRegJV0adbzULt3ySMF4CXXTQ0bJL8= 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=kAN0+Gi2kG5Pzf3bBOa0T2FJ1NA02CRitdLzfGe1bDI=; b=PAT0cHwjnKD6w88c5w78tH6t2n3zfeQjBI4HA+9G+ALsq2Byba/+ndy4VncDV1W02l z0h4YUS2wbRVHzeOjRKgOSyM8llzE0TR04k6jUYjcyvT4A0xryZF0Neg8qQ5QzSfCs8L YGjaXCAs0kO2b8YJyRrH2da1rNLlEnwxrErYPy+b6LLk8QGOWqU48VrnM3NNc86TPD9X mrOeXm/rhqyalLdQDOV8Lrb75N37bMK11gUZZgt2fjzAKoVeG2NhEtfKtCywKhAwJ9vx 1Re2mY5uG2AEiGKbrmPQg87H5QcGkCVYQ+tiXHlms5LbGplaqFFNJm+PHEBG8v/xgDRR wZ7g== X-Gm-Message-State: AKGB3mKwH8RNKeZ1sglU0lsMKh78K3JQdh/I0adx/LVY1ZlSqOGTcjtm npSE4FYW+8Op7+kEAC/KVXjKZA== X-Google-Smtp-Source: ACJfBovXvk90rRv1o8FP1HPfKiOix8mjEcEvF1Xq4c+vuDJLmSOpB/v+aSjgvsOWWryJA0hSWbZbOw== X-Received: by 10.223.172.199 with SMTP id o65mr6375955wrc.215.1515500577414; Tue, 09 Jan 2018 04:22:57 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:37 +0000 Message-Id: <20180109122252.17670-6-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::243 Subject: [Qemu-devel] [PATCH v2 05/20] include/fpu/softfloat: implement float16_set_sign helper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Peter Maydell --- include/fpu/softfloat.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index dc71b01dba..8ab5d0df47 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -363,6 +363,11 @@ static inline float16 float16_chs(float16 a) return make_float16(float16_val(a) ^ 0x8000); } =20 +static inline float16 float16_set_sign(float16 a, int sign) +{ + return make_float16((float16_val(a) & 0x7fff) | (sign << 15)); +} + /*------------------------------------------------------------------------= ---- | The pattern for a default generated half-precision NaN. *-------------------------------------------------------------------------= ---*/ --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515500842548896.6699101088975; Tue, 9 Jan 2018 04:27:22 -0800 (PST) Received: from localhost ([::1]:49488 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYszv-0001IU-My for importer@patchew.org; Tue, 09 Jan 2018 07:27:19 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51375) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvk-0006aM-Qo for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvj-0006PQ-H6 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:00 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:42674) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvj-0006Mi-B3 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:22:59 -0500 Received: by mail-wr0-x244.google.com with SMTP id w107so13908099wrb.9 for ; Tue, 09 Jan 2018 04:22:59 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id x127sm12731031wmb.10.2018.01.09.04.22.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:54 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 92E383E2B49; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wZxx7z+WQCnQ78WbUwlXVYn9xXoslXabdFmm18Cqbbs=; b=Y0yGmolRZ/VHYDHjDqMo4p2fxKVRqmwXm+MbNgORW1j0OENvHcJXgsablp4hAFJ4BB dVMiwNQYYlqyuOnFLxRsYVJhZZ+oz2aBFfwHLGE/PqPNMvuF7LszT6sbOttZkUAIQ8PV wvrB36sXwTrwN4t0LeCqI0DL0xZQCAk5I5ls4= 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=wZxx7z+WQCnQ78WbUwlXVYn9xXoslXabdFmm18Cqbbs=; b=mUD4dCfkcwbWOnT/YANmOcz9wUo9de/5Gjlyl7t+lfg4rpw66mdRBY3/fLCbZgLSbZ dekrbk/zRZJNgLwPOuAeYxxMPViAc0aXw+LAjRPmnxBXUWBxvqOR1xAaX+V2MiamQj74 1Cp+yyEBqgZyVDA4npOVlFs/PMex1DWMhOn+TO+h1dQfQd8Odbk7JOGmyT0s2Cfh3QRu rmMR6JOGEl+1RCj6/h7loYdbsEuwvu7wWjVYgZTkhvpOxe8yNpGtRejxM5aIgonxSPBm +IQI7lUTp7EOpScrVk0pdgxW82qMy8c4Xpalnw+oVluLrZ8oij/TRjDE4zBRHjBt4UiE c3nw== X-Gm-Message-State: AKGB3mLvmJFzZb0GLLtI8mFFwmJ1PpTm6MXgI/NG1HoO1zaz6iiJC2BH JxUxY9xOKzHdGvvimhvVKwza9A== X-Google-Smtp-Source: ACJfBotEVlRWCltcNP/XKPtq8G713ZGRVscMMt2cuVAs59NqcTkEBB0vXyTfkJV47NRPCA7srMnrgA== X-Received: by 10.223.158.144 with SMTP id a16mr14236070wrf.83.1515500578341; Tue, 09 Jan 2018 04:22:58 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:38 +0000 Message-Id: <20180109122252.17670-7-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v2 06/20] include/fpu/softfloat: add some float16 constants X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 This defines the same set of common constants for float 16 as defined for 32 and 64 bit floats. These are often used by target helper functions. I've also removed constants that are not used by anybody. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- v2 - fixup constants, remove unused onces --- include/fpu/softfloat.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 8ab5d0df47..e64bf62f3d 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -368,6 +368,11 @@ static inline float16 float16_set_sign(float16 a, int = sign) return make_float16((float16_val(a) & 0x7fff) | (sign << 15)); } =20 +#define float16_zero make_float16(0) +#define float16_one make_float16(0x3a00) +#define float16_half make_float16(0x3800) +#define float16_infinity make_float16(0x7c00) + /*------------------------------------------------------------------------= ---- | The pattern for a default generated half-precision NaN. *-------------------------------------------------------------------------= ---*/ @@ -474,8 +479,6 @@ static inline float32 float32_set_sign(float32 a, int s= ign) =20 #define float32_zero make_float32(0) #define float32_one make_float32(0x3f800000) -#define float32_ln2 make_float32(0x3f317218) -#define float32_pi make_float32(0x40490fdb) #define float32_half make_float32(0x3f000000) #define float32_infinity make_float32(0x7f800000) =20 @@ -588,7 +591,6 @@ static inline float64 float64_set_sign(float64 a, int s= ign) #define float64_zero make_float64(0) #define float64_one make_float64(0x3ff0000000000000LL) #define float64_ln2 make_float64(0x3fe62e42fefa39efLL) -#define float64_pi make_float64(0x400921fb54442d18LL) #define float64_half make_float64(0x3fe0000000000000LL) #define float64_infinity make_float64(0x7ff0000000000000LL) =20 --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 15155010102741003.0835625873594; Tue, 9 Jan 2018 04:30:10 -0800 (PST) Received: from localhost ([::1]:49523 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt2V-0003O8-3j for importer@patchew.org; Tue, 09 Jan 2018 07:29:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51445) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvp-0006ed-8C for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvn-0006d8-Ow for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:05 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:44851) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvn-0006aT-Hf for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:03 -0500 Received: by mail-wr0-x241.google.com with SMTP id w50so4697081wrc.11 for ; Tue, 09 Jan 2018 04:23:03 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id j132sm1629257wmd.7.2018.01.09.04.22.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:59 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id A33343E2B4A; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CMj7/OCLKuOKn1F/BoEznnKNy9Zs3Wj1+nU1V8x9KRo=; b=ayaBk4gPi3IEICu07geC1ugd1Lo++/gA4XvJ/3rZ/zCcRiK6yDl49SInXhTUXFWOk8 m9r+QAbdPY7wGvgbrdzumPBUNZnwtD0Tq9Qz+C4D+hksAKZBnAnxdagEMhhw9fVISIC7 Mj9qRQUjKBuV2Qksh2p2boz008Ur83rBQq4nc= 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=CMj7/OCLKuOKn1F/BoEznnKNy9Zs3Wj1+nU1V8x9KRo=; b=TiqThbdQ1NKrERK/xA5rrwOmjmBp/gCmIaW6XGQI4TUhj2L3hxBTsHzJvsoSCyHcn7 1eXSlYUqLzNjLInpiliZkgh7CiCeRxS3maQEsAT/Lb4eyugPwiQPCCjrIgzq1Rz6gYrA /1ZFErtOUH8HebNbqATa/rfDsbankSqOtuzq9RFQTz6MzqsU6n5ZS9RZ+cxDOVXpl9fW kGbp85fRYv0Te51VUc5tBYff+CigRDpYxMLjC5z2xVZ5tZv15j8Pra8Mp+uKnQhjjplG 1HSr+xCzuUjNRkKqt9/zcembrNfBIZAJ4oYMOYh3FXFY7cRpX3RLotDLCo6esIXCuhs8 ueig== X-Gm-Message-State: AKGB3mIeeKk5O9NiShvHz6uiGNq1LvV6k4gT5qKoA68FPkCt0jIcybM7 bmL6Mz8P1qNvt6qQ8vibsT7Mlg== X-Google-Smtp-Source: ACJfBos6QH69/L3gweEsoDA7/A/CRTvTHmv8kNdHe6V0rdyntIfr4hmY/n1HtiwCjI/MsG0pEuH3Bw== X-Received: by 10.223.164.148 with SMTP id g20mr13218352wrb.177.1515500582427; Tue, 09 Jan 2018 04:23:02 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:39 +0000 Message-Id: <20180109122252.17670-8-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::241 Subject: [Qemu-devel] [PATCH v2 07/20] fpu/softfloat: propagate signalling NaNs in MINMAX X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 While a comparison between a QNaN and a number will return the number it is not the same with a signaling NaN. In this case the SNaN will "win" and after potentially raising an exception it will be quietened. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- v2 - added return for propageFloat --- fpu/softfloat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3a4ab1355f..44c043924e 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -7683,6 +7683,7 @@ int float128_compare_quiet(float128 a, float128 b, fl= oat_status *status) * minnum() and maxnum() functions. These are similar to the min() * and max() functions but if one of the arguments is a QNaN and * the other is numerical then the numerical argument is returned. + * SNaNs will get quietened before being returned. * minnum() and maxnum correspond to the IEEE 754-2008 minNum() * and maxNum() operations. min() and max() are the typical min/max * semantics provided by many CPUs which predate that specification. @@ -7703,11 +7704,14 @@ static inline float ## s float ## s ## _minmax(floa= t ## s a, float ## s b, \ if (float ## s ## _is_any_nan(a) || \ float ## s ## _is_any_nan(b)) { \ if (isieee) { \ - if (float ## s ## _is_quiet_nan(a, status) && \ + if (float ## s ## _is_signaling_nan(a, status) || \ + float ## s ## _is_signaling_nan(b, status)) { \ + return propagateFloat ## s ## NaN(a, b, status); \ + } else if (float ## s ## _is_quiet_nan(a, status) && \ !float ## s ##_is_any_nan(b)) { \ return b; \ } else if (float ## s ## _is_quiet_nan(b, status) && \ - !float ## s ## _is_any_nan(a)) { \ + !float ## s ## _is_any_nan(a)) { \ return a; \ } \ } \ --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501390065852.511145206124; Tue, 9 Jan 2018 04:36:30 -0800 (PST) Received: from localhost ([::1]:49569 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt8i-0000Fi-Bx for importer@patchew.org; Tue, 09 Jan 2018 07:36:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51495) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvu-0006jA-B1 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvp-0006li-Sg for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:10 -0500 Received: from mail-wm0-x241.google.com ([2a00:1450:400c:c09::241]:41544) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvp-0006hg-MJ for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:05 -0500 Received: by mail-wm0-x241.google.com with SMTP id g75so20186467wme.0 for ; Tue, 09 Jan 2018 04:23:05 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 31sm17529754wrw.8.2018.01.09.04.22.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:59 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id B3D033E2B4B; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=w73w7ZZQIMHcKkvA79sIXqgUK5/buI45QDc8gpNpU+E=; b=IfJKldQLDdUzwauX2LkUXX+p7kQFwscvu5ASX8sdOSqLTJvcEBPOYLy+7/QCzTyRNW DEpn+vFi6frqOmSx/fZUN34K9huRpR8gvuUUKLV6icm4hshTwrzFYRuA7zLuR5O8lvrm 66PXdrVbxyisroCS/vTeJjEEm83W4OadkAQfE= 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=w73w7ZZQIMHcKkvA79sIXqgUK5/buI45QDc8gpNpU+E=; b=AS0WpKUM0Z4CwOM6LmtXYTwSLjlRpK5WAXjk4H/w3hgT7rqqHdKtJByKI6NdlE03Js ECrNjAZCO+M8dYifJIKQccPv68TfmNaYqARbr9tOqNrnwTumDgasMRAKrvJ+oBerYv4Z mLn9BiPmgYILRy9DADQ56qhFYe2WQ78XhN3s4998UMBwqpfcZr+2vVSLRNfflolkBtA3 tlNHab97REBxyv74XL5uQjg3iYcCtHQk7YhVLIz6dHrmcZ11NnbdZu1kK6APGww7vSq0 DLO1S032dVfCnMIPBOn0XP/6UsilYeHzZ/cmATHBLU4ox8638CoGfCOT7Uid70/A7Mi+ QYSw== X-Gm-Message-State: AKGB3mLfFJ59vbKbv/KOvWcycooPUDS/abmae+pwZ6C8t4VysfM3PUFj OPZnaJC7aXrKAm9c0Ew0hULyw+GfSJQ= X-Google-Smtp-Source: ACJfBou2n4a6q6mrI0bdcwUrHp/hnh5iRla+ckatZlI7AeD+JynEZkI32Ago116vYpMMZMxs2AGbqQ== X-Received: by 10.28.106.26 with SMTP id f26mr11098557wmc.40.1515500584601; Tue, 09 Jan 2018 04:23:04 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:40 +0000 Message-Id: <20180109122252.17670-9-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::241 Subject: [Qemu-devel] [PATCH v2 08/20] fpu/softfloat: improve comments on ARM NaN propagation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Mention the pseudo-code fragment from which this is based and correct the spelling of signalling. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- fpu/softfloat-specialize.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index de2c5d5702..3d507d8c77 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -445,14 +445,15 @@ static float32 commonNaNToFloat32(commonNaNT a, float= _status *status) =20 #if defined(TARGET_ARM) static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, - flag aIsLargerSignificand) + flag aIsLargerSignificand) { - /* ARM mandated NaN propagation rules: take the first of: - * 1. A if it is signaling - * 2. B if it is signaling + /* ARM mandated NaN propagation rules (see FPProcessNaNs()), take + * the first of: + * 1. A if it is signalling + * 2. B if it is signalling * 3. A (quiet) * 4. B (quiet) - * A signaling NaN is always quietened before returning it. + * A signalling NaN is always quietened before returning it. */ if (aIsSNaN) { return 0; --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501197161645.2328088253388; Tue, 9 Jan 2018 04:33:17 -0800 (PST) Received: from localhost ([::1]:49543 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt5d-00062W-F1 for importer@patchew.org; Tue, 09 Jan 2018 07:33:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51494) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvu-0006j9-AS for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvr-0006r6-57 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:10 -0500 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:36070) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvq-0006nY-Rj for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:07 -0500 Received: by mail-wm0-x243.google.com with SMTP id b76so20438620wmg.1 for ; Tue, 09 Jan 2018 04:23:06 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id q2sm12886646wma.19.2018.01.09.04.22.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:59 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id C4A833E2B4C; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0khpgXmq2qgbbb8kOfF1HJdjZVtA5n1xM++dq8n/wIA=; b=Hy4poktA7p+jIIhoo1asO9xb7iO98byjT3EXW1zyZ24ITOmUvYBjkNoNjmdz5qLg2Y hn0CAnZ2f20N/L+yPMJ17oNYHg+x3YR9L3NxnBzWAFhrzS3QnsNBkBu4M7WrVpq9ZRbv 3Nfe+XC4llsth9BCHPu9tok5Z4s7xNaZ8h4b8= 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=0khpgXmq2qgbbb8kOfF1HJdjZVtA5n1xM++dq8n/wIA=; b=XMAQN4wDkCKI3fakesKJa6bwaYRwOFX349CxD5rXP5sV6TEUswLOVC1ks+XIXwS2YC EwsitDT/z4qs62WnJSIuT+Mh+0rh3B5OYJp7IFxCT9na7KWyniSLb7asaTfnPF9LLxLg TnPtx60rwTRn1LsI1Qh78VFCtSulmtWouKH44EcUPYofsjteJ5no8NeJKuCqLQVn+HFg RT/Udzy/C/6yvte7W8+OvoNXOORniVWYuDnInD/SvXkjln/fBff6ApoKa66EzD7zD4Dr FS+4Ay7EFwVI6eUre22xeUoHiCTZw/Dl6NsQPOY/qgIGjWbh8SMGkLNG2mM3RMdhrfXt mhQg== X-Gm-Message-State: AKGB3mIH7qIVxrZbvPpkvbryDF0YSf5JUQ3Nq63T4pmzCtfX7mLKtJGw Wtesrd+LZaGymS0Mu0pVc2pslvi82vY= X-Google-Smtp-Source: ACJfBoveBaK/B19c/tGP8vEEmKx6EtobLDQeY55LxAntzMqFLhua1rsm/P/J+FPwuf4lYXjHLhGY4w== X-Received: by 10.28.183.8 with SMTP id h8mr10626199wmf.62.1515500585634; Tue, 09 Jan 2018 04:23:05 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:41 +0000 Message-Id: <20180109122252.17670-10-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::243 Subject: [Qemu-devel] [PATCH v2 09/20] fpu/softfloat: move the extract functions to the top of the file X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 This is pure code-motion during re-factoring as the helpers will be needed earlier. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson Reviewed-by: Peter Maydell --- v2 - fix minor white space nit --- fpu/softfloat.c | 120 +++++++++++++++++++++++++---------------------------= ---- 1 file changed, 54 insertions(+), 66 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 44c043924e..59afe81d06 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -132,6 +132,60 @@ static inline flag extractFloat16Sign(float16 a) return float16_val(a)>>15; } =20 +/*------------------------------------------------------------------------= ---- +| Returns the fraction bits of the single-precision floating-point value `= a'. +*-------------------------------------------------------------------------= ---*/ + +static inline uint32_t extractFloat32Frac(float32 a) +{ + return float32_val(a) & 0x007FFFFF; +} + +/*------------------------------------------------------------------------= ---- +| Returns the exponent bits of the single-precision floating-point value `= a'. +*-------------------------------------------------------------------------= ---*/ + +static inline int extractFloat32Exp(float32 a) +{ + return (float32_val(a) >> 23) & 0xFF; +} + +/*------------------------------------------------------------------------= ---- +| Returns the sign bit of the single-precision floating-point value `a'. +*-------------------------------------------------------------------------= ---*/ + +static inline flag extractFloat32Sign(float32 a) +{ + return float32_val(a) >> 31; +} + +/*------------------------------------------------------------------------= ---- +| Returns the fraction bits of the double-precision floating-point value `= a'. +*-------------------------------------------------------------------------= ---*/ + +static inline uint64_t extractFloat64Frac(float64 a) +{ + return float64_val(a) & LIT64(0x000FFFFFFFFFFFFF); +} + +/*------------------------------------------------------------------------= ---- +| Returns the exponent bits of the double-precision floating-point value `= a'. +*-------------------------------------------------------------------------= ---*/ + +static inline int extractFloat64Exp(float64 a) +{ + return (float64_val(a) >> 52) & 0x7FF; +} + +/*------------------------------------------------------------------------= ---- +| Returns the sign bit of the double-precision floating-point value `a'. +*-------------------------------------------------------------------------= ---*/ + +static inline flag extractFloat64Sign(float64 a) +{ + return float64_val(a) >> 63; +} + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -299,39 +353,6 @@ static int64_t roundAndPackUint64(flag zSign, uint64_t= absZ0, return absZ0; } =20 -/*------------------------------------------------------------------------= ---- -| Returns the fraction bits of the single-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline uint32_t extractFloat32Frac( float32 a ) -{ - - return float32_val(a) & 0x007FFFFF; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the exponent bits of the single-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline int extractFloat32Exp(float32 a) -{ - - return ( float32_val(a)>>23 ) & 0xFF; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the sign bit of the single-precision floating-point value `a'. -*-------------------------------------------------------------------------= ---*/ - -static inline flag extractFloat32Sign( float32 a ) -{ - - return float32_val(a)>>31; - -} - /*------------------------------------------------------------------------= ---- | If `a' is denormal and we are in flush-to-zero mode then set the | input-denormal exception and return zero. Otherwise just return the valu= e. @@ -492,39 +513,6 @@ static float32 =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the fraction bits of the double-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline uint64_t extractFloat64Frac( float64 a ) -{ - - return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF ); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the exponent bits of the double-precision floating-point value `= a'. -*-------------------------------------------------------------------------= ---*/ - -static inline int extractFloat64Exp(float64 a) -{ - - return ( float64_val(a)>>52 ) & 0x7FF; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the sign bit of the double-precision floating-point value `a'. -*-------------------------------------------------------------------------= ---*/ - -static inline flag extractFloat64Sign( float64 a ) -{ - - return float64_val(a)>>63; - -} - /*------------------------------------------------------------------------= ---- | If `a' is denormal and we are in flush-to-zero mode then set the | input-denormal exception and return zero. Otherwise just return the valu= e. --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501201369984.8650029428225; Tue, 9 Jan 2018 04:33:21 -0800 (PST) Received: from localhost ([::1]:49544 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt5k-00067m-Ga for importer@patchew.org; Tue, 09 Jan 2018 07:33:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51451) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvp-0006fS-Nm for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvo-0006g2-Nl for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:05 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:47022) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvo-0006eU-Hl for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:04 -0500 Received: by mail-wr0-x241.google.com with SMTP id g21so8109645wrb.13 for ; Tue, 09 Jan 2018 04:23:04 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 127sm17084022wmk.14.2018.01.09.04.22.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:59 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id D55333E2B4D; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=TuqpRZxm6uXuRzIpBThQodutJC+WGgUS7fzwpNjLwqk=; b=A7S/kq8MN3sgBnRuDtRysm9/2A7lBK1JsDThRptQ3WebRslj1u3Ku1Lz4iYgO+KAAb BIODiy2qflCjKEt7Ald1Kh6ddpbFaA3Y8PC/J6BKK+OKsLyONpdeuxM+t0Sq90/jcZjs QFadUxlxEpMm3EavgbD6A6ooHo4y2XvwB4yic= 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=TuqpRZxm6uXuRzIpBThQodutJC+WGgUS7fzwpNjLwqk=; b=WSU+FjPr6ig6kn8N93hzSqyGu+B8s1RHPSgyOkpW3a1EL+LlEuC0pw2eBumGIqfUkl vf53CBus2FSGGHLmF6Embxccbl8kDRBfbzpqTMDFdFAappYBaWearGgMpNK2ChhbPYA7 hJCBCeKvx1jqg84Z3uwMbnn83lP3nVb47RFd5czo7PqdcsKAoZD5WSyso+9NAQLahFXb FFvba8Dc3vVmkdV+jF1ltdQKrVUYcHohMGipP7TMm68o/VJvLASjAmwbjQoMKlHqaFY1 8dSnVg7zgHhdNMfvqHhiXG/hIlV8KTFU/ahRKZVI0ZkER6Wul9z2Ju3b/7dSrgt5nH8K Y5oQ== X-Gm-Message-State: AKGB3mLjV4wKrlBStVCbzqKA+YBPSge/os5mdgRW6OKmmlHVeyZhUDok IOVbeDEuxoKCd6w/10lJ08kYVg== X-Google-Smtp-Source: ACJfBovBM30ZQmnOxHq+QYV6OH6+g876q63uCac/ehFuNwC/AiQUxfhHKeNrca/Zm0YnzwZhiKjFdQ== X-Received: by 10.223.177.143 with SMTP id q15mr12524719wra.228.1515500583457; Tue, 09 Jan 2018 04:23:03 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:42 +0000 Message-Id: <20180109122252.17670-11-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::241 Subject: [Qemu-devel] [PATCH v2 10/20] fpu/softfloat: define decompose structures X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 These structures pave the way for generic softfloat helper routines that will operate on fully decomposed numbers. Signed-off-by: Alex Benn=C3=A9e Signed-off-by: Richard Henderson --- fpu/softfloat.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 59afe81d06..fcba28d3f8 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -83,7 +83,7 @@ this code that are retained. * target-dependent and needs the TARGET_* macros. */ #include "qemu/osdep.h" - +#include "qemu/bitops.h" #include "fpu/softfloat.h" =20 /* We only need stdlib for abort() */ @@ -186,6 +186,74 @@ static inline flag extractFloat64Sign(float64 a) return float64_val(a) >> 63; } =20 +/*------------------------------------------------------------------------= ---- +| Classify a floating point number. +*-------------------------------------------------------------------------= ---*/ + +typedef enum { + float_class_unclassified, + float_class_zero, + float_class_normal, + float_class_inf, + float_class_qnan, + float_class_snan, + float_class_dnan, + float_class_msnan, /* maybe silenced */ +} float_class; + +/*------------------------------------------------------------------------= ---- +| Structure holding all of the decomposed parts of a float. +| The exponent is unbiased and the fraction is normalized. +*-------------------------------------------------------------------------= ---*/ + +typedef struct { + uint64_t frac : 64; + int exp : 32; + float_class cls : 8; + int : 23; + bool sign : 1; +} decomposed_parts; + +#define DECOMPOSED_BINARY_POINT (64 - 2) +#define DECOMPOSED_IMPLICIT_BIT (1ull << DECOMPOSED_BINARY_POINT) +#define DECOMPOSED_OVERFLOW_BIT (DECOMPOSED_IMPLICIT_BIT << 1) + +/* Structure holding all of the relevant parameters for a format. */ +typedef struct { + int exp_bias; + int exp_max; + int frac_shift; + uint64_t frac_lsb; + uint64_t frac_lsbm1; + uint64_t round_mask; + uint64_t roundeven_mask; +} decomposed_params; + +#define FRAC_PARAMS(F) \ + .frac_shift =3D F, \ + .frac_lsb =3D 1ull << (F), \ + .frac_lsbm1 =3D 1ull << ((F) - 1), \ + .round_mask =3D (1ull << (F)) - 1, \ + .roundeven_mask =3D (2ull << (F)) - 1 + +static const decomposed_params float16_params =3D { + .exp_bias =3D 0x0f, + .exp_max =3D 0x1f, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 10) +}; + +static const decomposed_params float32_params =3D { + .exp_bias =3D 0x7f, + .exp_max =3D 0xff, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 23) +}; + +static const decomposed_params float64_params =3D { + .exp_bias =3D 0x3ff, + .exp_max =3D 0x7ff, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 52) +}; + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151550139012930.26917440095849; Tue, 9 Jan 2018 04:36:30 -0800 (PST) Received: from localhost ([::1]:49568 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt8k-0000FV-De for importer@patchew.org; Tue, 09 Jan 2018 07:36:26 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51530) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvw-0006kF-P6 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvt-0006zG-ME for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:12 -0500 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:41546) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvt-0006x0-8A for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:09 -0500 Received: by mail-wm0-x243.google.com with SMTP id g75so20186828wme.0 for ; Tue, 09 Jan 2018 04:23:09 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 52sm17541819wrz.80.2018.01.09.04.22.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:59 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id E81A63E2B4E; Tue, 9 Jan 2018 12:22:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=4azIq6vBvtc1ef4ukor3jmbdpMza9m9Op+G8OFa13YY=; b=FxtQNtT4bf8QM6O3b2kJ+tcMjt80pHfV508j7pv/7UW69/Jh2361b3z+49Ftd+B3fB yDm1tl2khMIzf42D+ncG7uDeVsLID9gz52BfhX7OjdQMLzjSgUfSdgZsisj+cd3YfdPU I1CiIs98U2EJ+mnu+Su6mdIG9CzBHYhGTBtps= 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=4azIq6vBvtc1ef4ukor3jmbdpMza9m9Op+G8OFa13YY=; b=FfdClYXXxvdyBYvnVMoYXEnI4YGxqbdrWb4PGnZoW9hFWE7QNmuZuYDBDG8/Edaam7 9MR+eovgNFMJGm1Eq7jt5M0j8bB7GZ+zWG4Et7KGe+axSE/y+nXTLWZijE/tZqEazuB6 uavrOTRj/aP8JBu2Nt0ahz/kKa4dzDuxfz7CPijn4JUY8wylZrMSeyvJhe7pcTR/NpfX UscRaLxUHGc6x0W1AnmTI8eKe+vEgBEglVOs7wdPC19yqOwL49ToUhZobjebefjETR3g wkNyQFVHCzs+TmyDGqPbwINRirJY/1oW9RkRutowKtZ/Lnl7/wHO44yZTFWPUna0NQ2m xQrQ== X-Gm-Message-State: AKGB3mKvAAmWUnowlBYX0aUKmuLGjBJd9Y2aJfayJKW2ip2f9jjYS2Jp NBTHTRxYXuTUGVQhvvMpPd0Qbw== X-Google-Smtp-Source: ACJfBou034kpcJvL1yOQQwsCtgd8B79LPNAzCBSZTJz25qJPDo3ayV4s9FsBf6SK2BsBuwFJeJxfzQ== X-Received: by 10.28.6.6 with SMTP id 6mr11156500wmg.8.1515500587714; Tue, 09 Jan 2018 04:23:07 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:43 +0000 Message-Id: <20180109122252.17670-12-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::243 Subject: [Qemu-devel] [PATCH v2 11/20] fpu/softfloat: re-factor add/sub X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We can now add float16_add/sub and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 add and sub functions. Signed-off-by: Alex Benn=C3=A9e Signed-off-by: Richard Henderson --- fpu/softfloat.c | 904 +++++++++++++++++++++++++-------------------= ---- include/fpu/softfloat.h | 4 + 2 files changed, 481 insertions(+), 427 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index fcba28d3f8..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,482 @@ static const decomposed_params float64_params =3D { FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 52) }; =20 +/* Unpack a float16 to parts, but do not canonicalize. */ +static inline decomposed_parts float16_unpack_raw(float16 f) +{ + return (decomposed_parts){ + .cls =3D float_class_unclassified, + .sign =3D extract32(f, 15, 1), + .exp =3D extract32(f, 10, 5), + .frac =3D extract32(f, 0, 10) + }; +} + +/* Unpack a float32 to parts, but do not canonicalize. */ +static inline decomposed_parts float32_unpack_raw(float32 f) +{ + return (decomposed_parts){ + .cls =3D float_class_unclassified, + .sign =3D extract32(f, 31, 1), + .exp =3D extract32(f, 23, 8), + .frac =3D extract32(f, 0, 23) + }; +} + +/* Unpack a float64 to parts, but do not canonicalize. */ +static inline decomposed_parts float64_unpack_raw(float64 f) +{ + return (decomposed_parts){ + .cls =3D float_class_unclassified, + .sign =3D extract64(f, 63, 1), + .exp =3D extract64(f, 52, 11), + .frac =3D extract64(f, 0, 52), + }; +} + +/* Pack a float32 from parts, but do not canonicalize. */ +static inline float16 float16_pack_raw(decomposed_parts p) +{ + uint32_t ret =3D p.frac; + ret =3D deposit32(ret, 10, 5, p.exp); + ret =3D deposit32(ret, 15, 1, p.sign); + return make_float16(ret); +} + +/* Pack a float32 from parts, but do not canonicalize. */ +static inline float32 float32_pack_raw(decomposed_parts p) +{ + uint32_t ret =3D p.frac; + ret =3D deposit32(ret, 23, 8, p.exp); + ret =3D deposit32(ret, 31, 1, p.sign); + return make_float32(ret); +} + +/* Pack a float64 from parts, but do not canonicalize. */ +static inline float64 float64_pack_raw(decomposed_parts p) +{ + uint64_t ret =3D p.frac; + ret =3D deposit64(ret, 52, 11, p.exp); + ret =3D deposit64(ret, 63, 1, p.sign); + return make_float64(ret); +} + +/* Canonicalize EXP and FRAC, setting CLS. */ +static decomposed_parts decomposed_canonicalize(decomposed_parts part, + const decomposed_params *parm, + float_status *status) +{ + if (part.exp =3D=3D parm->exp_max) { + if (part.frac =3D=3D 0) { + part.cls =3D float_class_inf; + } else { +#ifdef NO_SIGNALING_NANS + part.cls =3D float_class_qnan; +#else + int64_t msb =3D part.frac << (parm->frac_shift + 2); + if ((msb < 0) =3D=3D status->snan_bit_is_one) { + part.cls =3D float_class_snan; + } else { + part.cls =3D float_class_qnan; + } +#endif + } + } else if (part.exp =3D=3D 0) { + if (likely(part.frac =3D=3D 0)) { + part.cls =3D float_class_zero; + } else if (status->flush_inputs_to_zero) { + float_raise(float_flag_input_denormal, status); + part.cls =3D float_class_zero; + part.frac =3D 0; + } else { + int shift =3D clz64(part.frac) - 1; + part.cls =3D float_class_normal; + part.exp =3D parm->frac_shift - parm->exp_bias - shift + 1; + part.frac <<=3D shift; + } + } else { + part.cls =3D float_class_normal; + part.exp -=3D parm->exp_bias; + part.frac =3D DECOMPOSED_IMPLICIT_BIT + (part.frac << parm->frac_s= hift); + } + return part; +} + +/* Round and uncanonicalize a floating-point number by parts. + There are FRAC_SHIFT bits that may require rounding at the bottom + of the fraction; these bits will be removed. The exponent will be + biased by EXP_BIAS and must be bounded by [EXP_MAX-1, 0]. */ +static decomposed_parts decomposed_round_canonical(decomposed_parts p, + float_status *s, + const decomposed_params= *parm) +{ + const uint64_t frac_lsbm1 =3D parm->frac_lsbm1; + const uint64_t round_mask =3D parm->round_mask; + const uint64_t roundeven_mask =3D parm->roundeven_mask; + const int exp_max =3D parm->exp_max; + const int frac_shift =3D parm->frac_shift; + uint64_t frac, inc; + int exp, flags =3D 0; + bool overflow_norm; + + frac =3D p.frac; + exp =3D p.exp; + + switch (p.cls) { + case float_class_normal: + switch (s->float_rounding_mode) { + case float_round_nearest_even: + overflow_norm =3D false; + inc =3D ((frac & roundeven_mask) !=3D frac_lsbm1 ? frac_lsbm1 = : 0); + break; + case float_round_ties_away: + overflow_norm =3D false; + inc =3D frac_lsbm1; + break; + case float_round_to_zero: + overflow_norm =3D true; + inc =3D 0; + break; + case float_round_up: + inc =3D p.sign ? 0 : round_mask; + overflow_norm =3D p.sign; + break; + case float_round_down: + inc =3D p.sign ? round_mask : 0; + overflow_norm =3D !p.sign; + break; + default: + g_assert_not_reached(); + } + + exp +=3D parm->exp_bias; + if (likely(exp > 0)) { + if (frac & round_mask) { + flags |=3D float_flag_inexact; + frac +=3D inc; + if (frac & DECOMPOSED_OVERFLOW_BIT) { + frac >>=3D 1; + exp++; + } + } + frac >>=3D frac_shift; + + if (unlikely(exp >=3D exp_max)) { + flags |=3D float_flag_overflow | float_flag_inexact; + if (overflow_norm) { + exp =3D exp_max - 1; + frac =3D -1; + } else { + p.cls =3D float_class_inf; + goto do_inf; + } + } + } else if (s->flush_to_zero) { + flags |=3D float_flag_output_denormal; + p.cls =3D float_class_zero; + goto do_zero; + } else { + bool is_tiny =3D (s->float_detect_tininess + =3D=3D float_tininess_before_rounding) + || (exp < 0) + || !((frac + inc) & DECOMPOSED_OVERFLOW_BIT); + + shift64RightJamming(frac, 1 - exp, &frac); + if (frac & round_mask) { + /* Need to recompute round-to-even. */ + if (s->float_rounding_mode =3D=3D float_round_nearest_even= ) { + inc =3D ((frac & roundeven_mask) !=3D frac_lsbm1 + ? frac_lsbm1 : 0); + } + flags |=3D float_flag_inexact; + frac +=3D inc; + } + + exp =3D (frac & DECOMPOSED_IMPLICIT_BIT ? 1 : 0); + frac >>=3D frac_shift; + + if (is_tiny && (flags & float_flag_inexact)) { + flags |=3D float_flag_underflow; + } + if (exp =3D=3D 0 && frac =3D=3D 0) { + p.cls =3D float_class_zero; + } + } + break; + + case float_class_zero: + do_zero: + exp =3D 0; + frac =3D 0; + break; + + case float_class_inf: + do_inf: + exp =3D exp_max; + frac =3D 0; + break; + + case float_class_qnan: + case float_class_snan: + exp =3D exp_max; + break; + + default: + g_assert_not_reached(); + } + + float_raise(flags, s); + p.exp =3D exp; + p.frac =3D frac; + return p; +} + +static decomposed_parts float16_unpack_canonical(float16 f, float_status *= s) +{ + return decomposed_canonicalize(float16_unpack_raw(f), &float16_params,= s); +} + +static float16 float16_round_pack_canonical(decomposed_parts p, float_stat= us *s) +{ + switch (p.cls) { + case float_class_dnan: + return float16_default_nan(s); + case float_class_msnan: + return float16_maybe_silence_nan(float16_pack_raw(p), s); + default: + p =3D decomposed_round_canonical(p, s, &float16_params); + return float16_pack_raw(p); + } +} + +static decomposed_parts float32_unpack_canonical(float32 f, float_status *= s) +{ + return decomposed_canonicalize(float32_unpack_raw(f), &float32_params,= s); +} + +static float32 float32_round_pack_canonical(decomposed_parts p, float_stat= us *s) +{ + switch (p.cls) { + case float_class_dnan: + return float32_default_nan(s); + case float_class_msnan: + return float32_maybe_silence_nan(float32_pack_raw(p), s); + default: + p =3D decomposed_round_canonical(p, s, &float32_params); + return float32_pack_raw(p); + } +} + +static decomposed_parts float64_unpack_canonical(float64 f, float_status *= s) +{ + return decomposed_canonicalize(float64_unpack_raw(f), &float64_params,= s); +} + +static float64 float64_round_pack_canonical(decomposed_parts p, float_stat= us *s) +{ + switch (p.cls) { + case float_class_dnan: + return float64_default_nan(s); + case float_class_msnan: + return float64_maybe_silence_nan(float64_pack_raw(p), s); + default: + p =3D decomposed_round_canonical(p, s, &float64_params); + return float64_pack_raw(p); + } +} + +static decomposed_parts pick_nan_parts(decomposed_parts a, decomposed_part= s b, + float_status *s) +{ + if (a.cls =3D=3D float_class_snan || b.cls =3D=3D float_class_snan) { + s->float_exception_flags |=3D float_flag_invalid; + } + + if (s->default_nan_mode) { + a.cls =3D float_class_dnan; + } else { + if (pickNaN(a.cls =3D=3D float_class_qnan, + a.cls =3D=3D float_class_snan, + b.cls =3D=3D float_class_qnan, + b.cls =3D=3D float_class_snan, + a.frac > b.frac + || (a.frac =3D=3D b.frac && a.sign < b.sign))) { + a =3D b; + } + a.cls =3D float_class_msnan; + } + return a; +} + + +/* + * Returns the result of adding the absolute values of the + * floating-point values `a' and `b'. If `subtract' is set, the sum is + * negated before being returned. `subtract' is ignored if the result + * is a NaN. The addition is performed according to the IEC/IEEE + * Standard for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts add_decomposed(decomposed_parts a, decomposed_part= s b, + bool subtract, float_status *s) +{ + bool a_sign =3D a.sign; + bool b_sign =3D b.sign ^ subtract; + + if (a_sign !=3D b_sign) { + /* Subtraction */ + + if (a.cls =3D=3D float_class_normal && b.cls =3D=3D float_class_no= rmal) { + int a_exp =3D a.exp; + int b_exp =3D b.exp; + uint64_t a_frac =3D a.frac; + uint64_t b_frac =3D b.frac; + + if (a_exp > b_exp || (a_exp =3D=3D b_exp && a_frac >=3D b_frac= )) { + shift64RightJamming(b_frac, a_exp - b_exp, &b_frac); + a_frac =3D a_frac - b_frac; + } else { + shift64RightJamming(a_frac, b_exp - a_exp, &a_frac); + a_frac =3D b_frac - a_frac; + a_exp =3D b_exp; + a_sign ^=3D 1; + } + + if (a_frac =3D=3D 0) { + a.cls =3D float_class_zero; + a.sign =3D s->float_rounding_mode =3D=3D float_round_down; + } else { + int shift =3D clz64(a_frac) - 1; + a.frac =3D a_frac << shift; + a.exp =3D a_exp - shift; + a.sign =3D a_sign; + } + return a; + } + if (a.cls >=3D float_class_qnan + || + b.cls >=3D float_class_qnan) + { + return pick_nan_parts(a, b, s); + } + if (a.cls =3D=3D float_class_inf) { + if (b.cls =3D=3D float_class_inf) { + float_raise(float_flag_invalid, s); + a.cls =3D float_class_dnan; + } + return a; + } + if (a.cls =3D=3D float_class_zero && b.cls =3D=3D float_class_zero= ) { + a.sign =3D s->float_rounding_mode =3D=3D float_round_down; + return a; + } + if (a.cls =3D=3D float_class_zero || b.cls =3D=3D float_class_inf)= { + b.sign =3D a_sign ^ 1; + return b; + } + if (b.cls =3D=3D float_class_zero) { + return a; + } + } else { + /* Addition */ + if (a.cls =3D=3D float_class_normal && b.cls =3D=3D float_class_no= rmal) { + int a_exp =3D a.exp; + int b_exp =3D b.exp; + uint64_t a_frac =3D a.frac; + uint64_t b_frac =3D b.frac; + + if (a_exp > b_exp) { + shift64RightJamming(b_frac, a_exp - b_exp, &b_frac); + } else if (a_exp < b_exp) { + shift64RightJamming(a_frac, b_exp - a_exp, &a_frac); + a_exp =3D b_exp; + } + a_frac +=3D b_frac; + if (a_frac & DECOMPOSED_OVERFLOW_BIT) { + a_frac >>=3D 1; + a_exp +=3D 1; + } + + a.exp =3D a_exp; + a.frac =3D a_frac; + return a; + } + if (a.cls >=3D float_class_qnan + || + b.cls >=3D float_class_qnan) { + return pick_nan_parts(a, b, s); + } + if (a.cls =3D=3D float_class_inf || b.cls =3D=3D float_class_zero)= { + return a; + } + if (b.cls =3D=3D float_class_inf || a.cls =3D=3D float_class_zero)= { + b.sign =3D b_sign; + return b; + } + } + g_assert_not_reached(); +} + +/* + * Returns the result of adding or subtracting the floating-point + * values `a' and `b'. The operation is performed according to the + * IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +float16 float16_add(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pb =3D float16_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, false, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_add(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pb =3D float32_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, false, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_add(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pb =3D float64_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, false, status); + + return float64_round_pack_canonical(pr, status); +} + +float16 float16_sub(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pb =3D float16_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, true, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_sub(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pb =3D float32_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, true, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_sub(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pb =3D float64_unpack_canonical(b, status); + decomposed_parts pr =3D add_decomposed(pa, pb, true, status); + + return float64_round_pack_canonical(pr, status); +} + /*------------------------------------------------------------------------= ---- | 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 @@ -2065,219 +2541,6 @@ float32 float32_round_to_int(float32 a, float_statu= s *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of adding the absolute values of the single-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -static float32 addFloat32Sigs(float32 a, float32 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint32_t aSig, bSig, zSig; - int expDiff; - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - bSig =3D extractFloat32Frac( b ); - bExp =3D extractFloat32Exp( b ); - expDiff =3D aExp - bExp; - aSig <<=3D 6; - bSig <<=3D 6; - if ( 0 < expDiff ) { - if ( aExp =3D=3D 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - --expDiff; - } - else { - bSig |=3D 0x20000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - zExp =3D aExp; - } - else if ( expDiff < 0 ) { - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp =3D=3D 0 ) { - ++expDiff; - } - else { - aSig |=3D 0x20000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - zExp =3D bExp; - } - else { - if ( aExp =3D=3D 0xFF ) { - if (aSig | bSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( aExp =3D=3D 0 ) { - if (status->flush_to_zero) { - if (aSig | bSig) { - float_raise(float_flag_output_denormal, status); - } - return packFloat32(zSign, 0, 0); - } - return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); - } - zSig =3D 0x40000000 + aSig + bSig; - zExp =3D aExp; - goto roundAndPack; - } - aSig |=3D 0x20000000; - zSig =3D ( aSig + bSig )<<1; - --zExp; - if ( (int32_t) zSig < 0 ) { - zSig =3D aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of subtracting the absolute values of the single- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -static float32 subFloat32Sigs(float32 a, float32 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint32_t aSig, bSig, zSig; - int expDiff; - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - bSig =3D extractFloat32Frac( b ); - bExp =3D extractFloat32Exp( b ); - expDiff =3D aExp - bExp; - aSig <<=3D 7; - bSig <<=3D 7; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp =3D=3D 0xFF ) { - if (aSig | bSig) { - return propagateFloat32NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - if ( aExp =3D=3D 0 ) { - aExp =3D 1; - bExp =3D 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat32(status->float_rounding_mode =3D=3D float_round_down= , 0, 0); - bExpBigger: - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign ^ 1, 0xFF, 0 ); - } - if ( aExp =3D=3D 0 ) { - ++expDiff; - } - else { - aSig |=3D 0x40000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - bSig |=3D 0x40000000; - bBigger: - zSig =3D bSig - aSig; - zExp =3D bExp; - zSign ^=3D 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp =3D=3D 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - --expDiff; - } - else { - bSig |=3D 0x40000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - aSig |=3D 0x40000000; - aBigger: - zSig =3D aSig - bSig; - zExp =3D aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat32(zSign, zExp, zSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of adding the single-precision floating-point values = `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard = for -| Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_add(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign; - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - aSign =3D extractFloat32Sign( a ); - bSign =3D extractFloat32Sign( b ); - if ( aSign =3D=3D bSign ) { - return addFloat32Sigs(a, b, aSign, status); - } - else { - return subFloat32Sigs(a, b, aSign, status); - } - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of subtracting the single-precision floating-point va= lues -| `a' and `b'. The operation is performed according to the IEC/IEEE Stand= ard -| for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_sub(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign; - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - aSign =3D extractFloat32Sign( a ); - bSign =3D extractFloat32Sign( b ); - if ( aSign =3D=3D bSign ) { - return subFloat32Sigs(a, b, aSign, status); - } - else { - return addFloat32Sigs(a, b, aSign, status); - } - -} =20 /*------------------------------------------------------------------------= ---- | Returns the result of multiplying the single-precision floating-point va= lues @@ -3875,219 +4138,6 @@ float64 float64_trunc_to_int(float64 a, float_statu= s *status) return res; } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of adding the absolute values of the double-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -static float64 addFloat64Sigs(float64 a, float64 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig; - int expDiff; - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - bSig =3D extractFloat64Frac( b ); - bExp =3D extractFloat64Exp( b ); - expDiff =3D aExp - bExp; - aSig <<=3D 9; - bSig <<=3D 9; - if ( 0 < expDiff ) { - if ( aExp =3D=3D 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - --expDiff; - } - else { - bSig |=3D LIT64( 0x2000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - zExp =3D aExp; - } - else if ( expDiff < 0 ) { - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp =3D=3D 0 ) { - ++expDiff; - } - else { - aSig |=3D LIT64( 0x2000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - zExp =3D bExp; - } - else { - if ( aExp =3D=3D 0x7FF ) { - if (aSig | bSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( aExp =3D=3D 0 ) { - if (status->flush_to_zero) { - if (aSig | bSig) { - float_raise(float_flag_output_denormal, status); - } - return packFloat64(zSign, 0, 0); - } - return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); - } - zSig =3D LIT64( 0x4000000000000000 ) + aSig + bSig; - zExp =3D aExp; - goto roundAndPack; - } - aSig |=3D LIT64( 0x2000000000000000 ); - zSig =3D ( aSig + bSig )<<1; - --zExp; - if ( (int64_t) zSig < 0 ) { - zSig =3D aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat64(zSign, zExp, zSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of subtracting the absolute values of the double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -static float64 subFloat64Sigs(float64 a, float64 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig; - int expDiff; - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - bSig =3D extractFloat64Frac( b ); - bExp =3D extractFloat64Exp( b ); - expDiff =3D aExp - bExp; - aSig <<=3D 10; - bSig <<=3D 10; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp =3D=3D 0x7FF ) { - if (aSig | bSig) { - return propagateFloat64NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - if ( aExp =3D=3D 0 ) { - aExp =3D 1; - bExp =3D 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat64(status->float_rounding_mode =3D=3D float_round_down= , 0, 0); - bExpBigger: - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign ^ 1, 0x7FF, 0 ); - } - if ( aExp =3D=3D 0 ) { - ++expDiff; - } - else { - aSig |=3D LIT64( 0x4000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - bSig |=3D LIT64( 0x4000000000000000 ); - bBigger: - zSig =3D bSig - aSig; - zExp =3D bExp; - zSign ^=3D 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp =3D=3D 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( bExp =3D=3D 0 ) { - --expDiff; - } - else { - bSig |=3D LIT64( 0x4000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - aSig |=3D LIT64( 0x4000000000000000 ); - aBigger: - zSig =3D aSig - bSig; - zExp =3D aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat64(zSign, zExp, zSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of adding the double-precision floating-point values = `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard = for -| Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_add(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign; - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - - aSign =3D extractFloat64Sign( a ); - bSign =3D extractFloat64Sign( b ); - if ( aSign =3D=3D bSign ) { - return addFloat64Sigs(a, b, aSign, status); - } - else { - return subFloat64Sigs(a, b, aSign, status); - } - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of subtracting the double-precision floating-point va= lues -| `a' and `b'. The operation is performed according to the IEC/IEEE Stand= ard -| for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_sub(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign; - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - - aSign =3D extractFloat64Sign( a ); - bSign =3D extractFloat64Sign( b ); - if ( aSign =3D=3D bSign ) { - return subFloat64Sigs(a, b, aSign, status); - } - else { - return addFloat64Sigs(a, b, aSign, status); - } - -} =20 /*------------------------------------------------------------------------= ---- | Returns the result of multiplying the double-precision floating-point va= lues diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index e64bf62f3d..3a21a2bcef 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -318,6 +318,10 @@ float64 float16_to_float64(float16 a, flag ieee, float= _status *status); /*------------------------------------------------------------------------= ---- | Software half-precision operations. *-------------------------------------------------------------------------= ---*/ + +float16 float16_add(float16, float16, float_status *status); +float16 float16_sub(float16, float16, float_status *status); + int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); float16 float16_maybe_silence_nan(float16, float_status *status); --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501007545405.3235975736201; Tue, 9 Jan 2018 04:30:07 -0800 (PST) Received: from localhost ([::1]:49524 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt2Z-0003RA-Di for importer@patchew.org; Tue, 09 Jan 2018 07:30:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51497) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvu-0006jB-BA for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvs-0006vB-5Y for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:10 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:35866) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvr-0006ro-Rh for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:08 -0500 Received: by mail-wr0-x243.google.com with SMTP id b76so13906746wrd.3 for ; Tue, 09 Jan 2018 04:23:07 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id i65sm33419352wme.20.2018.01.09.04.22.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:22:59 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 067E93E2B4F; Tue, 9 Jan 2018 12:22:53 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mJy0Ou8oHgPU1r6rmJO8Ul+ReONVCxYllLdFXdtsb1M=; b=Rh361zc3XLZAvoMSqwzsjUAqK2yH33Eghnu+Q5Vw+DS7FGoy57Qsx2pOVzwL+JZgyV z7dbvy4AJqKQ0Y8W4yPHwsw9/5a75Qdp1k5bPMTc9lWT+ShB5QWhfgiZC5Q5tCx6Ds18 shG1fQyzFCnVN6xyZbqHPvj5uzR6MLeOCTSVc= 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=mJy0Ou8oHgPU1r6rmJO8Ul+ReONVCxYllLdFXdtsb1M=; b=p8kXm1jcksSGd+3JYRRVcqIOl2xq3wT/1zLAkImlPlZUnl1xF8V2kiY3vosJkJcZR5 EhTqc7/FAEBXnp3aw8dK8zp0boOf/VbQ70kdFlLNhEeMjaIlyBfpQ/GCLfYKLF1366DP xCrDzK2j31rB2aSxYSfR0Qw8SMBnvJDQAp60gyxOVbI3WDcrLpvur+0EpJJESWUSShJy bRqLim3R8w8HfzYOf4pFNCG+37RQz71Ay9DNgtTuqrUVPhVvLsaxX87I5/T1F8OoIkDB 9yYcAJXerrufu81k+ZpJXVTDoaWvbSf0RZre+kuEyES6gp9vDIOXMUI79pNTWzopUsY9 Sk4g== X-Gm-Message-State: AKGB3mKKu9BCsnpIEgut9lmB2DYbLSjrN2bUNDv6pAHs93RvwNhgKwYw nFy1vLsRVCaC/2iJIbYUSHUVZw== X-Google-Smtp-Source: ACJfBovOSkfnZqEghTSEp6bAH29iP49QEqFHa9Rbct0jMrTxKBhUTLzao03VB6/UzsGUI66vmYz78w== X-Received: by 10.223.137.1 with SMTP id s1mr9833991wrs.53.1515500586666; Tue, 09 Jan 2018 04:23:06 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:44 +0000 Message-Id: <20180109122252.17670-13-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::243 Subject: [Qemu-devel] [PATCH v2 12/20] fpu/softfloat: re-factor mul X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We can now add float16_mul and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 versions. Signed-off-by: Alex Benn=C3=A9e Signed-off-by: Richard Henderson Signed-off-by: Richard Henderson --- fpu/softfloat.c | 207 ++++++++++++++++++--------------------------= ---- include/fpu/softfloat.h | 1 + 2 files changed, 80 insertions(+), 128 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index f89e47e3ef..6e9d4c172c 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -730,6 +730,85 @@ float64 float64_sub(float64 a, float64 b, float_status= *status) return float64_round_pack_canonical(pr, status); } =20 +/* + * Returns the result of multiplying the floating-point values `a' and + * `b'. The operation is performed according to the IEC/IEEE Standard + * for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts mul_decomposed(decomposed_parts a, decomposed_part= s b, + float_status *s) +{ + bool sign =3D a.sign ^ b.sign; + + if (a.cls =3D=3D float_class_normal && b.cls =3D=3D float_class_normal= ) { + uint64_t hi, lo; + int exp =3D a.exp + b.exp; + + mul64To128(a.frac, b.frac, &hi, &lo); + shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, &hi, &lo); + if (lo & DECOMPOSED_OVERFLOW_BIT) { + shift64RightJamming(lo, 1, &lo); + exp +=3D 1; + } + + /* Re-use a */ + a.exp =3D exp; + a.sign =3D sign; + a.frac =3D lo; + return a; + } + /* handle all the NaN cases */ + if (a.cls >=3D float_class_qnan || b.cls >=3D float_class_qnan) { + return pick_nan_parts(a, b, s); + } + /* Inf * Zero =3D=3D NaN */ + if (((1 << a.cls) | (1 << b.cls)) =3D=3D + ((1 << float_class_inf) | (1 << float_class_zero))) { + s->float_exception_flags |=3D float_flag_invalid; + a.cls =3D float_class_dnan; + a.sign =3D sign; + return a; + } + /* Multiply by 0 or Inf */ + if (a.cls =3D=3D float_class_inf || a.cls =3D=3D float_class_zero) { + a.sign =3D sign; + return a; + } + if (b.cls =3D=3D float_class_inf || b.cls =3D=3D float_class_zero) { + b.sign =3D sign; + return b; + } + g_assert_not_reached(); +} + +float16 float16_mul(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pb =3D float16_unpack_canonical(b, status); + decomposed_parts pr =3D mul_decomposed(pa, pb, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_mul(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pb =3D float32_unpack_canonical(b, status); + decomposed_parts pr =3D mul_decomposed(pa, pb, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_mul(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pb =3D float64_unpack_canonical(b, status); + decomposed_parts pr =3D mul_decomposed(pa, pb, status); + + return float64_round_pack_canonical(pr, status); +} + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -2542,70 +2621,6 @@ float32 float32_round_to_int(float32 a, float_status= *status) } =20 =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of multiplying the single-precision floating-point va= lues -| `a' and `b'. The operation is performed according to the IEC/IEEE Stand= ard -| for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_mul(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint32_t aSig, bSig; - uint64_t zSig64; - uint32_t zSig; - - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - bSig =3D extractFloat32Frac( b ); - bExp =3D extractFloat32Exp( b ); - bSign =3D extractFloat32Sign( b ); - zSign =3D aSign ^ bSign; - if ( aExp =3D=3D 0xFF ) { - if ( aSig || ( ( bExp =3D=3D 0xFF ) && bSig ) ) { - return propagateFloat32NaN(a, b, status); - } - if ( ( bExp | bSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - if ( ( aExp | aSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - zExp =3D aExp + bExp - 0x7F; - aSig =3D ( aSig | 0x00800000 )<<7; - bSig =3D ( bSig | 0x00800000 )<<8; - shift64RightJamming( ( (uint64_t) aSig ) * bSig, 32, &zSig64 ); - zSig =3D zSig64; - if ( 0 <=3D (int32_t) ( zSig<<1 ) ) { - zSig <<=3D 1; - --zExp; - } - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} =20 /*------------------------------------------------------------------------= ---- | Returns the result of dividing the single-precision floating-point value= `a' @@ -4138,70 +4153,6 @@ float64 float64_trunc_to_int(float64 a, float_status= *status) return res; } =20 - -/*------------------------------------------------------------------------= ---- -| Returns the result of multiplying the double-precision floating-point va= lues -| `a' and `b'. The operation is performed according to the IEC/IEEE Stand= ard -| for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_mul(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig0, zSig1; - - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - bSig =3D extractFloat64Frac( b ); - bExp =3D extractFloat64Exp( b ); - bSign =3D extractFloat64Sign( b ); - zSign =3D aSign ^ bSign; - if ( aExp =3D=3D 0x7FF ) { - if ( aSig || ( ( bExp =3D=3D 0x7FF ) && bSig ) ) { - return propagateFloat64NaN(a, b, status); - } - if ( ( bExp | bSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - if ( ( aExp | aSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - zExp =3D aExp + bExp - 0x3FF; - aSig =3D ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig =3D ( bSig | LIT64( 0x0010000000000000 ) )<<11; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - zSig0 |=3D ( zSig1 !=3D 0 ); - if ( 0 <=3D (int64_t) ( zSig0<<1 ) ) { - zSig0 <<=3D 1; - --zExp; - } - return roundAndPackFloat64(zSign, zExp, zSig0, status); - -} - /*------------------------------------------------------------------------= ---- | Returns the result of dividing the double-precision floating-point value= `a' | by the corresponding value `b'. The operation is performed according to diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 3a21a2bcef..cfee28061e 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -321,6 +321,7 @@ float64 float16_to_float64(float16 a, flag ieee, float_= status *status); =20 float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); +float16 float16_mul(float16, float16, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501237512669.9987568023847; Tue, 9 Jan 2018 04:33:57 -0800 (PST) Received: from localhost ([::1]:49545 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt6K-0006i0-FD for importer@patchew.org; Tue, 09 Jan 2018 07:33:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53761) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt15-0002ag-Tv for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYt12-0002BV-K4 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:31 -0500 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:35695) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYt12-0002AK-9y for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:28 -0500 Received: by mail-wm0-x243.google.com with SMTP id a79so20274124wma.0 for ; Tue, 09 Jan 2018 04:28:28 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id g78sm18974127wmc.30.2018.01.09.04.28.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:28:24 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 1A75C3E2B50; Tue, 9 Jan 2018 12:22:53 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gY4Pw0/J5CvztqQ5CA9vHCcbOrXRpr6mRK8t/cdEnK8=; b=Zvyc9ZttOXz+zby7Iqbe5w8g6+iP0vCaayN8yEhUUPjZACrBiI7DSGOao5+bXV+BEG HK6Om5UwkNZkWMxHo92Dmhjry3nNqpH3KpCWA4xohydhFI4DTQEpuymjRbApS1cIvqhp /kC7yvix2RrMQilYx3u9WTBfDeYLwf32P8JXA= 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=gY4Pw0/J5CvztqQ5CA9vHCcbOrXRpr6mRK8t/cdEnK8=; b=AZ/u8UBcCJU27qGgFU2WkYowmOZUi4+K38zMr0At6tvU4JRnLm4Zt5fhu7V/NDImwu tMPBCdbAe8ur//PwHl30+YVDsEjwIq4gpYCGlT/T16YgcqfHxhPSUKU2k395oH53XFlE +u8+lBob5d2TjL/imYQbqSTEdAILiW6XNLe+C0L1GsXunJkE0nxZlPGlmpVUevugduLa tX2nMGGz0EVfkMsM89WHadPT/010ai4o5iwyga3vJSJZpQ3hZI5W0q0LdPtA1V8u8Evw dCRqy3YE+gjvnRxJMYNlgryyHU4Hhceg/VVpGYLWtXclEcy7EPjB+1VbHJHOPjEJGEq3 +akw== X-Gm-Message-State: AKGB3mJx8psmYPs+IiY12GvjDAqM+qigQjzNQK0h7p3uObem1lZmMJJp ePjeJqDN1CQN3VoOYJQg1pp6Fw== X-Google-Smtp-Source: ACJfBovXVCEhyLGDEkUUG8XWhO9cPOBfdh0rlussiCVFuIVNnltZ7LTsrXp2l/1hyhUfZjkYQ2tkIg== X-Received: by 10.28.87.146 with SMTP id l140mr11109805wmb.86.1515500907035; Tue, 09 Jan 2018 04:28:27 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:45 +0000 Message-Id: <20180109122252.17670-14-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::243 Subject: [Qemu-devel] [PATCH v2 13/20] fpu/softfloat: re-factor div X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We can now add float16_div and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 versions. Signed-off-by: Alex Benn=C3=A9e Signed-off-by: Richard Henderson --- fpu/softfloat-macros.h | 44 +++++++++ fpu/softfloat.c | 235 ++++++++++++++++++--------------------------= ---- include/fpu/softfloat.h | 1 + 3 files changed, 134 insertions(+), 146 deletions(-) diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h index 9cc6158cb4..980be2c051 100644 --- a/fpu/softfloat-macros.h +++ b/fpu/softfloat-macros.h @@ -625,6 +625,50 @@ static uint64_t estimateDiv128To64( uint64_t a0, uint6= 4_t a1, uint64_t b ) =20 } =20 +/* Nicked from gmp longlong.h __udiv_qrnnd */ +static uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d) +{ + uint64_t d0, d1, q0, q1, r1, r0, m; + + d0 =3D (uint32_t)d; + d1 =3D d >> 32; + + r1 =3D n1 % d1; + q1 =3D n1 / d1; + m =3D q1 * d0; + r1 =3D (r1 << 32) | (n0 >> 32); + if (r1 < m) { + q1 -=3D 1; + r1 +=3D d; + if (r1 >=3D d) { + if (r1 < m) { + q1 -=3D 1; + r1 +=3D d; + } + } + } + r1 -=3D m; + + r0 =3D r1 % d1; + q0 =3D r1 / d1; + m =3D q0 * d0; + r0 =3D (r0 << 32) | (uint32_t)n0; + if (r0 < m) { + q0 -=3D 1; + r0 +=3D d; + if (r0 >=3D d) { + if (r0 < m) { + q0 -=3D 1; + r0 +=3D d; + } + } + } + r0 -=3D m; + + /* Return remainder in LSB */ + return (q1 << 32) | q0 | (r0 !=3D 0); +} + /*------------------------------------------------------------------------= ---- | Returns an approximation to the square root of the 32-bit significand gi= ven | by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 = of diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6e9d4c172c..2b703c12ed 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -809,6 +809,95 @@ float64 float64_mul(float64 a, float64 b, float_status= *status) return float64_round_pack_canonical(pr, status); } =20 +/* + * Returns the result of dividing the floating-point value `a' by the + * corresponding value `b'. The operation is performed according to + * the IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts div_decomposed(decomposed_parts a, decomposed_part= s b, + float_status *s) +{ + bool sign =3D a.sign ^ b.sign; + + if (a.cls =3D=3D float_class_normal && b.cls =3D=3D float_class_normal= ) { + uint64_t temp_lo, temp_hi; + int exp =3D a.exp - b.exp; + if (a.frac < b.frac) { + exp -=3D 1; + shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT + 1, + &temp_hi, &temp_lo); + } else { + shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT, + &temp_hi, &temp_lo); + } + /* LSB of quot is set if inexact which roundandpack will use + * to set flags. Yet again we re-use a for the result */ + a.frac =3D div128To64(temp_lo, temp_hi, b.frac); + a.sign =3D sign; + a.exp =3D exp; + return a; + } + /* handle all the NaN cases */ + if (a.cls >=3D float_class_qnan || b.cls >=3D float_class_qnan) { + return pick_nan_parts(a, b, s); + } + /* 0/0 or Inf/Inf */ + if (a.cls =3D=3D b.cls + && + (a.cls =3D=3D float_class_inf || a.cls =3D=3D float_class_zero)) { + s->float_exception_flags |=3D float_flag_invalid; + a.cls =3D float_class_dnan; + return a; + } + /* Div 0 =3D> Inf */ + if (b.cls =3D=3D float_class_zero) { + s->float_exception_flags |=3D float_flag_divbyzero; + a.cls =3D float_class_inf; + a.sign =3D sign; + return a; + } + /* Inf / x or 0 / x */ + if (a.cls =3D=3D float_class_inf || a.cls =3D=3D float_class_zero) { + a.sign =3D sign; + return a; + } + /* Div by Inf */ + if (b.cls =3D=3D float_class_inf) { + a.cls =3D float_class_zero; + a.sign =3D sign; + return a; + } + g_assert_not_reached(); +} + +float16 float16_div(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pb =3D float16_unpack_canonical(b, status); + decomposed_parts pr =3D div_decomposed(pa, pb, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_div(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pb =3D float32_unpack_canonical(b, status); + decomposed_parts pr =3D div_decomposed(pa, pb, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_div(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pb =3D float64_unpack_canonical(b, status); + decomposed_parts pr =3D div_decomposed(pa, pb, status); + + return float64_round_pack_canonical(pr, status); +} + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -2622,75 +2711,6 @@ float32 float32_round_to_int(float32 a, float_status= *status) =20 =20 =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of dividing the single-precision floating-point value= `a' -| by the corresponding value `b'. The operation is performed according to= the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_div(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint32_t aSig, bSig, zSig; - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - bSig =3D extractFloat32Frac( b ); - bExp =3D extractFloat32Exp( b ); - bSign =3D extractFloat32Sign( b ); - zSign =3D aSign ^ bSign; - if ( aExp =3D=3D 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp =3D=3D 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign, 0, 0 ); - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) { - if ( ( aExp | aSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - float_raise(float_flag_divbyzero, status); - return packFloat32( zSign, 0xFF, 0 ); - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp =3D aExp - bExp + 0x7D; - aSig =3D ( aSig | 0x00800000 )<<7; - bSig =3D ( bSig | 0x00800000 )<<8; - if ( bSig <=3D ( aSig + aSig ) ) { - aSig >>=3D 1; - ++zExp; - } - zSig =3D ( ( (uint64_t) aSig )<<32 ) / bSig; - if ( ( zSig & 0x3F ) =3D=3D 0 ) { - zSig |=3D ( (uint64_t) bSig * zSig !=3D ( (uint64_t) aSig )<<32 ); - } - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} =20 /*------------------------------------------------------------------------= ---- | Returns the remainder of the single-precision floating-point value `a' @@ -4153,83 +4173,6 @@ float64 float64_trunc_to_int(float64 a, float_status= *status) return res; } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of dividing the double-precision floating-point value= `a' -| by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_div(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig; - uint64_t rem0, rem1; - uint64_t term0, term1; - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - bSig =3D extractFloat64Frac( b ); - bExp =3D extractFloat64Exp( b ); - bSign =3D extractFloat64Sign( b ); - zSign =3D aSign ^ bSign; - if ( aExp =3D=3D 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp =3D=3D 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign, 0, 0 ); - } - if ( bExp =3D=3D 0 ) { - if ( bSig =3D=3D 0 ) { - if ( ( aExp | aSig ) =3D=3D 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - float_raise(float_flag_divbyzero, status); - return packFloat64( zSign, 0x7FF, 0 ); - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp =3D=3D 0 ) { - if ( aSig =3D=3D 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp =3D aExp - bExp + 0x3FD; - aSig =3D ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig =3D ( bSig | LIT64( 0x0010000000000000 ) )<<11; - if ( bSig <=3D ( aSig + aSig ) ) { - aSig >>=3D 1; - ++zExp; - } - zSig =3D estimateDiv128To64( aSig, 0, bSig ); - if ( ( zSig & 0x1FF ) <=3D 2 ) { - mul64To128( bSig, zSig, &term0, &term1 ); - sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (int64_t) rem0 < 0 ) { - --zSig; - add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); - } - zSig |=3D ( rem1 !=3D 0 ); - } - return roundAndPackFloat64(zSign, zExp, zSig, status); - -} =20 /*------------------------------------------------------------------------= ---- | Returns the remainder of the double-precision floating-point value `a' diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index cfee28061e..335f199bb6 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -322,6 +322,7 @@ float64 float16_to_float64(float16 a, flag ieee, float_= status *status); float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); float16 float16_mul(float16, float16, float_status *status); +float16 float16_div(float16, float16, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501575366750.5086137194427; Tue, 9 Jan 2018 04:39:35 -0800 (PST) Received: from localhost ([::1]:49740 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYtBk-0002vY-FA for importer@patchew.org; Tue, 09 Jan 2018 07:39:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51537) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsvy-0006mC-LQ for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvv-00072D-1b for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:14 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:47025) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvu-0006zp-Kr for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:10 -0500 Received: by mail-wr0-x243.google.com with SMTP id g21so8109890wrb.13 for ; Tue, 09 Jan 2018 04:23:10 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id i71sm16650160wmd.1.2018.01.09.04.22.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:23:07 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 2F2CB3E2B51; Tue, 9 Jan 2018 12:22:53 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zmNIouwe1+7YZQyIGNBXgw1pykG59RbUL33SXn0AUAw=; b=a+Zv/0ptBq3rMwm4oc3xQrQVWsk4gYqarXeTl4Z9uz9XRv+29KpLLlDjW3bE8R0wd2 fU469ddckdeg6WVLPtIR7MtMWdcHSoYbBGK//aeQ/jheAG3KWIYFO/A6Ktq56zNMHXGB xvG6HzTic6WaDt/2tBgJlTayHh++wJOjrO8z8= 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=zmNIouwe1+7YZQyIGNBXgw1pykG59RbUL33SXn0AUAw=; b=bch34GKtj3rgJJk8+fo8GDup9OcPEKCfbSmJLyHEsgS/FC157bqx43EM3z3eeMwRGv MNTFl02C8QTwYEd67LX98BYf+5APTbowL8I7u3YWmNm8mr5gt29KA4OSg7AgikfALp07 wxp2MHVElJ2tm7KLZlP2pJ7bBGkGGWiVxSCabwMfD9YvaukZ7I/KQ++43/zh5HDgk8Sv KgfYMsvYdVMMplvDKatUVNrM/PhgrsZbOd09opEe7ETFlIcZRDdXUTUXMeEisNY3T3Io zGDO3tatyLJrepT8ecibSk4Wa+z/UeIJhfUAFWfXDPV/3rwg8ImU+MkEuu4htOM6y2kR 6b/g== X-Gm-Message-State: AKGB3mJpE13L8PbKuDxJfmwgZMEbx89kaycQdkCwonntrRXKWwU/KVZq jEIjnvOkOigMdDfr1nl4X6/wcw== X-Google-Smtp-Source: ACJfBouHr78ksECLdVbCZPkTD1YqHHiA/M7bJX4B4sl/5p/UTl3jnRPOIbpTZug0X6r6N1ovsoJOEQ== X-Received: by 10.223.139.24 with SMTP id n24mr5012659wra.23.1515500589031; Tue, 09 Jan 2018 04:23:09 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:46 +0000 Message-Id: <20180109122252.17670-15-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::243 Subject: [Qemu-devel] [PATCH v2 14/20] fpu/softfloat: re-factor muladd X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We can now add float16_muladd and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 muladd functions. Signed-off-by: Alex Benn=C3=A9e Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell --- fpu/softfloat-specialize.h | 104 ------- fpu/softfloat.c | 756 +++++++++++++++++------------------------= ---- include/fpu/softfloat.h | 1 + 3 files changed, 286 insertions(+), 575 deletions(-) diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 3d507d8c77..98fb0e7001 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -729,58 +729,6 @@ static float32 propagateFloat32NaN(float32 a, float32 = b, float_status *status) } } =20 -/*------------------------------------------------------------------------= ---- -| Takes three single-precision floating-point values `a', `b' and `c', one= of -| which is a NaN, and returns the appropriate NaN result. If any of `a', -| `b' or `c' is a signaling NaN, the invalid exception is raised. -| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case -| obviously c is a NaN, and whether to propagate c or some other NaN is -| implementation defined). -*-------------------------------------------------------------------------= ---*/ - -static float32 propagateFloat32MulAddNaN(float32 a, float32 b, - float32 c, flag infzero, - float_status *status) -{ - flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN; - int which; - - aIsQuietNaN =3D float32_is_quiet_nan(a, status); - aIsSignalingNaN =3D float32_is_signaling_nan(a, status); - bIsQuietNaN =3D float32_is_quiet_nan(b, status); - bIsSignalingNaN =3D float32_is_signaling_nan(b, status); - cIsQuietNaN =3D float32_is_quiet_nan(c, status); - cIsSignalingNaN =3D float32_is_signaling_nan(c, status); - - if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { - float_raise(float_flag_invalid, status); - } - - which =3D pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN, - bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN, infzero, status); - - if (status->default_nan_mode) { - /* Note that this check is after pickNaNMulAdd so that function - * has an opportunity to set the Invalid flag. - */ - return float32_default_nan(status); - } - - switch (which) { - case 0: - return float32_maybe_silence_nan(a, status); - case 1: - return float32_maybe_silence_nan(b, status); - case 2: - return float32_maybe_silence_nan(c, status); - case 3: - default: - return float32_default_nan(status); - } -} - #ifdef NO_SIGNALING_NANS int float64_is_quiet_nan(float64 a_, float_status *status) { @@ -936,58 +884,6 @@ static float64 propagateFloat64NaN(float64 a, float64 = b, float_status *status) } } =20 -/*------------------------------------------------------------------------= ---- -| Takes three double-precision floating-point values `a', `b' and `c', one= of -| which is a NaN, and returns the appropriate NaN result. If any of `a', -| `b' or `c' is a signaling NaN, the invalid exception is raised. -| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case -| obviously c is a NaN, and whether to propagate c or some other NaN is -| implementation defined). -*-------------------------------------------------------------------------= ---*/ - -static float64 propagateFloat64MulAddNaN(float64 a, float64 b, - float64 c, flag infzero, - float_status *status) -{ - flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN; - int which; - - aIsQuietNaN =3D float64_is_quiet_nan(a, status); - aIsSignalingNaN =3D float64_is_signaling_nan(a, status); - bIsQuietNaN =3D float64_is_quiet_nan(b, status); - bIsSignalingNaN =3D float64_is_signaling_nan(b, status); - cIsQuietNaN =3D float64_is_quiet_nan(c, status); - cIsSignalingNaN =3D float64_is_signaling_nan(c, status); - - if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { - float_raise(float_flag_invalid, status); - } - - which =3D pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN, - bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN, infzero, status); - - if (status->default_nan_mode) { - /* Note that this check is after pickNaNMulAdd so that function - * has an opportunity to set the Invalid flag. - */ - return float64_default_nan(status); - } - - switch (which) { - case 0: - return float64_maybe_silence_nan(a, status); - case 1: - return float64_maybe_silence_nan(b, status); - case 2: - return float64_maybe_silence_nan(c, status); - case 3: - default: - return float64_default_nan(status); - } -} - #ifdef NO_SIGNALING_NANS int floatx80_is_quiet_nan(floatx80 a_, float_status *status) { diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 2b703c12ed..84386f354b 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -561,6 +561,50 @@ static decomposed_parts pick_nan_parts(decomposed_part= s a, decomposed_parts b, return a; } =20 +static decomposed_parts pick_nan_muladd_parts(decomposed_parts a, + decomposed_parts b, + decomposed_parts c, + bool inf_zero, + float_status *s) +{ + if (a.cls =3D=3D float_class_snan + || + b.cls =3D=3D float_class_snan + || + c.cls =3D=3D float_class_snan) { + s->float_exception_flags |=3D float_flag_invalid; + } + + if (s->default_nan_mode) { + a.cls =3D float_class_dnan; + } else { + switch (pickNaNMulAdd(a.cls =3D=3D float_class_qnan, + a.cls =3D=3D float_class_snan, + b.cls =3D=3D float_class_qnan, + b.cls =3D=3D float_class_snan, + c.cls =3D=3D float_class_qnan, + c.cls =3D=3D float_class_snan, + inf_zero, s)) { + case 0: + break; + case 1: + a =3D b; + break; + case 2: + a =3D c; + break; + case 3: + a.cls =3D float_class_dnan; + return a; + default: + g_assert_not_reached(); + } + + a.cls =3D float_class_msnan; + } + return a; +} + =20 /* * Returns the result of adding the absolute values of the @@ -809,6 +853,247 @@ float64 float64_mul(float64 a, float64 b, float_statu= s *status) return float64_round_pack_canonical(pr, status); } =20 +/* + * Returns the result of multiplying the floating-point values `a' and + * `b' then adding 'c', with no intermediate rounding step after the + * multiplication. The operation is performed according to the + * IEC/IEEE Standard for Binary Floating-Point Arithmetic 754-2008. + * The flags argument allows the caller to select negation of the + * addend, the intermediate product, or the final result. (The + * difference between this and having the caller do a separate + * negation is that negating externally will flip the sign bit on + * NaNs.) + */ + +static decomposed_parts muladd_decomposed(decomposed_parts a, + decomposed_parts b, + decomposed_parts c, int flags, + float_status *s) +{ + bool inf_zero =3D ((1 << a.cls) | (1 << b.cls)) =3D=3D + ((1 << float_class_inf) | (1 << float_class_zero)); + bool p_sign; + bool sign_flip =3D flags & float_muladd_negate_result; + float_class p_class; + uint64_t hi, lo; + int p_exp; + + /* It is implementation-defined whether the cases of (0,inf,qnan) + * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN + * they return if they do), so we have to hand this information + * off to the target-specific pick-a-NaN routine. + */ + if (a.cls >=3D float_class_qnan || + b.cls >=3D float_class_qnan || + c.cls >=3D float_class_qnan) { + return pick_nan_muladd_parts(a, b, c, inf_zero, s); + } + + if (inf_zero) { + s->float_exception_flags |=3D float_flag_invalid; + a.cls =3D float_class_dnan; + return a; + } + + if (flags & float_muladd_negate_c) { + c.sign ^=3D 1; + } + + p_sign =3D a.sign ^ b.sign; + + if (flags & float_muladd_negate_product) { + p_sign ^=3D 1; + } + + if (a.cls =3D=3D float_class_inf || b.cls =3D=3D float_class_inf) { + p_class =3D float_class_inf; + } else if (a.cls =3D=3D float_class_zero || b.cls =3D=3D float_class_z= ero) { + p_class =3D float_class_zero; + } else { + p_class =3D float_class_normal; + } + + if (c.cls =3D=3D float_class_inf) { + if (p_class =3D=3D float_class_inf && p_sign !=3D c.sign) { + s->float_exception_flags |=3D float_flag_invalid; + a.cls =3D float_class_dnan; + } else { + a.cls =3D float_class_inf; + a.sign =3D c.sign ^ sign_flip; + } + return a; + } + + if (p_class =3D=3D float_class_inf) { + a.cls =3D float_class_inf; + a.sign =3D p_sign ^ sign_flip; + return a; + } + + if (p_class =3D=3D float_class_zero) { + if (c.cls =3D=3D float_class_zero) { + if (p_sign !=3D c.sign) { + p_sign =3D s->float_rounding_mode =3D=3D float_round_down; + } + c.sign =3D p_sign; + } else if (flags & float_muladd_halve_result) { + c.exp -=3D 1; + } + c.sign ^=3D sign_flip; + return c; + } + + /* a & b should be normals now... */ + assert(a.cls =3D=3D float_class_normal && + b.cls =3D=3D float_class_normal); + + p_exp =3D a.exp + b.exp; + + /* Multiply of 2 62-bit numbers produces a (2*62) =3D=3D 124-bit + * result. + */ + mul64To128(a.frac, b.frac, &hi, &lo); + /* binary point now at bit 124 */ + + /* check for overflow */ + if (hi & (1ULL << (DECOMPOSED_BINARY_POINT * 2 + 1 - 64))) { + shift128RightJamming(hi, lo, 1, &hi, &lo); + p_exp +=3D 1; + } + + /* + add/sub */ + if (c.cls =3D=3D float_class_zero) { + /* move binary point back to 62 */ + shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, &hi, &lo); + } else { + int exp_diff =3D p_exp - c.exp; + if (p_sign =3D=3D c.sign) { + /* Addition */ + if (exp_diff <=3D 0) { + shift128RightJamming(hi, lo, + DECOMPOSED_BINARY_POINT - exp_diff, + &hi, &lo); + lo +=3D c.frac; + p_exp =3D c.exp; + } else { + uint64_t c_hi, c_lo; + /* shift c to the same binary point as the product (124) */ + c_hi =3D c.frac >> 2; + c_lo =3D 0; + shift128RightJamming(c_hi, c_lo, + exp_diff, + &c_hi, &c_lo); + add128(hi, lo, c_hi, c_lo, &hi, &lo); + /* move binary point back to 62 */ + shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, &hi,= &lo); + } + + if (lo & DECOMPOSED_OVERFLOW_BIT) { + shift64RightJamming(lo, 1, &lo); + p_exp +=3D 1; + } + + } else { + /* Subtraction */ + uint64_t c_hi, c_lo; + /* make C binary point match product at bit 124 */ + c_hi =3D c.frac >> 2; + c_lo =3D 0; + + if (exp_diff <=3D 0) { + shift128RightJamming(hi, lo, -exp_diff, &hi, &lo); + if (exp_diff =3D=3D 0 + && + (hi > c_hi || (hi =3D=3D c_hi && lo >=3D c_lo))) { + sub128(hi, lo, c_hi, c_lo, &hi, &lo); + } else { + sub128(c_hi, c_lo, hi, lo, &hi, &lo); + p_sign ^=3D 1; + p_exp =3D c.exp; + } + } else { + shift128RightJamming(c_hi, c_lo, + exp_diff, + &c_hi, &c_lo); + sub128(hi, lo, c_hi, c_lo, &hi, &lo); + } + + if (hi =3D=3D 0 && lo =3D=3D 0) { + a.cls =3D float_class_zero; + a.sign =3D s->float_rounding_mode =3D=3D float_round_down; + a.sign ^=3D sign_flip; + return a; + } else { + int shift; + if (hi !=3D 0) { + shift =3D clz64(hi); + } else { + shift =3D clz64(lo) + 64; + } + /* Normalizing to a binary point of 124 is the + correct adjust for the exponent. However since we're + shifting, we might as well put the binary point back + at 62 where we really want it. Therefore shift as + if we're leaving 1 bit at the top of the word, but + adjust the exponent as if we're leaving 3 bits. */ + shift -=3D 1; + if (shift >=3D 64) { + lo =3D lo << (shift - 64); + } else { + hi =3D (hi << shift) | (lo >> (64 - shift)); + lo =3D hi | ((lo << shift) !=3D 0); + } + p_exp -=3D shift - 2; + } + } + } + + if (flags & float_muladd_halve_result) { + p_exp -=3D 1; + } + + /* finally prepare our result */ + a.cls =3D float_class_normal; + a.sign =3D p_sign ^ sign_flip; + a.exp =3D p_exp; + a.frac =3D lo; + + return a; +} + +float16 float16_muladd(float16 a, float16 b, float16 c, int flags, + float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pb =3D float16_unpack_canonical(b, status); + decomposed_parts pc =3D float16_unpack_canonical(c, status); + decomposed_parts pr =3D muladd_decomposed(pa, pb, pc, flags, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_muladd(float32 a, float32 b, float32 c, int flags, + float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pb =3D float32_unpack_canonical(b, status); + decomposed_parts pc =3D float32_unpack_canonical(c, status); + decomposed_parts pr =3D muladd_decomposed(pa, pb, pc, flags, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_muladd(float64 a, float64 b, float64 c, int flags, + float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pb =3D float64_unpack_canonical(b, status); + decomposed_parts pc =3D float64_unpack_canonical(c, status); + decomposed_parts pr =3D muladd_decomposed(pa, pb, pc, flags, status); + + return float64_round_pack_canonical(pr, status); +} + /* * Returns the result of dividing the floating-point value `a' by the * corresponding value `b'. The operation is performed according to @@ -2814,231 +3099,6 @@ float32 float32_rem(float32 a, float32 b, float_sta= tus *status) return normalizeRoundAndPackFloat32(aSign ^ zSign, bExp, aSig, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of multiplying the single-precision floating-point va= lues -| `a' and `b' then adding 'c', with no intermediate rounding step after the -| multiplication. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic 754-2008. -| The flags argument allows the caller to select negation of the -| addend, the intermediate product, or the final result. (The difference -| between this and having the caller do a separate negation is that negati= ng -| externally will flip the sign bit on NaNs.) -*-------------------------------------------------------------------------= ---*/ - -float32 float32_muladd(float32 a, float32 b, float32 c, int flags, - float_status *status) -{ - flag aSign, bSign, cSign, zSign; - int aExp, bExp, cExp, pExp, zExp, expDiff; - uint32_t aSig, bSig, cSig; - flag pInf, pZero, pSign; - uint64_t pSig64, cSig64, zSig64; - uint32_t pSig; - int shiftcount; - flag signflip, infzero; - - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - c =3D float32_squash_input_denormal(c, status); - aSig =3D extractFloat32Frac(a); - aExp =3D extractFloat32Exp(a); - aSign =3D extractFloat32Sign(a); - bSig =3D extractFloat32Frac(b); - bExp =3D extractFloat32Exp(b); - bSign =3D extractFloat32Sign(b); - cSig =3D extractFloat32Frac(c); - cExp =3D extractFloat32Exp(c); - cSign =3D extractFloat32Sign(c); - - infzero =3D ((aExp =3D=3D 0 && aSig =3D=3D 0 && bExp =3D=3D 0xff && bS= ig =3D=3D 0) || - (aExp =3D=3D 0xff && aSig =3D=3D 0 && bExp =3D=3D 0 && bSig= =3D=3D 0)); - - /* It is implementation-defined whether the cases of (0,inf,qnan) - * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN - * they return if they do), so we have to hand this information - * off to the target-specific pick-a-NaN routine. - */ - if (((aExp =3D=3D 0xff) && aSig) || - ((bExp =3D=3D 0xff) && bSig) || - ((cExp =3D=3D 0xff) && cSig)) { - return propagateFloat32MulAddNaN(a, b, c, infzero, status); - } - - if (infzero) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - - if (flags & float_muladd_negate_c) { - cSign ^=3D 1; - } - - signflip =3D (flags & float_muladd_negate_result) ? 1 : 0; - - /* Work out the sign and type of the product */ - pSign =3D aSign ^ bSign; - if (flags & float_muladd_negate_product) { - pSign ^=3D 1; - } - pInf =3D (aExp =3D=3D 0xff) || (bExp =3D=3D 0xff); - pZero =3D ((aExp | aSig) =3D=3D 0) || ((bExp | bSig) =3D=3D 0); - - if (cExp =3D=3D 0xff) { - if (pInf && (pSign ^ cSign)) { - /* addition of opposite-signed infinities =3D> InvalidOperatio= n */ - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - /* Otherwise generate an infinity of the same sign */ - return packFloat32(cSign ^ signflip, 0xff, 0); - } - - if (pInf) { - return packFloat32(pSign ^ signflip, 0xff, 0); - } - - if (pZero) { - if (cExp =3D=3D 0) { - if (cSig =3D=3D 0) { - /* Adding two exact zeroes */ - if (pSign =3D=3D cSign) { - zSign =3D pSign; - } else if (status->float_rounding_mode =3D=3D float_round_= down) { - zSign =3D 1; - } else { - zSign =3D 0; - } - return packFloat32(zSign ^ signflip, 0, 0); - } - /* Exact zero plus a denorm */ - if (status->flush_to_zero) { - float_raise(float_flag_output_denormal, status); - return packFloat32(cSign ^ signflip, 0, 0); - } - } - /* Zero plus something non-zero : just return the something */ - if (flags & float_muladd_halve_result) { - if (cExp =3D=3D 0) { - normalizeFloat32Subnormal(cSig, &cExp, &cSig); - } - /* Subtract one to halve, and one again because roundAndPackFl= oat32 - * wants one less than the true exponent. - */ - cExp -=3D 2; - cSig =3D (cSig | 0x00800000) << 7; - return roundAndPackFloat32(cSign ^ signflip, cExp, cSig, statu= s); - } - return packFloat32(cSign ^ signflip, cExp, cSig); - } - - if (aExp =3D=3D 0) { - normalizeFloat32Subnormal(aSig, &aExp, &aSig); - } - if (bExp =3D=3D 0) { - normalizeFloat32Subnormal(bSig, &bExp, &bSig); - } - - /* Calculate the actual result a * b + c */ - - /* Multiply first; this is easy. */ - /* NB: we subtract 0x7e where float32_mul() subtracts 0x7f - * because we want the true exponent, not the "one-less-than" - * flavour that roundAndPackFloat32() takes. - */ - pExp =3D aExp + bExp - 0x7e; - aSig =3D (aSig | 0x00800000) << 7; - bSig =3D (bSig | 0x00800000) << 8; - pSig64 =3D (uint64_t)aSig * bSig; - if ((int64_t)(pSig64 << 1) >=3D 0) { - pSig64 <<=3D 1; - pExp--; - } - - zSign =3D pSign ^ signflip; - - /* Now pSig64 is the significand of the multiply, with the explicit bi= t in - * position 62. - */ - if (cExp =3D=3D 0) { - if (!cSig) { - /* Throw out the special case of c being an exact zero now */ - shift64RightJamming(pSig64, 32, &pSig64); - pSig =3D pSig64; - if (flags & float_muladd_halve_result) { - pExp--; - } - return roundAndPackFloat32(zSign, pExp - 1, - pSig, status); - } - normalizeFloat32Subnormal(cSig, &cExp, &cSig); - } - - cSig64 =3D (uint64_t)cSig << (62 - 23); - cSig64 |=3D LIT64(0x4000000000000000); - expDiff =3D pExp - cExp; - - if (pSign =3D=3D cSign) { - /* Addition */ - if (expDiff > 0) { - /* scale c to match p */ - shift64RightJamming(cSig64, expDiff, &cSig64); - zExp =3D pExp; - } else if (expDiff < 0) { - /* scale p to match c */ - shift64RightJamming(pSig64, -expDiff, &pSig64); - zExp =3D cExp; - } else { - /* no scaling needed */ - zExp =3D cExp; - } - /* Add significands and make sure explicit bit ends up in posn 62 = */ - zSig64 =3D pSig64 + cSig64; - if ((int64_t)zSig64 < 0) { - shift64RightJamming(zSig64, 1, &zSig64); - } else { - zExp--; - } - } else { - /* Subtraction */ - if (expDiff > 0) { - shift64RightJamming(cSig64, expDiff, &cSig64); - zSig64 =3D pSig64 - cSig64; - zExp =3D pExp; - } else if (expDiff < 0) { - shift64RightJamming(pSig64, -expDiff, &pSig64); - zSig64 =3D cSig64 - pSig64; - zExp =3D cExp; - zSign ^=3D 1; - } else { - zExp =3D pExp; - if (cSig64 < pSig64) { - zSig64 =3D pSig64 - cSig64; - } else if (pSig64 < cSig64) { - zSig64 =3D cSig64 - pSig64; - zSign ^=3D 1; - } else { - /* Exact zero */ - zSign =3D signflip; - if (status->float_rounding_mode =3D=3D float_round_down) { - zSign ^=3D 1; - } - return packFloat32(zSign, 0, 0); - } - } - --zExp; - /* Normalize to put the explicit bit back into bit 62. */ - shiftcount =3D countLeadingZeros64(zSig64) - 1; - zSig64 <<=3D shiftcount; - zExp -=3D shiftcount; - } - if (flags & float_muladd_halve_result) { - zExp--; - } - - shift64RightJamming(zSig64, 32, &zSig64); - return roundAndPackFloat32(zSign, zExp, zSig64, status); -} - =20 /*------------------------------------------------------------------------= ---- | Returns the square root of the single-precision floating-point value `a'. @@ -4262,252 +4322,6 @@ float64 float64_rem(float64 a, float64 b, float_sta= tus *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of multiplying the double-precision floating-point va= lues -| `a' and `b' then adding 'c', with no intermediate rounding step after the -| multiplication. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic 754-2008. -| The flags argument allows the caller to select negation of the -| addend, the intermediate product, or the final result. (The difference -| between this and having the caller do a separate negation is that negati= ng -| externally will flip the sign bit on NaNs.) -*-------------------------------------------------------------------------= ---*/ - -float64 float64_muladd(float64 a, float64 b, float64 c, int flags, - float_status *status) -{ - flag aSign, bSign, cSign, zSign; - int aExp, bExp, cExp, pExp, zExp, expDiff; - uint64_t aSig, bSig, cSig; - flag pInf, pZero, pSign; - uint64_t pSig0, pSig1, cSig0, cSig1, zSig0, zSig1; - int shiftcount; - flag signflip, infzero; - - a =3D float64_squash_input_denormal(a, status); - b =3D float64_squash_input_denormal(b, status); - c =3D float64_squash_input_denormal(c, status); - aSig =3D extractFloat64Frac(a); - aExp =3D extractFloat64Exp(a); - aSign =3D extractFloat64Sign(a); - bSig =3D extractFloat64Frac(b); - bExp =3D extractFloat64Exp(b); - bSign =3D extractFloat64Sign(b); - cSig =3D extractFloat64Frac(c); - cExp =3D extractFloat64Exp(c); - cSign =3D extractFloat64Sign(c); - - infzero =3D ((aExp =3D=3D 0 && aSig =3D=3D 0 && bExp =3D=3D 0x7ff && b= Sig =3D=3D 0) || - (aExp =3D=3D 0x7ff && aSig =3D=3D 0 && bExp =3D=3D 0 && bSi= g =3D=3D 0)); - - /* It is implementation-defined whether the cases of (0,inf,qnan) - * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN - * they return if they do), so we have to hand this information - * off to the target-specific pick-a-NaN routine. - */ - if (((aExp =3D=3D 0x7ff) && aSig) || - ((bExp =3D=3D 0x7ff) && bSig) || - ((cExp =3D=3D 0x7ff) && cSig)) { - return propagateFloat64MulAddNaN(a, b, c, infzero, status); - } - - if (infzero) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - - if (flags & float_muladd_negate_c) { - cSign ^=3D 1; - } - - signflip =3D (flags & float_muladd_negate_result) ? 1 : 0; - - /* Work out the sign and type of the product */ - pSign =3D aSign ^ bSign; - if (flags & float_muladd_negate_product) { - pSign ^=3D 1; - } - pInf =3D (aExp =3D=3D 0x7ff) || (bExp =3D=3D 0x7ff); - pZero =3D ((aExp | aSig) =3D=3D 0) || ((bExp | bSig) =3D=3D 0); - - if (cExp =3D=3D 0x7ff) { - if (pInf && (pSign ^ cSign)) { - /* addition of opposite-signed infinities =3D> InvalidOperatio= n */ - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - /* Otherwise generate an infinity of the same sign */ - return packFloat64(cSign ^ signflip, 0x7ff, 0); - } - - if (pInf) { - return packFloat64(pSign ^ signflip, 0x7ff, 0); - } - - if (pZero) { - if (cExp =3D=3D 0) { - if (cSig =3D=3D 0) { - /* Adding two exact zeroes */ - if (pSign =3D=3D cSign) { - zSign =3D pSign; - } else if (status->float_rounding_mode =3D=3D float_round_= down) { - zSign =3D 1; - } else { - zSign =3D 0; - } - return packFloat64(zSign ^ signflip, 0, 0); - } - /* Exact zero plus a denorm */ - if (status->flush_to_zero) { - float_raise(float_flag_output_denormal, status); - return packFloat64(cSign ^ signflip, 0, 0); - } - } - /* Zero plus something non-zero : just return the something */ - if (flags & float_muladd_halve_result) { - if (cExp =3D=3D 0) { - normalizeFloat64Subnormal(cSig, &cExp, &cSig); - } - /* Subtract one to halve, and one again because roundAndPackFl= oat64 - * wants one less than the true exponent. - */ - cExp -=3D 2; - cSig =3D (cSig | 0x0010000000000000ULL) << 10; - return roundAndPackFloat64(cSign ^ signflip, cExp, cSig, statu= s); - } - return packFloat64(cSign ^ signflip, cExp, cSig); - } - - if (aExp =3D=3D 0) { - normalizeFloat64Subnormal(aSig, &aExp, &aSig); - } - if (bExp =3D=3D 0) { - normalizeFloat64Subnormal(bSig, &bExp, &bSig); - } - - /* Calculate the actual result a * b + c */ - - /* Multiply first; this is easy. */ - /* NB: we subtract 0x3fe where float64_mul() subtracts 0x3ff - * because we want the true exponent, not the "one-less-than" - * flavour that roundAndPackFloat64() takes. - */ - pExp =3D aExp + bExp - 0x3fe; - aSig =3D (aSig | LIT64(0x0010000000000000))<<10; - bSig =3D (bSig | LIT64(0x0010000000000000))<<11; - mul64To128(aSig, bSig, &pSig0, &pSig1); - if ((int64_t)(pSig0 << 1) >=3D 0) { - shortShift128Left(pSig0, pSig1, 1, &pSig0, &pSig1); - pExp--; - } - - zSign =3D pSign ^ signflip; - - /* Now [pSig0:pSig1] is the significand of the multiply, with the expl= icit - * bit in position 126. - */ - if (cExp =3D=3D 0) { - if (!cSig) { - /* Throw out the special case of c being an exact zero now */ - shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1); - if (flags & float_muladd_halve_result) { - pExp--; - } - return roundAndPackFloat64(zSign, pExp - 1, - pSig1, status); - } - normalizeFloat64Subnormal(cSig, &cExp, &cSig); - } - - /* Shift cSig and add the explicit bit so [cSig0:cSig1] is the - * significand of the addend, with the explicit bit in position 126. - */ - cSig0 =3D cSig << (126 - 64 - 52); - cSig1 =3D 0; - cSig0 |=3D LIT64(0x4000000000000000); - expDiff =3D pExp - cExp; - - if (pSign =3D=3D cSign) { - /* Addition */ - if (expDiff > 0) { - /* scale c to match p */ - shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); - zExp =3D pExp; - } else if (expDiff < 0) { - /* scale p to match c */ - shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); - zExp =3D cExp; - } else { - /* no scaling needed */ - zExp =3D cExp; - } - /* Add significands and make sure explicit bit ends up in posn 126= */ - add128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - if ((int64_t)zSig0 < 0) { - shift128RightJamming(zSig0, zSig1, 1, &zSig0, &zSig1); - } else { - zExp--; - } - shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1); - if (flags & float_muladd_halve_result) { - zExp--; - } - return roundAndPackFloat64(zSign, zExp, zSig1, status); - } else { - /* Subtraction */ - if (expDiff > 0) { - shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); - sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - zExp =3D pExp; - } else if (expDiff < 0) { - shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); - sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); - zExp =3D cExp; - zSign ^=3D 1; - } else { - zExp =3D pExp; - if (lt128(cSig0, cSig1, pSig0, pSig1)) { - sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - } else if (lt128(pSig0, pSig1, cSig0, cSig1)) { - sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); - zSign ^=3D 1; - } else { - /* Exact zero */ - zSign =3D signflip; - if (status->float_rounding_mode =3D=3D float_round_down) { - zSign ^=3D 1; - } - return packFloat64(zSign, 0, 0); - } - } - --zExp; - /* Do the equivalent of normalizeRoundAndPackFloat64() but - * starting with the significand in a pair of uint64_t. - */ - if (zSig0) { - shiftcount =3D countLeadingZeros64(zSig0) - 1; - shortShift128Left(zSig0, zSig1, shiftcount, &zSig0, &zSig1); - if (zSig1) { - zSig0 |=3D 1; - } - zExp -=3D shiftcount; - } else { - shiftcount =3D countLeadingZeros64(zSig1); - if (shiftcount =3D=3D 0) { - zSig0 =3D (zSig1 >> 1) | (zSig1 & 1); - zExp -=3D 63; - } else { - shiftcount--; - zSig0 =3D zSig1 << shiftcount; - zExp -=3D (shiftcount + 64); - } - } - if (flags & float_muladd_halve_result) { - zExp--; - } - return roundAndPackFloat64(zSign, zExp, zSig0, status); - } -} =20 /*------------------------------------------------------------------------= ---- | Returns the square root of the double-precision floating-point value `a'. diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 335f199bb6..c92147abec 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -322,6 +322,7 @@ float64 float16_to_float64(float16 a, flag ieee, float_= status *status); float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); float16 float16_mul(float16, float16, float_status *status); +float16 float16_muladd(float16, float16, float16, int, float_status *statu= s); float16 float16_div(float16, float16, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501917564162.5928438989207; Tue, 9 Jan 2018 04:45:17 -0800 (PST) Received: from localhost ([::1]:50140 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYtHI-0007qW-4z for importer@patchew.org; Tue, 09 Jan 2018 07:45:16 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53760) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt15-0002af-TE for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYt11-0002AS-Q8 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:31 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:35900) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYt11-00029k-Gg for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:27 -0500 Received: by mail-wr0-x244.google.com with SMTP id b76so13921202wrd.3 for ; Tue, 09 Jan 2018 04:28:27 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id u10sm3386560wrg.6.2018.01.09.04.28.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:28:24 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 413673E2B52; Tue, 9 Jan 2018 12:22:53 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gZUuItoMCkv+JpgUBtuyfqdsiVU3EEiyMFXhGaZpH1Q=; b=ksV13FY2AZwbWWJWL4N+43vtRcRjVrmkUDhVnt1dzqmg2wokNW8Rdl++Li27xKY+TQ R8iodj0rzMy+sZUo2aHb/v37NJOz9ky8o1n5u0k3IRF6RvPGTDHEzLYGB1NbxByCgN17 u9tufjJF3Lxxf70wiElq7JYZOTpcdghE4fKls= 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=gZUuItoMCkv+JpgUBtuyfqdsiVU3EEiyMFXhGaZpH1Q=; b=UlkysYx+ohbfXBo3nEwVi7G/Y0S0DHXQ/QfHhBShVnOi2RElrQfhSJFCFL3dB/YBEN I82yD+PhnvkzKcEWQIEoWlOWWo1Qyicj25KKyTuAAG08166BgpWxfoRWP+4Nzw0XpKHK mJG92JgSz4UOloTGU5Rx7C+hgiUg9+6K2CcUAD48vrDVRnWZ46BU+NcjfTyiS1ZC+Y+N pfS1MhohMH5bmJ9R3UDffjyJclFTpGGp2KgwvQ+O5OOa4kukjigsV3gljsO5l5/2FoH9 J/RIMvKgp9SigNMqOKbrfcKXvvEj9zdvHqS3E4uexombIg2e1sQoXFH42DbAMxrwCXX7 RrPg== X-Gm-Message-State: AKGB3mLskenDFb12l9rm2+5hdUyI6at/TUd2grc0ehKENsiRoQLXoY+c TSDJEm5CQmBpZe3BKFNvPFnmOA== X-Google-Smtp-Source: ACJfBovDzZCSIguHjmviIp9d3I9X9dIroB/jcHTEacsh3f5+FnwjYGNjXbaP0Iq2bwEShQF1Pr0teg== X-Received: by 10.223.160.139 with SMTP id m11mr13092185wrm.119.1515500906249; Tue, 09 Jan 2018 04:28:26 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:47 +0000 Message-Id: <20180109122252.17670-16-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PATCH v2 15/20] fpu/softfloat: re-factor round_to_int X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We can now add float16_round_to_int and use the common round_decomposed and canonicalize functions to have a single implementation for float16/32/64 round_to_int functions. Signed-off-by: Alex Benn=C3=A9e Signed-off-by: Richard Henderson --- fpu/softfloat.c | 304 ++++++++++++++++++++------------------------= ---- include/fpu/softfloat.h | 1 + 2 files changed, 130 insertions(+), 175 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 84386f354b..edc35300d1 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1183,6 +1183,135 @@ float64 float64_div(float64 a, float64 b, float_sta= tus *status) return float64_round_pack_canonical(pr, status); } =20 +/* + * Rounds the floating-point value `a' to an integer, and returns the + * result as a floating-point value. The operation is performed + * according to the IEC/IEEE Standard for Binary Floating-Point + * Arithmetic. + */ + +static decomposed_parts round_decomposed(decomposed_parts a, int rounding_= mode, + float_status *s) +{ + + switch (a.cls) { + case float_class_snan: + a.cls =3D s->default_nan_mode ? float_class_dnan : float_class_msn= an; + s->float_exception_flags |=3D float_flag_invalid; + break; + case float_class_zero: + case float_class_inf: + case float_class_qnan: + /* already "integral" */ + break; + case float_class_normal: + if (a.exp >=3D DECOMPOSED_BINARY_POINT) { + /* already integral */ + break; + } + if (a.exp < 0) { + bool one; + /* all fractional */ + s->float_exception_flags |=3D float_flag_inexact; + switch (rounding_mode) { + case float_round_nearest_even: + one =3D a.exp =3D=3D -1 && a.frac > DECOMPOSED_IMPLICIT_BI= T; + break; + case float_round_ties_away: + one =3D a.exp =3D=3D -1 && a.frac >=3D DECOMPOSED_IMPLICIT= _BIT; + break; + case float_round_to_zero: + one =3D false; + break; + case float_round_up: + one =3D !a.sign; + break; + case float_round_down: + one =3D a.sign; + break; + default: + g_assert_not_reached(); + } + + if (one) { + a.frac =3D DECOMPOSED_IMPLICIT_BIT; + a.exp =3D 0; + } else { + a.cls =3D float_class_zero; + } + } else { + uint64_t frac_lsb, frac_lsbm1, round_mask, roundeven_mask, inc; + + frac_lsb =3D DECOMPOSED_IMPLICIT_BIT >> a.exp; + frac_lsbm1 =3D frac_lsb >> 1; + roundeven_mask =3D (frac_lsb - 1) | frac_lsb; + round_mask =3D roundeven_mask >> 1; + + switch (rounding_mode) { + case float_round_nearest_even: + inc =3D ((a.frac & roundeven_mask) !=3D frac_lsbm1 ? frac_= lsbm1 : 0); + break; + case float_round_ties_away: + inc =3D frac_lsbm1; + break; + case float_round_to_zero: + inc =3D 0; + break; + case float_round_up: + inc =3D a.sign ? 0 : round_mask; + break; + case float_round_down: + inc =3D a.sign ? round_mask : 0; + break; + default: + g_assert_not_reached(); + } + + if (a.frac & round_mask) { + s->float_exception_flags |=3D float_flag_inexact; + a.frac +=3D inc; + a.frac &=3D ~round_mask; + if (a.frac & DECOMPOSED_OVERFLOW_BIT) { + a.frac >>=3D 1; + a.exp++; + } + } + } + break; + default: + g_assert_not_reached(); + } + return a; +} + +float16 float16_round_to_int(float16 a, float_status *s) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, s); + decomposed_parts pr =3D round_decomposed(pa, s->float_rounding_mode, s= ); + return float16_round_pack_canonical(pr, s); +} + +float32 float32_round_to_int(float32 a, float_status *s) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, s); + decomposed_parts pr =3D round_decomposed(pa, s->float_rounding_mode, s= ); + return float32_round_pack_canonical(pr, s); +} + +float64 float64_round_to_int(float64 a, float_status *s) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, s); + decomposed_parts pr =3D round_decomposed(pa, s->float_rounding_mode, s= ); + return float64_round_pack_canonical(pr, s); +} + +float64 float64_trunc_to_int(float64 a, float_status *s) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, s); + decomposed_parts pr =3D round_decomposed(pa, float_round_to_zero, s); + return float64_round_pack_canonical(pr, s); +} + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -2913,88 +3042,6 @@ float128 float32_to_float128(float32 a, float_status= *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Rounds the single-precision floating-point value `a' to an integer, and -| returns the result as a single-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 float32_round_to_int(float32 a, float_status *status) -{ - flag aSign; - int aExp; - uint32_t lastBitMask, roundBitsMask; - uint32_t z; - a =3D float32_squash_input_denormal(a, status); - - aExp =3D extractFloat32Exp( a ); - if ( 0x96 <=3D aExp ) { - if ( ( aExp =3D=3D 0xFF ) && extractFloat32Frac( a ) ) { - return propagateFloat32NaN(a, a, status); - } - return a; - } - if ( aExp <=3D 0x7E ) { - if ( (uint32_t) ( float32_val(a)<<1 ) =3D=3D 0 ) return a; - status->float_exception_flags |=3D float_flag_inexact; - aSign =3D extractFloat32Sign( a ); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - if ( ( aExp =3D=3D 0x7E ) && extractFloat32Frac( a ) ) { - return packFloat32( aSign, 0x7F, 0 ); - } - break; - case float_round_ties_away: - if (aExp =3D=3D 0x7E) { - return packFloat32(aSign, 0x7F, 0); - } - break; - case float_round_down: - return make_float32(aSign ? 0xBF800000 : 0); - case float_round_up: - return make_float32(aSign ? 0x80000000 : 0x3F800000); - } - return packFloat32( aSign, 0, 0 ); - } - lastBitMask =3D 1; - lastBitMask <<=3D 0x96 - aExp; - roundBitsMask =3D lastBitMask - 1; - z =3D float32_val(a); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - z +=3D lastBitMask>>1; - if ((z & roundBitsMask) =3D=3D 0) { - z &=3D ~lastBitMask; - } - break; - case float_round_ties_away: - z +=3D lastBitMask >> 1; - break; - case float_round_to_zero: - break; - case float_round_up: - if (!extractFloat32Sign(make_float32(z))) { - z +=3D roundBitsMask; - } - break; - case float_round_down: - if (extractFloat32Sign(make_float32(z))) { - z +=3D roundBitsMask; - } - break; - default: - abort(); - } - z &=3D ~ roundBitsMask; - if (z !=3D float32_val(a)) { - status->float_exception_flags |=3D float_flag_inexact; - } - return make_float32(z); - -} - - =20 =20 /*------------------------------------------------------------------------= ---- @@ -4140,99 +4187,6 @@ float128 float64_to_float128(float64 a, float_status= *status) =20 } =20 -/*------------------------------------------------------------------------= ---- -| Rounds the double-precision floating-point value `a' to an integer, and -| returns the result as a double-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 float64_round_to_int(float64 a, float_status *status) -{ - flag aSign; - int aExp; - uint64_t lastBitMask, roundBitsMask; - uint64_t z; - a =3D float64_squash_input_denormal(a, status); - - aExp =3D extractFloat64Exp( a ); - if ( 0x433 <=3D aExp ) { - if ( ( aExp =3D=3D 0x7FF ) && extractFloat64Frac( a ) ) { - return propagateFloat64NaN(a, a, status); - } - return a; - } - if ( aExp < 0x3FF ) { - if ( (uint64_t) ( float64_val(a)<<1 ) =3D=3D 0 ) return a; - status->float_exception_flags |=3D float_flag_inexact; - aSign =3D extractFloat64Sign( a ); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - if ( ( aExp =3D=3D 0x3FE ) && extractFloat64Frac( a ) ) { - return packFloat64( aSign, 0x3FF, 0 ); - } - break; - case float_round_ties_away: - if (aExp =3D=3D 0x3FE) { - return packFloat64(aSign, 0x3ff, 0); - } - break; - case float_round_down: - return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0); - case float_round_up: - return make_float64( - aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF000000000000= 0 )); - } - return packFloat64( aSign, 0, 0 ); - } - lastBitMask =3D 1; - lastBitMask <<=3D 0x433 - aExp; - roundBitsMask =3D lastBitMask - 1; - z =3D float64_val(a); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - z +=3D lastBitMask >> 1; - if ((z & roundBitsMask) =3D=3D 0) { - z &=3D ~lastBitMask; - } - break; - case float_round_ties_away: - z +=3D lastBitMask >> 1; - break; - case float_round_to_zero: - break; - case float_round_up: - if (!extractFloat64Sign(make_float64(z))) { - z +=3D roundBitsMask; - } - break; - case float_round_down: - if (extractFloat64Sign(make_float64(z))) { - z +=3D roundBitsMask; - } - break; - default: - abort(); - } - z &=3D ~ roundBitsMask; - if (z !=3D float64_val(a)) { - status->float_exception_flags |=3D float_flag_inexact; - } - return make_float64(z); - -} - -float64 float64_trunc_to_int(float64 a, float_status *status) -{ - int oldmode; - float64 res; - oldmode =3D status->float_rounding_mode; - status->float_rounding_mode =3D float_round_to_zero; - res =3D float64_round_to_int(a, status); - status->float_rounding_mode =3D oldmode; - return res; -} - =20 /*------------------------------------------------------------------------= ---- | Returns the remainder of the double-precision floating-point value `a' diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index c92147abec..6427762a9a 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -319,6 +319,7 @@ float64 float16_to_float64(float16 a, flag ieee, float_= status *status); | Software half-precision operations. *-------------------------------------------------------------------------= ---*/ =20 +float16 float16_round_to_int(float16, float_status *status); float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); float16 float16_mul(float16, float16, float_status *status); --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151550127895769.18158448843815; Tue, 9 Jan 2018 04:34:38 -0800 (PST) Received: from localhost ([::1]:49546 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt6z-0007CY-Vy for importer@patchew.org; Tue, 09 Jan 2018 07:34:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51548) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsw0-0006nY-45 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYsvw-000755-8Y for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:16 -0500 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:39250) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYsvv-00072X-R3 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:23:12 -0500 Received: by mail-wm0-x244.google.com with SMTP id i11so20234682wmf.4 for ; Tue, 09 Jan 2018 04:23:11 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id e132sm15904984wmd.40.2018.01.09.04.22.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:23:07 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 54A8F3E2B53; Tue, 9 Jan 2018 12:22:53 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gFxawPFfcFKLqcrR8t9RlmB5BzbYkhcyH3KPgWXjRvs=; b=DPvpyoGRnM/6wV9f5FfRWY3by/vD5hTEYBtcEb4Xp2tVg7ooz9wpLdECjmm7LfnWEr Tu/CH3GgXuPnzjrraMK82YKzNjbNXYmci6ja+iUXONRIRaFMHV2JvYj/uNk523OlcF8U ho53o8W5+71dQJthlKJwEM8XFuOlmAcrnw92E= 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=gFxawPFfcFKLqcrR8t9RlmB5BzbYkhcyH3KPgWXjRvs=; b=mJMhxgi7e6DX69QTSWDWDmysxSbU6ZX//HM7nZl34TuCEH5k2/p9ufwRpOQVPHQYki DRmnQN2ALhgY/saPVo07BW8cvlgUo1nn5ucw230/VCBkUali6IQ2Mxw9L173kSbVJxtf 3+4b73tlaEG9ldRPSbkqNL+zOxM51KCr+tLNW/QV225XKzNMXrSRteGjsRWXh8uzbm0q ZGUV66BJdfMe/Tm6VttcNKIBiGQXiQK0SI79yi8m3cDG+uJqbAkIqlNCld/dfDbxvHoY 4e8WIMADSD2gydPLGcSjH6YpPQFwOKVKkuF8Q87NwatMxgXeJ+yBvaABZaVg2He1xDi/ faSg== X-Gm-Message-State: AKGB3mKgCCYEMc2P451eliIS7MNWyj7ZhX9cbBqmG9WP/bxMqQ3TaGx0 uyab/0bSlJEmOCuuQ7OGAvHjRg== X-Google-Smtp-Source: ACJfBovOl3UTax0Jl4w04jOOCPEfNQUFes7odeCZ5Mgf+FwfvVFasuO1EUTM2q8aSgwG9+xW+V1gTQ== X-Received: by 10.28.132.207 with SMTP id g198mr11412114wmd.118.1515500590112; Tue, 09 Jan 2018 04:23:10 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:48 +0000 Message-Id: <20180109122252.17670-17-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::244 Subject: [Qemu-devel] [PATCH v2 16/20] fpu/softfloat: re-factor float to int/uint X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 We share the common int64/uint64_pack_decomposed function across all the helpers and simply limit the final result depending on the final size. Signed-off-by: Alex Benn=C3=A9e -- v2 - apply float_flg_invalid fixes next patch Reviewed-by: Richard Henderson --- fpu/softfloat.c | 1011 +++++++++++--------------------------------= ---- include/fpu/softfloat.h | 13 + 2 files changed, 235 insertions(+), 789 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index edc35300d1..514f43c065 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1312,6 +1312,194 @@ float64 float64_trunc_to_int(float64 a, float_statu= s *s) return float64_round_pack_canonical(pr, s); } =20 +/*------------------------------------------------------------------------= ---- +| Returns the result of converting the floating-point value +| `a' to the two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. Otherwise, if the conversion overflows, t= he +| largest integer with the same sign as `a' is returned. +*-------------------------------------------------------------------------= ---*/ + +static int64_t int64_pack_decomposed(decomposed_parts p, float_status *s) +{ + uint64_t r; + + switch (p.cls) { + case float_class_snan: + case float_class_qnan: + return INT64_MAX; + case float_class_inf: + return p.sign ? INT64_MIN : INT64_MAX; + case float_class_zero: + return 0; + case float_class_normal: + if (p.exp < DECOMPOSED_BINARY_POINT) { + r =3D p.frac >> (DECOMPOSED_BINARY_POINT - p.exp); + } else if (p.exp < 64) { + r =3D p.frac << (p.exp - DECOMPOSED_BINARY_POINT); + } else { + s->float_exception_flags |=3D float_flag_invalid; + r =3D UINT64_MAX; + } + if (p.sign) { + return r < - (uint64_t) INT64_MIN ? -r : INT64_MIN; + } else { + return r < INT64_MAX ? r : INT64_MAX; + } + default: + g_assert_not_reached(); + } +} + +static int16_t int16_pack_decomposed(decomposed_parts p, float_status *s) +{ + int64_t r =3D int64_pack_decomposed(p, s); + if (r < INT16_MIN) { + s->float_exception_flags |=3D float_flag_invalid; + return INT16_MIN; + } else if (r > INT16_MAX) { + s->float_exception_flags |=3D float_flag_invalid; + return INT16_MAX; + } + return r; +} + +static int32_t int32_pack_decomposed(decomposed_parts p, float_status *s) +{ + int64_t r =3D int64_pack_decomposed(p, s); + if (r < INT32_MIN) { + s->float_exception_flags |=3D float_flag_invalid; + return INT32_MIN; + } else if (r > INT32_MAX) { + s->float_exception_flags |=3D float_flag_invalid; + return INT32_MAX; + } + return r; +} + +#define FLOAT_TO_INT(fsz, isz) \ +int ## isz ## _t float ## fsz ## _to_int ## isz(float ## fsz a, float_stat= us *s) \ +{ \ + decomposed_parts pa =3D float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr =3D round_decomposed(pa, s->float_rounding_mode, s= ); \ + return int ## isz ## _pack_decomposed(pr, s); \ +} \ + \ +int ## isz ## _t float ## fsz ## _to_int ## isz ## _round_to_zero \ + (float ## fsz a, float_status *s) \ +{ \ + decomposed_parts pa =3D float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr =3D round_decomposed(pa, float_round_to_zero, s); \ + return int ## isz ## _pack_decomposed(pr, s); \ +} + +FLOAT_TO_INT(16, 16) +FLOAT_TO_INT(16, 32) +FLOAT_TO_INT(16, 64) + +FLOAT_TO_INT(32, 16) +FLOAT_TO_INT(32, 32) +FLOAT_TO_INT(32, 64) + +FLOAT_TO_INT(64, 16) +FLOAT_TO_INT(64, 32) +FLOAT_TO_INT(64, 64) + +#undef FLOAT_TO_INT + +/* + * Returns the result of converting the floating-point value `a' to + * the unsigned integer format. The conversion is performed according + * to the IEC/IEEE Standard for Binary Floating-Point + * Arithmetic---which means in particular that the conversion is + * rounded according to the current rounding mode. If `a' is a NaN, + * the largest unsigned integer is returned. Otherwise, if the + * conversion overflows, 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) { + s->float_exception_flags |=3D float_flag_invalid; + 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 { + s->float_exception_flags |=3D float_flag_invalid; + return UINT64_MAX; + } + default: + g_assert_not_reached(); + } +} + +static uint16_t uint16_pack_decomposed(decomposed_parts p, float_status *s) +{ + uint64_t r =3D uint64_pack_decomposed(p, s); + if (r > UINT16_MAX) { + s->float_exception_flags |=3D float_flag_invalid; + r =3D UINT16_MAX; + } + return r; +} + +static uint32_t uint32_pack_decomposed(decomposed_parts p, float_status *s) +{ + uint64_t r =3D uint64_pack_decomposed(p, s); + if (r > UINT32_MAX) { + s->float_exception_flags |=3D float_flag_invalid; + r =3D UINT32_MAX; + } + return r; +} + +#define FLOAT_TO_UINT(fsz, isz) \ +uint ## isz ## _t float ## fsz ## _to_uint ## isz(float ## fsz a, float_st= atus *s) \ +{ \ + decomposed_parts pa =3D float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr =3D round_decomposed(pa, s->float_rounding_mode, s= ); \ + return uint ## isz ## _pack_decomposed(pr, s); \ +} \ + \ +uint ## isz ## _t float ## fsz ## _to_uint ## isz ## _round_to_zero \ + (float ## fsz a, float_status *s) \ +{ \ + decomposed_parts pa =3D float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr =3D round_decomposed(pa, float_round_to_zero, s); \ + return uint ## isz ## _pack_decomposed(pr, s); \ +} + +FLOAT_TO_UINT(16, 16) +FLOAT_TO_UINT(16, 32) +FLOAT_TO_UINT(16, 64) + +FLOAT_TO_UINT(32, 16) +FLOAT_TO_UINT(32, 32) +FLOAT_TO_UINT(32, 64) + +FLOAT_TO_UINT(64, 16) +FLOAT_TO_UINT(64, 32) +FLOAT_TO_UINT(64, 64) + +#undef FLOAT_TO_UINT + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -2663,288 +2851,8 @@ float128 uint64_to_float128(uint64_t a, float_statu= s *status) return normalizeRoundAndPackFloat128(0, 0x406E, a, 0, status); } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, t= he -| largest integer with the same sign as `a' is returned. -*-------------------------------------------------------------------------= ---*/ =20 -int32_t float32_to_int32(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64; - - a =3D float32_squash_input_denormal(a, status); - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - if ( ( aExp =3D=3D 0xFF ) && aSig ) aSign =3D 0; - if ( aExp ) aSig |=3D 0x00800000; - shiftCount =3D 0xAF - aExp; - aSig64 =3D aSig; - aSig64 <<=3D 32; - if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64= ); - return roundAndPackInt32(aSign, aSig64, status); =20 -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' = is -| returned. -*-------------------------------------------------------------------------= ---*/ - -int32_t float32_to_int32_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - int32_t z; - a =3D float32_squash_input_denormal(a, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - shiftCount =3D aExp - 0x9E; - if ( 0 <=3D shiftCount ) { - if ( float32_val(a) !=3D 0xCF000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp =3D=3D 0xFF ) && aSig ) ) return 0x7F= FFFFFF; - } - return (int32_t) 0x80000000; - } - else if ( aExp <=3D 0x7E ) { - if (aExp | aSig) { - status->float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - aSig =3D ( aSig | 0x00800000 )<<8; - z =3D aSig>>( - shiftCount ); - if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { - status->float_exception_flags |=3D float_flag_inexact; - } - if ( aSign ) z =3D - z; - return z; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 16-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' = is -| returned. -*-------------------------------------------------------------------------= ---*/ - -int16_t float32_to_int16_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - int32_t z; - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - shiftCount =3D aExp - 0x8E; - if ( 0 <=3D shiftCount ) { - if ( float32_val(a) !=3D 0xC7000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp =3D=3D 0xFF ) && aSig ) ) { - return 0x7FFF; - } - } - return (int32_t) 0xffff8000; - } - else if ( aExp <=3D 0x7E ) { - if ( aExp | aSig ) { - status->float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - shiftCount -=3D 0x10; - aSig =3D ( aSig | 0x00800000 )<<8; - z =3D aSig>>( - shiftCount ); - if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { - status->float_exception_flags |=3D float_flag_inexact; - } - if ( aSign ) { - z =3D - z; - } - return z; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, t= he -| largest integer with the same sign as `a' is returned. -*-------------------------------------------------------------------------= ---*/ - -int64_t float32_to_int64(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64, aSigExtra; - a =3D float32_squash_input_denormal(a, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - shiftCount =3D 0xBE - aExp; - if ( shiftCount < 0 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp =3D=3D 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - if ( aExp ) aSig |=3D 0x00800000; - aSig64 =3D aSig; - aSig64 <<=3D 40; - shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); - return roundAndPackInt64(aSign, aSig64, aSigExtra, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| unsigned integer is returned. Otherwise, if the conversion overflows, t= he -| largest unsigned integer is returned. If the 'a' is negative, the result -| is rounded and zero is returned; values that do not round to zero will -| raise the inexact exception flag. -*-------------------------------------------------------------------------= ---*/ - -uint64_t float32_to_uint64(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64, aSigExtra; - a =3D float32_squash_input_denormal(a, status); - - aSig =3D extractFloat32Frac(a); - aExp =3D extractFloat32Exp(a); - aSign =3D extractFloat32Sign(a); - if ((aSign) && (aExp > 126)) { - float_raise(float_flag_invalid, status); - if (float32_is_any_nan(a)) { - return LIT64(0xFFFFFFFFFFFFFFFF); - } else { - return 0; - } - } - shiftCount =3D 0xBE - aExp; - if (aExp) { - aSig |=3D 0x00800000; - } - if (shiftCount < 0) { - float_raise(float_flag_invalid, status); - return LIT64(0xFFFFFFFFFFFFFFFF); - } - - aSig64 =3D aSig; - aSig64 <<=3D 40; - shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra); - return roundAndPackUint64(aSign, aSig64, aSigExtra, status); -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest unsigned integer is returned. Otherwise, if t= he -| conversion overflows, the largest unsigned integer is returned. If the -| 'a' is negative, the result is rounded and zero is returned; values that= do -| not round to zero will raise the inexact flag. -*-------------------------------------------------------------------------= ---*/ - -uint64_t float32_to_uint64_round_to_zero(float32 a, float_status *status) -{ - signed char current_rounding_mode =3D status->float_rounding_mode; - set_float_rounding_mode(float_round_to_zero, status); - int64_t v =3D float32_to_uint64(a, status); - set_float_rounding_mode(current_rounding_mode, status); - return v; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the single-precision floating-point val= ue -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest positive integer is returned. Otherwise, if t= he -| conversion overflows, the largest integer with the same sign as `a' is -| returned. -*-------------------------------------------------------------------------= ---*/ - -int64_t float32_to_int64_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64; - int64_t z; - a =3D float32_squash_input_denormal(a, status); - - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - shiftCount =3D aExp - 0xBE; - if ( 0 <=3D shiftCount ) { - if ( float32_val(a) !=3D 0xDF000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp =3D=3D 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - else if ( aExp <=3D 0x7E ) { - if (aExp | aSig) { - status->float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - aSig64 =3D aSig | 0x00800000; - aSig64 <<=3D 40; - z =3D aSig64>>( - shiftCount ); - if ( (uint64_t) ( aSig64<<( shiftCount & 63 ) ) ) { - status->float_exception_flags |=3D float_flag_inexact; - } - if ( aSign ) z =3D - z; - return z; - -} =20 /*------------------------------------------------------------------------= ---- | Returns the result of converting the single-precision floating-point val= ue @@ -3500,289 +3408,59 @@ int float32_le_quiet(float32 a, float32 b, float_s= tatus *status) | Returns 1 if the single-precision floating-point value `a' is less than | the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an | exception. Otherwise, the comparison is performed according to the IEC/= IEEE -| Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -int float32_lt_quiet(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign; - uint32_t av, bv; - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - if ( ( ( extractFloat32Exp( a ) =3D=3D 0xFF ) && extractFloat32Frac= ( a ) ) - || ( ( extractFloat32Exp( b ) =3D=3D 0xFF ) && extractFloat32Frac= ( b ) ) - ) { - if (float32_is_signaling_nan(a, status) - || float32_is_signaling_nan(b, status)) { - float_raise(float_flag_invalid, status); - } - return 0; - } - aSign =3D extractFloat32Sign( a ); - bSign =3D extractFloat32Sign( b ); - av =3D float32_val(a); - bv =3D float32_val(b); - if ( aSign !=3D bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 = ) !=3D 0 ); - return ( av !=3D bv ) && ( aSign ^ ( av < bv ) ); - -} - -/*------------------------------------------------------------------------= ---- -| Returns 1 if the single-precision floating-point values `a' and `b' cann= ot -| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The -| comparison is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -int float32_unordered_quiet(float32 a, float32 b, float_status *status) -{ - a =3D float32_squash_input_denormal(a, status); - b =3D float32_squash_input_denormal(b, status); - - if ( ( ( extractFloat32Exp( a ) =3D=3D 0xFF ) && extractFloat32Frac= ( a ) ) - || ( ( extractFloat32Exp( b ) =3D=3D 0xFF ) && extractFloat32Frac= ( b ) ) - ) { - if (float32_is_signaling_nan(a, status) - || float32_is_signaling_nan(b, status)) { - float_raise(float_flag_invalid, status); - } - return 1; - } - return 0; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, t= he -| largest integer with the same sign as `a' is returned. -*-------------------------------------------------------------------------= ---*/ - -int32_t float64_to_int32(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig; - a =3D float64_squash_input_denormal(a, status); - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( ( aExp =3D=3D 0x7FF ) && aSig ) aSign =3D 0; - if ( aExp ) aSig |=3D LIT64( 0x0010000000000000 ); - shiftCount =3D 0x42C - aExp; - if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32(aSign, aSig, status); - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' = is -| returned. -*-------------------------------------------------------------------------= ---*/ - -int32_t float64_to_int32_round_to_zero(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, savedASig; - int32_t z; - a =3D float64_squash_input_denormal(a, status); - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( 0x41E < aExp ) { - if ( ( aExp =3D=3D 0x7FF ) && aSig ) aSign =3D 0; - goto invalid; - } - else if ( aExp < 0x3FF ) { - if (aExp || aSig) { - status->float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - aSig |=3D LIT64( 0x0010000000000000 ); - shiftCount =3D 0x433 - aExp; - savedASig =3D aSig; - aSig >>=3D shiftCount; - z =3D aSig; - if ( aSign ) z =3D - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise(float_flag_invalid, status); - return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<float_exception_flags |=3D float_flag_inexact; - } - return z; - -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 16-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' = is -| returned. -*-------------------------------------------------------------------------= ---*/ - -int16_t float64_to_int16_round_to_zero(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, savedASig; - int32_t z; - - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( 0x40E < aExp ) { - if ( ( aExp =3D=3D 0x7FF ) && aSig ) { - aSign =3D 0; - } - goto invalid; - } - else if ( aExp < 0x3FF ) { - if ( aExp || aSig ) { - status->float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - aSig |=3D LIT64( 0x0010000000000000 ); - shiftCount =3D 0x433 - aExp; - savedASig =3D aSig; - aSig >>=3D shiftCount; - z =3D aSig; - if ( aSign ) { - z =3D - z; - } - if ( ( (int16_t)z < 0 ) ^ aSign ) { - invalid: - float_raise(float_flag_invalid, status); - return aSign ? (int32_t) 0xffff8000 : 0x7FFF; - } - if ( ( aSig<float_exception_flags |=3D float_flag_inexact; - } - return z; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, t= he -| largest integer with the same sign as `a' is returned. +| Standard for Binary Floating-Point Arithmetic. *-------------------------------------------------------------------------= ---*/ =20 -int64_t float64_to_int64(float64 a, float_status *status) +int float32_lt_quiet(float32 a, float32 b, float_status *status) { - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, aSigExtra; - a =3D float64_squash_input_denormal(a, status); + flag aSign, bSign; + uint32_t av, bv; + a =3D float32_squash_input_denormal(a, status); + b =3D float32_squash_input_denormal(b, status); =20 - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( aExp ) aSig |=3D LIT64( 0x0010000000000000 ); - shiftCount =3D 0x433 - aExp; - if ( shiftCount <=3D 0 ) { - if ( 0x43E < aExp ) { + if ( ( ( extractFloat32Exp( a ) =3D=3D 0xFF ) && extractFloat32Frac= ( a ) ) + || ( ( extractFloat32Exp( b ) =3D=3D 0xFF ) && extractFloat32Frac= ( b ) ) + ) { + if (float32_is_signaling_nan(a, status) + || float32_is_signaling_nan(b, status)) { float_raise(float_flag_invalid, status); - if ( ! aSign - || ( ( aExp =3D=3D 0x7FF ) - && ( aSig !=3D LIT64( 0x0010000000000000 ) ) ) - ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (int64_t) LIT64( 0x8000000000000000 ); } - aSigExtra =3D 0; - aSig <<=3D - shiftCount; - } - else { - shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra ); + return 0; } - return roundAndPackInt64(aSign, aSig, aSigExtra, status); + aSign =3D extractFloat32Sign( a ); + bSign =3D extractFloat32Sign( b ); + av =3D float32_val(a); + bv =3D float32_val(b); + if ( aSign !=3D bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 = ) !=3D 0 ); + return ( av !=3D bv ) && ( aSign ^ ( av < bv ) ); =20 } =20 /*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' = is -| returned. +| Returns 1 if the single-precision floating-point values `a' and `b' cann= ot +| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The +| comparison is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. *-------------------------------------------------------------------------= ---*/ =20 -int64_t float64_to_int64_round_to_zero(float64 a, float_status *status) +int float32_unordered_quiet(float32 a, float32 b, float_status *status) { - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig; - int64_t z; - a =3D float64_squash_input_denormal(a, status); + a =3D float32_squash_input_denormal(a, status); + b =3D float32_squash_input_denormal(b, status); =20 - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - if ( aExp ) aSig |=3D LIT64( 0x0010000000000000 ); - shiftCount =3D aExp - 0x433; - if ( 0 <=3D shiftCount ) { - if ( 0x43E <=3D aExp ) { - if ( float64_val(a) !=3D LIT64( 0xC3E0000000000000 ) ) { - float_raise(float_flag_invalid, status); - if ( ! aSign - || ( ( aExp =3D=3D 0x7FF ) - && ( aSig !=3D LIT64( 0x0010000000000000 ) ) ) - ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - z =3D aSig<float_exception_flags |=3D float_flag_inexact; - } - return 0; - } - z =3D aSig>>( - shiftCount ); - if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) { - status->float_exception_flags |=3D float_flag_inexact; + if ( ( ( extractFloat32Exp( a ) =3D=3D 0xFF ) && extractFloat32Frac= ( a ) ) + || ( ( extractFloat32Exp( b ) =3D=3D 0xFF ) && extractFloat32Frac= ( b ) ) + ) { + if (float32_is_signaling_nan(a, status) + || float32_is_signaling_nan(b, status)) { + float_raise(float_flag_invalid, status); } + return 1; } - if ( aSign ) z =3D - z; - return z; - + return 0; } =20 + /*------------------------------------------------------------------------= ---- | Returns the result of converting the double-precision floating-point val= ue | `a' to the single-precision floating-point format. The conversion is @@ -7049,252 +6727,7 @@ float64 uint32_to_float64(uint32_t a, float_status = *status) return int64_to_float64(a, status); } =20 -uint32_t float32_to_uint32(float32 a, float_status *status) -{ - int64_t v; - uint32_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float32_to_int64(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffffffff) { - res =3D 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint32_t float32_to_uint32_round_to_zero(float32 a, float_status *status) -{ - int64_t v; - uint32_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float32_to_int64_round_to_zero(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffffffff) { - res =3D 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -int16_t float32_to_int16(float32 a, float_status *status) -{ - int32_t v; - int16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float32_to_int32(a, status); - if (v < -0x8000) { - res =3D -0x8000; - } else if (v > 0x7fff) { - res =3D 0x7fff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float32_to_uint16(float32 a, float_status *status) -{ - int32_t v; - uint16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float32_to_int32(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffff) { - res =3D 0xffff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float32_to_uint16_round_to_zero(float32 a, float_status *status) -{ - int64_t v; - uint16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float32_to_int64_round_to_zero(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffff) { - res =3D 0xffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint32_t float64_to_uint32(float64 a, float_status *status) -{ - uint64_t v; - uint32_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float64_to_uint64(a, status); - if (v > 0xffffffff) { - res =3D 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint32_t float64_to_uint32_round_to_zero(float64 a, float_status *status) -{ - uint64_t v; - uint32_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float64_to_uint64_round_to_zero(a, status); - if (v > 0xffffffff) { - res =3D 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -int16_t float64_to_int16(float64 a, float_status *status) -{ - int64_t v; - int16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float64_to_int32(a, status); - if (v < -0x8000) { - res =3D -0x8000; - } else if (v > 0x7fff) { - res =3D 0x7fff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float64_to_uint16(float64 a, float_status *status) -{ - int64_t v; - uint16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float64_to_int32(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffff) { - res =3D 0xffff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float64_to_uint16_round_to_zero(float64 a, float_status *status) -{ - int64_t v; - uint16_t res; - int old_exc_flags =3D get_float_exception_flags(status); - - v =3D float64_to_int64_round_to_zero(a, status); - if (v < 0) { - res =3D 0; - } else if (v > 0xffff) { - res =3D 0xffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the double-precision floating-point val= ue -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. If the conversion overflows, the -| largest unsigned integer is returned. If 'a' is negative, the value is -| rounded and zero is returned; negative values that do not round to zero -| will raise the inexact exception. -*-------------------------------------------------------------------------= ---*/ - -uint64_t float64_to_uint64(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, aSigExtra; - a =3D float64_squash_input_denormal(a, status); - - aSig =3D extractFloat64Frac(a); - aExp =3D extractFloat64Exp(a); - aSign =3D extractFloat64Sign(a); - if (aSign && (aExp > 1022)) { - float_raise(float_flag_invalid, status); - if (float64_is_any_nan(a)) { - return LIT64(0xFFFFFFFFFFFFFFFF); - } else { - return 0; - } - } - if (aExp) { - aSig |=3D LIT64(0x0010000000000000); - } - shiftCount =3D 0x433 - aExp; - if (shiftCount <=3D 0) { - if (0x43E < aExp) { - float_raise(float_flag_invalid, status); - return LIT64(0xFFFFFFFFFFFFFFFF); - } - aSigExtra =3D 0; - aSig <<=3D -shiftCount; - } else { - shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra); - } - return roundAndPackUint64(aSign, aSig, aSigExtra, status); -} =20 -uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *status) -{ - signed char current_rounding_mode =3D status->float_rounding_mode; - set_float_rounding_mode(float_round_to_zero, status); - uint64_t v =3D float64_to_uint64(a, status); - set_float_rounding_mode(current_rounding_mode, status); - return v; -} =20 #define COMPARE(s, nan_exp) = \ static inline int float ## s ## _compare_internal(float ## s a, float ## s= b,\ diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 6427762a9a..d7bc7cbcb6 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -314,6 +314,19 @@ float16 float32_to_float16(float32, flag, float_status= *status); float32 float16_to_float32(float16, flag, float_status *status); float16 float64_to_float16(float64 a, flag ieee, float_status *status); float64 float16_to_float64(float16 a, flag ieee, float_status *status); +int16_t float16_to_int16(float16, float_status *status); +uint16_t float16_to_uint16(float16 a, float_status *status); +int16_t float16_to_int16_round_to_zero(float16, float_status *status); +uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status); +int32_t float16_to_int32(float16, float_status *status); +uint32_t float16_to_uint32(float16 a, float_status *status); +int32_t float16_to_int32_round_to_zero(float16, float_status *status); +uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status); +int64_t float16_to_int64(float16, float_status *status); +uint64_t float16_to_uint64(float16 a, float_status *status); +int64_t float16_to_int64_round_to_zero(float16, float_status *status); +uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); +float16 int16_to_float16(int16_t a, float_status *status); =20 /*------------------------------------------------------------------------= ---- | Software half-precision operations. --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501764916903.9844462048255; Tue, 9 Jan 2018 04:42:44 -0800 (PST) Received: from localhost ([::1]:50025 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYtEq-0005dM-1K for importer@patchew.org; Tue, 09 Jan 2018 07:42:44 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53780) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt16-0002bd-Tn for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYt14-0002D2-En for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:32 -0500 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:33360) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYt14-0002Cb-4X for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:30 -0500 Received: by mail-wm0-x244.google.com with SMTP id 123so742874wme.0 for ; Tue, 09 Jan 2018 04:28:30 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id d5sm6695827wrc.4.2018.01.09.04.28.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:28:24 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 6711F3E2B54; Tue, 9 Jan 2018 12:22:53 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Cd1mYU8XGNQ5/1cXy362zD56NfttIO5m6b+OmxTdnaI=; b=ckvuvOayIVgJLDgEB/cbV0WAMo/GMzUuGqej+GmsSJdSVtyEB/6XhrKYwQinjb459c //iQaTKYrUSL6ffH+84K6cu1QIY8ef70eXmFB4FgWvedNVLLor2xVQOcFMW+dl/deXkY AdrrRCiRi8yHxeXDgxu21Cv7AL8wNsNL1UC4c= 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=Cd1mYU8XGNQ5/1cXy362zD56NfttIO5m6b+OmxTdnaI=; b=tFmhPvXrAP8qG9fXeW5+1PUqK3WML3x5rCxrsFExBF3aCS3PtmVp+W314q1CQBv4Ny 18dvxMpuxyXYjFaTx31LMmI4YgveW6aIaEaA4d1nJxi7lpCQ38t57IU0eBShBi0q0VEQ Ap6JU0b3cLp2qk1X4lGkfyuimdjoc5RkwGKS164VvayVlZ+QrXMFL/HNIj9FEX/+QVU6 +3jYC13zcJvFHIGbfYEDz6hzoi/SHuNBAywtGKEpHEYUgOj2IcU3XOe8BFzw3IOynMIn 1WSS+OEa1CqvuZWJd9FfuqHrxPPXVy4B25wH2M04lvg7FWl/rK6kJN6sAPUu7L5AmyfV t3pA== X-Gm-Message-State: AKGB3mL6nSrqKzTP2Frwzq/SjGzn7B6ToE7QJvtX2d6ZtQAo9TcQReH6 ChpNr1PH4yEQ4hf2drpZf6doJg== X-Google-Smtp-Source: ACJfBouhhBE07YOxalca7Ai5KNa0VGwGvZQF2CFhsPNj97+Tu2qvZ+HrLxqA2pSWyP9tRE3nwn5R+Q== X-Received: by 10.28.45.83 with SMTP id t80mr11517460wmt.90.1515500908866; Tue, 09 Jan 2018 04:28:28 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:49 +0000 Message-Id: <20180109122252.17670-18-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::244 Subject: [Qemu-devel] [PATCH v2 17/20] fpu/softfloat: re-factor int/uint to float X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 These are considerably simpler as the lower order integers can just use the higher order conversion function. As the decomposed fractional part is a full 64 bit rounding and inexact handling comes from the pack functions. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- v2 - explicit setting of r.sign --- fpu/softfloat.c | 322 ++++++++++++++++++++++++--------------------= ---- include/fpu/softfloat.h | 30 ++--- 2 files changed, 172 insertions(+), 180 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 514f43c065..bb68d77f72 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1500,6 +1500,169 @@ FLOAT_TO_UINT(64, 64) =20 #undef FLOAT_TO_UINT =20 +/* + * Integer to float conversions + * + * Returns the result of converting the two's complement integer `a' + * to the floating-point format. The conversion is performed according + * to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts int_to_float(int64_t a, float_status *status) +{ + decomposed_parts r; + if (a =3D=3D 0) { + r.cls =3D float_class_zero; + r.sign =3D false; + } else if (a =3D=3D (1ULL << 63)) { + r.cls =3D float_class_normal; + r.sign =3D true; + r.frac =3D DECOMPOSED_IMPLICIT_BIT; + r.exp =3D 63; + } else { + uint64_t f; + if (a < 0) { + f =3D -a; + r.sign =3D true; + } else { + f =3D a; + r.sign =3D false; + } + int shift =3D clz64(f) - 1; + r.cls =3D float_class_normal; + r.exp =3D (DECOMPOSED_BINARY_POINT - shift); + r.frac =3D f << shift; + } + + return r; +} + +float16 int64_to_float16(int64_t a, float_status *status) +{ + decomposed_parts pa =3D int_to_float(a, status); + return float16_round_pack_canonical(pa, status); +} + +float16 int32_to_float16(int32_t a, float_status *status) +{ + return int64_to_float16(a, status); +} + +float16 int16_to_float16(int16_t a, float_status *status) +{ + return int64_to_float16(a, status); +} + +float32 int64_to_float32(int64_t a, float_status *status) +{ + decomposed_parts pa =3D int_to_float(a, status); + return float32_round_pack_canonical(pa, status); +} + +float32 int32_to_float32(int32_t a, float_status *status) +{ + return int64_to_float32(a, status); +} + +float32 int16_to_float32(int16_t a, float_status *status) +{ + return int64_to_float32(a, status); +} + +float64 int64_to_float64(int64_t a, float_status *status) +{ + decomposed_parts pa =3D int_to_float(a, status); + return float64_round_pack_canonical(pa, status); +} + +float64 int32_to_float64(int32_t a, float_status *status) +{ + return int64_to_float64(a, status); +} + +float64 int16_to_float64(int16_t a, float_status *status) +{ + return int64_to_float64(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 =3D { .sign =3D false}; + + if (a =3D=3D 0) { + r.cls =3D float_class_zero; + } else { + int spare_bits =3D clz64(a) - 1; + r.cls =3D float_class_normal; + r.exp =3D DECOMPOSED_BINARY_POINT - spare_bits; + if (spare_bits < 0) { + shift64RightJamming(a, -spare_bits, &a); + r.frac =3D a; + } else { + r.frac =3D a << spare_bits; + } + } + + return r; +} + +float16 uint64_to_float16(uint64_t a, float_status *status) +{ + decomposed_parts pa =3D uint_to_float(a, status); + return float16_round_pack_canonical(pa, status); +} + +float16 uint32_to_float16(uint32_t a, float_status *status) +{ + return uint64_to_float16(a, status); +} + +float16 uint16_to_float16(uint16_t a, float_status *status) +{ + return uint64_to_float16(a, status); +} + +float32 uint64_to_float32(uint64_t a, float_status *status) +{ + decomposed_parts pa =3D uint_to_float(a, status); + return float32_round_pack_canonical(pa, status); +} + +float32 uint32_to_float32(uint32_t a, float_status *status) +{ + return uint64_to_float32(a, status); +} + +float32 uint16_to_float32(uint16_t a, float_status *status) +{ + return uint64_to_float32(a, status); +} + +float64 uint64_to_float64(uint64_t a, float_status *status) +{ + decomposed_parts pa =3D uint_to_float(a, status); + return float64_round_pack_canonical(pa, status); +} + +float64 uint32_to_float64(uint32_t a, float_status *status) +{ + return uint64_to_float64(a, status); +} + +float64 uint16_to_float64(uint16_t a, float_status *status) +{ + return uint64_to_float64(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 @@ -2591,43 +2754,6 @@ static float128 normalizeRoundAndPackFloat128(flag z= Sign, int32_t zExp, =20 } =20 -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the single-precision floating-point format. The conversion is perfor= med -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float32 int32_to_float32(int32_t a, float_status *status) -{ - flag zSign; - - if ( a =3D=3D 0 ) return float32_zero; - if ( a =3D=3D (int32_t) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); - zSign =3D ( a < 0 ); - return normalizeRoundAndPackFloat32(zSign, 0x9C, zSign ? -a : a, statu= s); -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the double-precision floating-point format. The conversion is perfor= med -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 int32_to_float64(int32_t a, float_status *status) -{ - flag zSign; - uint32_t absA; - int8_t shiftCount; - uint64_t zSig; - - if ( a =3D=3D 0 ) return float64_zero; - zSign =3D ( a < 0 ); - absA =3D zSign ? - a : a; - shiftCount =3D countLeadingZeros32( absA ) + 21; - zSig =3D absA; - return packFloat64( zSign, 0x432 - shiftCount, zSig<=3D 0) { - return packFloat32(0, 0x95 - shiftcount, a << shiftcount); - } - /* Otherwise we need to do a round-and-pack. roundAndPackFloat32() - * expects the binary point between bits 30 and 29, hence the + 7. - */ - shiftcount +=3D 7; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<=3D shiftcount; - } - - return roundAndPackFloat32(0, 0x9c - shiftcount, a, status); -} - -/*------------------------------------------------------------------------= ---- -| Returns the result of converting the 64-bit unsigned integer `a' -| to the double-precision floating-point format. The conversion is perfor= med -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*-------------------------------------------------------------------------= ---*/ - -float64 uint64_to_float64(uint64_t a, float_status *status) -{ - int exp =3D 0x43C; - int shiftcount; - - if (a =3D=3D 0) { - return float64_zero; - } - - shiftcount =3D countLeadingZeros64(a) - 1; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<=3D shiftcount; - } - return roundAndPackFloat64(0, exp - shiftcount, a, status); -} - /*------------------------------------------------------------------------= ---- | Returns the result of converting the 64-bit unsigned integer `a' | to the quadruple-precision floating-point format. The conversion is per= formed @@ -6716,19 +6733,6 @@ int float128_unordered_quiet(float128 a, float128 b,= float_status *status) return 0; } =20 -/* misc functions */ -float32 uint32_to_float32(uint32_t a, float_status *status) -{ - return int64_to_float32(a, status); -} - -float64 uint32_to_float64(uint32_t a, float_status *status) -{ - return int64_to_float64(a, status); -} - - - #define COMPARE(s, nan_exp) = \ static inline int float ## s ## _compare_internal(float ## s a, float ## s= b,\ int is_quiet, float_status *status) = \ diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index d7bc7cbcb6..aa9e30d254 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -272,9 +272,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); @@ -286,27 +290,6 @@ float32 uint64_to_float32(uint64_t, float_status *stat= us); float64 uint64_to_float64(uint64_t, float_status *status); float128 uint64_to_float128(uint64_t, float_status *status); =20 -/* We provide the int16 versions for symmetry of API with float-to-int */ -static inline float32 int16_to_float32(int16_t v, float_status *status) -{ - return int32_to_float32(v, status); -} - -static inline float32 uint16_to_float32(uint16_t v, float_status *status) -{ - return uint32_to_float32(v, status); -} - -static inline float64 int16_to_float64(int16_t v, float_status *status) -{ - return int32_to_float64(v, status); -} - -static inline float64 uint16_to_float64(uint16_t v, float_status *status) -{ - return uint32_to_float64(v, status); -} - /*------------------------------------------------------------------------= ---- | Software half-precision conversion routines. *-------------------------------------------------------------------------= ---*/ @@ -327,6 +310,11 @@ uint64_t float16_to_uint64(float16 a, float_status *st= atus); int64_t float16_to_int64_round_to_zero(float16, float_status *status); uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); float16 int16_to_float16(int16_t a, float_status *status); +float16 int32_to_float16(int32_t a, float_status *status); +float16 int64_to_float16(int64_t a, float_status *status); +float16 uint16_to_float16(uint16_t a, float_status *status); +float16 uint32_to_float16(uint32_t a, float_status *status); +float16 uint64_to_float16(uint64_t a, float_status *status); =20 /*------------------------------------------------------------------------= ---- | Software half-precision operations. --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501662360681.2611372353296; Tue, 9 Jan 2018 04:41:02 -0800 (PST) Received: from localhost ([::1]:49944 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYtDB-0004N8-IC for importer@patchew.org; Tue, 09 Jan 2018 07:41:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53759) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt15-0002ae-TR for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYt11-00029s-0T for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:31 -0500 Received: from mail-wm0-x241.google.com ([2a00:1450:400c:c09::241]:33357) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYt10-00029D-OR for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:26 -0500 Received: by mail-wm0-x241.google.com with SMTP id 123so742650wme.0 for ; Tue, 09 Jan 2018 04:28:26 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id x127sm12740919wmb.10.2018.01.09.04.28.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:28:24 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 797233E025C; Tue, 9 Jan 2018 12:22:53 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iqs4IKr51meQKEBEWobMjAnSDOK0/YUs1Bat82nJ60M=; b=Rd6bSRdmay10qJdcjkI/r5RqqVMiFfs0LXhdgFbva0Au7AElSQIflkjhSFbb6OL3SJ LKFD8mKA/okpQUk3kLVnoEblUhaRAEzOJblGBpZOugZtdAOLc4yDER6lYVpUfiAnzyK+ Ytub6QdTDlEP8je3Bln+ENUhPpwfCsuD//5RE= 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=iqs4IKr51meQKEBEWobMjAnSDOK0/YUs1Bat82nJ60M=; b=frqtW3QmO0rLFoFaaF7zDsF9rlzBaAn4FffcPhwYhfyeWFG8c7oyg96HsJwuKndIGk LpJgMhxqjPMkBZvG+4W5cOJ+KmvJunzCQLBamdNH+OqFobZru6vz8bbcp1LqP9b4R5HC LZJCWz1ELHPRYe2dZaHpq5hdPcic8LfwwVzVEX8s0znlPJMA5z3Xqr//k9j5DdCbToLl FQXQVJUUvqcWokoIymRkcq6bipAV4mWD9DsbMm0UXSkQFNL2mqDpP89gaoKHKyLLai7Q CU5VQp7hXC38YAOaDZ+cw5KsRy+A/yPcEr0RhhhAds/A5m4Ul6DTuSN3q5VackJNRHsl 39vw== X-Gm-Message-State: AKGB3mJ/AIxopkR5cr9FOrYVupflw0qmy/KsIxJf4xWHX3Qbid+CHiC8 oqzWOMkrV3sjnwGHtVG33pxubQ== X-Google-Smtp-Source: ACJfBoucK3NNXeXW2oQztXx5yRqgimnkn/kXJIFvajbx93U1NfihgcYLRNp/xeg5rIZGm8YGBxPc4w== X-Received: by 10.28.85.193 with SMTP id j184mr12462536wmb.56.1515500905527; Tue, 09 Jan 2018 04:28:25 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:50 +0000 Message-Id: <20180109122252.17670-19-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::241 Subject: [Qemu-devel] [PATCH v2 18/20] fpu/softfloat: re-factor scalbn X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 This is one of the simpler manipulations you could make to a floating point number. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- fpu/softfloat.c | 104 +++++++++++++++-----------------------------= ---- include/fpu/softfloat.h | 1 + 2 files changed, 32 insertions(+), 73 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index bb68d77f72..3647f6ca03 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1663,6 +1663,37 @@ float64 uint16_to_float64(uint16_t a, float_status *= status) return uint64_to_float64(a, status); } =20 +/* Multiply A by 2 raised to the power N. */ +static decomposed_parts scalbn_decomposed(decomposed_parts a, int n, + float_status *s) +{ + if (a.cls =3D=3D float_class_normal) { + a.exp +=3D n; + } + return a; +} + +float16 float16_scalbn(float16 a, int n, float_status *status) +{ + decomposed_parts pa =3D float16_unpack_canonical(a, status); + decomposed_parts pr =3D scalbn_decomposed(pa, n, status); + return float16_round_pack_canonical(pr, status); +} + +float32 float32_scalbn(float32 a, int n, float_status *status) +{ + decomposed_parts pa =3D float32_unpack_canonical(a, status); + decomposed_parts pr =3D scalbn_decomposed(pa, n, status); + return float32_round_pack_canonical(pr, status); +} + +float64 float64_scalbn(float64 a, int n, float_status *status) +{ + decomposed_parts pa =3D float64_unpack_canonical(a, status); + decomposed_parts pr =3D scalbn_decomposed(pa, n, status); + return float64_round_pack_canonical(pr, status); +} + /*------------------------------------------------------------------------= ---- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to = the @@ -6992,79 +7023,6 @@ MINMAX(32) MINMAX(64) =20 =20 -/* Multiply A by 2 raised to the power N. */ -float32 float32_scalbn(float32 a, int n, float_status *status) -{ - flag aSign; - int16_t aExp; - uint32_t aSig; - - a =3D float32_squash_input_denormal(a, status); - aSig =3D extractFloat32Frac( a ); - aExp =3D extractFloat32Exp( a ); - aSign =3D extractFloat32Sign( a ); - - if ( aExp =3D=3D 0xFF ) { - if ( aSig ) { - return propagateFloat32NaN(a, a, status); - } - return a; - } - if (aExp !=3D 0) { - aSig |=3D 0x00800000; - } else if (aSig =3D=3D 0) { - return a; - } else { - aExp++; - } - - if (n > 0x200) { - n =3D 0x200; - } else if (n < -0x200) { - n =3D -0x200; - } - - aExp +=3D n - 1; - aSig <<=3D 7; - return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status); -} - -float64 float64_scalbn(float64 a, int n, float_status *status) -{ - flag aSign; - int16_t aExp; - uint64_t aSig; - - a =3D float64_squash_input_denormal(a, status); - aSig =3D extractFloat64Frac( a ); - aExp =3D extractFloat64Exp( a ); - aSign =3D extractFloat64Sign( a ); - - if ( aExp =3D=3D 0x7FF ) { - if ( aSig ) { - return propagateFloat64NaN(a, a, status); - } - return a; - } - if (aExp !=3D 0) { - aSig |=3D LIT64( 0x0010000000000000 ); - } else if (aSig =3D=3D 0) { - return a; - } else { - aExp++; - } - - if (n > 0x1000) { - n =3D 0x1000; - } else if (n < -0x1000) { - n =3D -0x1000; - } - - aExp +=3D n - 1; - aSig <<=3D 10; - return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status); -} - floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) { flag aSign; diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index aa9e30d254..41338184d5 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -326,6 +326,7 @@ float16 float16_sub(float16, float16, float_status *sta= tus); float16 float16_mul(float16, float16, float_status *status); float16 float16_muladd(float16, float16, float16, int, float_status *statu= s); float16 float16_div(float16, float16, float_status *status); +float16 float16_scalbn(float16, int, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501041277171.03643385803537; Tue, 9 Jan 2018 04:30:41 -0800 (PST) Received: from localhost ([::1]:49526 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt3A-0003xF-8C for importer@patchew.org; Tue, 09 Jan 2018 07:30:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53762) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt15-0002ah-Tt for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYt13-0002CR-C9 for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:31 -0500 Received: from mail-wm0-x241.google.com ([2a00:1450:400c:c09::241]:41641) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYt13-0002BE-1r for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:29 -0500 Received: by mail-wm0-x241.google.com with SMTP id g75so20215892wme.0 for ; Tue, 09 Jan 2018 04:28:28 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id c11sm2236290wrb.81.2018.01.09.04.28.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:28:24 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 8B9CC3E2B55; Tue, 9 Jan 2018 12:22:53 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=X4rnVqpYCQie3dztzQP9kk+QOx2KcVI9sLNxrrbidZk=; b=G2Jm8m7N7FreSJz3O2HEAgTO+Ncwruncttx4IrguYsieFW4wpd+rF4XfwhBHEG2lao 8mmE4NAylfs2ulAgHTTXsfe0U19rqRuIAZ4FjXy3Yb24fU4W7tMBdHJA43Wdciz1Rm3K x5XHDHntMEE4glqXsmXIGx3lX2Vxm4gkkIn2A= 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=X4rnVqpYCQie3dztzQP9kk+QOx2KcVI9sLNxrrbidZk=; b=DUwHJ0xuayMDItojT+KnCFWHlGxspo5c4lQLVHIs9lt39Zakp8j8kosSWJl8RMNnBa Vh7GHsfTwvx0JojC2iBxB3xg6kyJcnGo3WqS0RtlWPD4qWIx/ts0aa4/x/Q5H+1ogGQf GeiFapfNZDUnK5usqRpEOrSPm6TbsDEM3Ok0ViaSvI36d0YUE2lDQYg4pAH/qQt+FoTX 2nwprRHe0lNjjW0jAn4ic74Brmc7dEYxXKErRPTXtSVTdN2p/CAxPt6OKrvwgCpdHhLN UjZipDXN5eSUDp9CR40zPdLlgPg53AEjz6g/+k8cxsVcrs8fWjYXE5W521YPGD7Nwf9E IG/w== X-Gm-Message-State: AKGB3mJeADp2C8IGlijavWG6eowIuo9zrfI/vUaUZS1C0oMTqc4VbTk5 pq2/vmUSdml2iMUbYrgdJls4lA== X-Google-Smtp-Source: ACJfBouJA1I9N+GNM0c80xuGL2PIcN46X6Sif3e8Un+6LWsSmC54TkWNj3VbIc4Ru5d12W2n0fJSbw== X-Received: by 10.28.19.210 with SMTP id 201mr10762569wmt.4.1515500907923; Tue, 09 Jan 2018 04:28:27 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:51 +0000 Message-Id: <20180109122252.17670-20-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::241 Subject: [Qemu-devel] [PATCH v2 19/20] fpu/softfloat: re-factor minmax X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Let's do the same re-factor treatment for minmax functions. I still use the MACRO trick to expand but now all the checking code is common. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- v2 - minor indentation fix --- fpu/softfloat.c | 239 ++++++++++++++++++++++++++------------------= ---- include/fpu/softfloat.h | 6 ++ 2 files changed, 134 insertions(+), 111 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3647f6ca03..1dd9bd5972 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1663,6 +1663,134 @@ float64 uint16_to_float64(uint16_t a, float_status = *status) return uint64_to_float64(a, status); } =20 +/* Float Min/Max */ +/* min() and max() functions. These can't be implemented as + * 'compare and pick one input' because that would mishandle + * NaNs and +0 vs -0. + * + * minnum() and maxnum() functions. These are similar to the min() + * and max() functions but if one of the arguments is a QNaN and + * the other is numerical then the numerical argument is returned. + * SNaNs will get quietened before being returned. + * minnum() and maxnum correspond to the IEEE 754-2008 minNum() + * and maxNum() operations. min() and max() are the typical min/max + * semantics provided by many CPUs which predate that specification. + * + * minnummag() and maxnummag() functions correspond to minNumMag() + * and minNumMag() from the IEEE-754 2008. + */ +static decomposed_parts minmax_decomposed(decomposed_parts a, + decomposed_parts b, + bool ismin, bool ieee, bool isma= g, + float_status *s) +{ + if (a.cls >=3D float_class_qnan + || + b.cls >=3D float_class_qnan) + { + if (ieee) { + /* Takes two floating-point values `a' and `b', one of + * which is a NaN, and returns the appropriate NaN + * result. If either `a' or `b' is a signaling NaN, + * the invalid exception is raised. + */ + if (a.cls =3D=3D float_class_snan || b.cls =3D=3D float_class_= snan) { + return pick_nan_parts(a, b, s); + } else if (a.cls >=3D float_class_qnan + && + b.cls < float_class_qnan) { + return b; + } else if (b.cls >=3D float_class_qnan + && + a.cls < float_class_qnan) { + return a; + } + } + return pick_nan_parts(a, b, s); + } else { + int a_exp, b_exp; + bool a_sign, b_sign; + + switch (a.cls) { + case float_class_normal: + a_exp =3D a.exp; + break; + case float_class_inf: + a_exp =3D INT_MAX; + break; + case float_class_zero: + a_exp =3D INT_MIN; + break; + default: + g_assert_not_reached(); + break; + } + switch (b.cls) { + case float_class_normal: + b_exp =3D b.exp; + break; + case float_class_inf: + b_exp =3D INT_MAX; + break; + case float_class_zero: + b_exp =3D INT_MIN; + break; + default: + g_assert_not_reached(); + break; + } + + a_sign =3D a.sign; + b_sign =3D b.sign; + if (ismag) { + a_sign =3D b_sign =3D 0; + } + + if (a_sign =3D=3D b_sign) { + bool a_less =3D a_exp < b_exp; + if (a_exp =3D=3D b_exp) { + a_less =3D a.frac < b.frac; + } + return a_sign ^ a_less ^ ismin ? b : a; + } else { + return a_sign ^ ismin ? b : a; + } + } +} + +#define MINMAX(sz, name, ismin, isiee, ismag) \ +float ## sz float ## sz ## _ ## name(float ## sz a, float ## sz b, float_s= tatus *s) \ +{ \ + decomposed_parts pa =3D float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb =3D float ## sz ## _unpack_canonical(b, s); \ + decomposed_parts pr =3D minmax_decomposed(pa, pb, ismin, isiee, ismag,= s); \ + \ + return float ## sz ## _round_pack_canonical(pr, s); \ +} + +MINMAX(16, min, true, false, false) +MINMAX(16, minnum, true, true, false) +MINMAX(16, minnummag, true, true, true) +MINMAX(16, max, false, false, false) +MINMAX(16, maxnum, false, true, false) +MINMAX(16, maxnummag, false, true, true) + +MINMAX(32, min, true, false, false) +MINMAX(32, minnum, true, true, false) +MINMAX(32, minnummag, true, true, true) +MINMAX(32, max, false, false, false) +MINMAX(32, maxnum, false, true, false) +MINMAX(32, maxnummag, false, true, true) + +MINMAX(64, min, true, false, false) +MINMAX(64, minnum, true, true, false) +MINMAX(64, minnummag, true, true, true) +MINMAX(64, max, false, false, false) +MINMAX(64, maxnum, false, true, false) +MINMAX(64, maxnummag, false, true, true) + +#undef MINMAX + /* Multiply A by 2 raised to the power N. */ static decomposed_parts scalbn_decomposed(decomposed_parts a, int n, float_status *s) @@ -6912,117 +7040,6 @@ int float128_compare_quiet(float128 a, float128 b, = float_status *status) return float128_compare_internal(a, b, 1, status); } =20 -/* min() and max() functions. These can't be implemented as - * 'compare and pick one input' because that would mishandle - * NaNs and +0 vs -0. - * - * minnum() and maxnum() functions. These are similar to the min() - * and max() functions but if one of the arguments is a QNaN and - * the other is numerical then the numerical argument is returned. - * SNaNs will get quietened before being returned. - * minnum() and maxnum correspond to the IEEE 754-2008 minNum() - * and maxNum() operations. min() and max() are the typical min/max - * semantics provided by many CPUs which predate that specification. - * - * minnummag() and maxnummag() functions correspond to minNumMag() - * and minNumMag() from the IEEE-754 2008. - */ -#define MINMAX(s) \ -static inline float ## s float ## s ## _minmax(float ## s a, float ## s b,= \ - int ismin, int isieee, \ - int ismag, \ - float_status *status) \ -{ \ - flag aSign, bSign; \ - uint ## s ## _t av, bv, aav, abv; \ - a =3D float ## s ## _squash_input_denormal(a, status); \ - b =3D float ## s ## _squash_input_denormal(b, status); \ - if (float ## s ## _is_any_nan(a) || \ - float ## s ## _is_any_nan(b)) { \ - if (isieee) { \ - if (float ## s ## _is_signaling_nan(a, status) || \ - float ## s ## _is_signaling_nan(b, status)) { \ - return propagateFloat ## s ## NaN(a, b, status); \ - } else if (float ## s ## _is_quiet_nan(a, status) && \ - !float ## s ##_is_any_nan(b)) { \ - return b; \ - } else if (float ## s ## _is_quiet_nan(b, status) && \ - !float ## s ## _is_any_nan(a)) { \ - return a; \ - } \ - } \ - return propagateFloat ## s ## NaN(a, b, status); \ - } \ - aSign =3D extractFloat ## s ## Sign(a); \ - bSign =3D extractFloat ## s ## Sign(b); \ - av =3D float ## s ## _val(a); \ - bv =3D float ## s ## _val(b); \ - if (ismag) { \ - aav =3D float ## s ## _abs(av); \ - abv =3D float ## s ## _abs(bv); \ - if (aav !=3D abv) { \ - if (ismin) { \ - return (aav < abv) ? a : b; \ - } else { \ - return (aav < abv) ? b : a; \ - } \ - } \ - } \ - if (aSign !=3D bSign) { \ - if (ismin) { \ - return aSign ? a : b; \ - } else { \ - return aSign ? b : a; \ - } \ - } else { \ - if (ismin) { \ - return (aSign ^ (av < bv)) ? a : b; \ - } else { \ - return (aSign ^ (av < bv)) ? b : a; \ - } \ - } \ -} \ - \ -float ## s float ## s ## _min(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 1, 0, 0, status); \ -} \ - \ -float ## s float ## s ## _max(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 0, 0, 0, status); \ -} \ - \ -float ## s float ## s ## _minnum(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 1, 1, 0, status); \ -} \ - \ -float ## s float ## s ## _maxnum(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 0, 1, 0, status); \ -} \ - \ -float ## s float ## s ## _minnummag(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 1, 1, 1, status); \ -} \ - \ -float ## s float ## s ## _maxnummag(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 0, 1, 1, status); \ -} - -MINMAX(32) -MINMAX(64) - - floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) { flag aSign; diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 41338184d5..c948727bbb 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -327,6 +327,12 @@ float16 float16_mul(float16, float16, float_status *st= atus); float16 float16_muladd(float16, float16, float16, int, float_status *statu= s); float16 float16_div(float16, float16, float_status *status); float16 float16_scalbn(float16, int, float_status *status); +float16 float16_min(float16, float16, float_status *status); +float16 float16_max(float16, float16, float_status *status); +float16 float16_minnum(float16, float16, float_status *status); +float16 float16_maxnum(float16, float16, float_status *status); +float16 float16_minnummag(float16, float16, float_status *status); +float16 float16_maxnummag(float16, float16, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); --=20 2.15.1 From nobody Sun Apr 28 22:15:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515501424391529.5169260637347; Tue, 9 Jan 2018 04:37:04 -0800 (PST) Received: from localhost ([::1]:49571 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt9L-0000li-IB for importer@patchew.org; Tue, 09 Jan 2018 07:37:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53777) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt16-0002bY-Rs for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eYt15-0002Dd-BM for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:32 -0500 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:39343) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eYt14-0002Ct-UQ for qemu-devel@nongnu.org; Tue, 09 Jan 2018 07:28:31 -0500 Received: by mail-wm0-x242.google.com with SMTP id i11so20264249wmf.4 for ; Tue, 09 Jan 2018 04:28:30 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id v195sm13000897wmf.25.2018.01.09.04.28.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Jan 2018 04:28:28 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 9DCC73E2B56; Tue, 9 Jan 2018 12:22:53 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9EVuYq8Svz+r+ohBrFBZAJHxebiz/Vagrbylnmdb36U=; b=a7aH0Ox0oTTXWCMmc8nOnjrnHXa8kRKcgfpfBFiD1fkUCCbhroZFva90+tBS53dph9 z489C1Nob/zCMWTvCLbFObbABgK+u/NJv7C0ZnI/s87Ejhh8FS/ZQN5/FZXPzSSQPL33 /ib0g0wgyvDi2nTfVhxPRpU8VYCqloLBfh5sc= 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=9EVuYq8Svz+r+ohBrFBZAJHxebiz/Vagrbylnmdb36U=; b=AGGxOKMuv9Wwo4QoV9sL0m4YrZY2gZ2JggwJoend937rrX8qIvhKTWQNSK59ITBqUu nLJAdR+R2Es6fY51qhPZ7evSDlngnExwhpVvEvsU0UlO6cnExqfvx5cCBrEzFlZ/daYB 0r9hIMvE65LuePEsbbJfBDrZNUp+TsKOgHmj0hjQmh4a+Qx4qeV77958U6M40jTMs9EI J9mLScuy1aAlrgNz+QtKdAT8goGPnryFFXrmQybsxNFmisfoDyHdyGf0wB+qtVOT3c9Q j/0IIZgeSYv5h6HigTG7iJ/H1SCyFGZtNL7sWWqo0KQQdpxp10HIQbUIqz2uDLbyUddh 5yQw== X-Gm-Message-State: AKGB3mLp4GZUiTbutykByIPvc+vmbDqhNN7Qwfs3Kdp7158vyyUrMSYY /Wvst8pTNALvjQdXbaEbGZiw6w== X-Google-Smtp-Source: ACJfBosj+NIL7KMK3ghcEu7wGiXjKzsSJVc7IkpWQsNracW2VgLJnEpnaeYSIpBrZTeT3jvNtbv2Lw== X-Received: by 10.28.212.72 with SMTP id l69mr11050418wmg.66.1515500909840; Tue, 09 Jan 2018 04:28:29 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com Date: Tue, 9 Jan 2018 12:22:52 +0000 Message-Id: <20180109122252.17670-21-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180109122252.17670-1-alex.bennee@linaro.org> References: <20180109122252.17670-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::242 Subject: [Qemu-devel] [PATCH v2 20/20] fpu/softfloat: re-factor compare X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 The compare function was already expanded from a macro. I keep the macro expansion but move most of the logic into a compare_decomposed. Signed-off-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- v2 - minor re-factor for better inf handling --- fpu/softfloat.c | 134 +++++++++++++++++++++++++++++---------------= ---- include/fpu/softfloat.h | 2 + 2 files changed, 82 insertions(+), 54 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 1dd9bd5972..8eda35acd5 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1791,6 +1791,86 @@ MINMAX(64, maxnummag, false, true, true) =20 #undef MINMAX =20 +/* Floating point compare */ +static int compare_decomposed(decomposed_parts a, decomposed_parts b, + bool is_quiet, float_status *s) +{ + if (a.cls >=3D float_class_qnan + || + b.cls >=3D float_class_qnan) { + if (!is_quiet || + a.cls =3D=3D float_class_snan || + b.cls =3D=3D float_class_snan) { + s->float_exception_flags |=3D float_flag_invalid; + } + return float_relation_unordered; + } + + if (a.cls =3D=3D float_class_zero) { + if (b.cls =3D=3D float_class_zero) { + return float_relation_equal; + } + return b.sign ? float_relation_greater : float_relation_less; + } else if (b.cls =3D=3D float_class_zero) { + return a.sign ? float_relation_less : float_relation_greater; + } + + /* The only really important thing about infinity is its sign. If + * both are infinities the sign marks the smallest of the two. + */ + if (a.cls =3D=3D float_class_inf) { + if ((b.cls =3D=3D float_class_inf) && (a.sign =3D=3D b.sign)) { + return float_relation_equal; + } + return a.sign ? float_relation_less : float_relation_greater; + } else if (b.cls =3D=3D float_class_inf) { + return b.sign ? float_relation_greater : float_relation_less; + } + + if (a.sign !=3D b.sign) { + return a.sign ? float_relation_less : float_relation_greater; + } + + if (a.exp =3D=3D b.exp) { + if (a.frac =3D=3D b.frac) { + return float_relation_equal; + } + if (a.sign) { + return a.frac > b.frac ? + float_relation_less : float_relation_greater; + } else { + return a.frac > b.frac ? + float_relation_greater : float_relation_less; + } + } else { + if (a.sign) { + return a.exp > b.exp ? float_relation_less : float_relation_gr= eater; + } else { + return a.exp > b.exp ? float_relation_greater : float_relation= _less; + } + } +} + +#define COMPARE(sz) \ +int float ## sz ## _compare(float ## sz a, float ## sz b, float_status *s)= \ +{ \ + decomposed_parts pa =3D float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb =3D float ## sz ## _unpack_canonical(b, s); \ + return compare_decomposed(pa, pb, false, s); \ +} \ +int float ## sz ## _compare_quiet(float ## sz a, float ## sz b, float_stat= us *s) \ +{ \ + decomposed_parts pa =3D float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb =3D float ## sz ## _unpack_canonical(b, s); \ + return compare_decomposed(pa, pb, true, s); \ +} + +COMPARE(16) +COMPARE(32) +COMPARE(64) + +#undef COMPARE + /* Multiply A by 2 raised to the power N. */ static decomposed_parts scalbn_decomposed(decomposed_parts a, int n, float_status *s) @@ -6892,60 +6972,6 @@ int float128_unordered_quiet(float128 a, float128 b,= float_status *status) return 0; } =20 -#define COMPARE(s, nan_exp) = \ -static inline int float ## s ## _compare_internal(float ## s a, float ## s= b,\ - int is_quiet, float_status *status) = \ -{ = \ - flag aSign, bSign; = \ - uint ## s ## _t av, bv; = \ - a =3D float ## s ## _squash_input_denormal(a, status); = \ - b =3D float ## s ## _squash_input_denormal(b, status); = \ - = \ - if (( ( extractFloat ## s ## Exp( a ) =3D=3D nan_exp ) && = \ - extractFloat ## s ## Frac( a ) ) || = \ - ( ( extractFloat ## s ## Exp( b ) =3D=3D nan_exp ) && = \ - extractFloat ## s ## Frac( b ) )) { = \ - if (!is_quiet || = \ - float ## s ## _is_signaling_nan(a, status) || = \ - float ## s ## _is_signaling_nan(b, status)) { \ - float_raise(float_flag_invalid, status); = \ - } = \ - return float_relation_unordered; = \ - } = \ - aSign =3D extractFloat ## s ## Sign( a ); = \ - bSign =3D extractFloat ## s ## Sign( b ); = \ - av =3D float ## s ## _val(a); = \ - bv =3D float ## s ## _val(b); = \ - if ( aSign !=3D bSign ) { = \ - if ( (uint ## s ## _t) ( ( av | bv )<<1 ) =3D=3D 0 ) { = \ - /* zero case */ = \ - return float_relation_equal; = \ - } else { = \ - return 1 - (2 * aSign); = \ - } = \ - } else { = \ - if (av =3D=3D bv) { = \ - return float_relation_equal; = \ - } else { = \ - return 1 - 2 * (aSign ^ ( av < bv )); = \ - } = \ - } = \ -} = \ - = \ -int float ## s ## _compare(float ## s a, float ## s b, float_status *statu= s) \ -{ = \ - return float ## s ## _compare_internal(a, b, 0, status); = \ -} = \ - = \ -int float ## s ## _compare_quiet(float ## s a, float ## s b, = \ - float_status *status) = \ -{ = \ - return float ## s ## _compare_internal(a, b, 1, status); = \ -} - -COMPARE(32, 0xff) -COMPARE(64, 0x7ff) - static inline int floatx80_compare_internal(floatx80 a, floatx80 b, int is_quiet, float_status *st= atus) { diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index c948727bbb..e5aa8d65f9 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -333,6 +333,8 @@ float16 float16_minnum(float16, float16, float_status *= status); float16 float16_maxnum(float16, float16, float_status *status); float16 float16_minnummag(float16, float16, float_status *status); float16 float16_maxnummag(float16, float16, float_status *status); +int float16_compare(float16, float16, float_status *status); +int float16_compare_quiet(float16, float16, float_status *status); =20 int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); --=20 2.15.1