From patchwork Tue Jan 9 12:22:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123905 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3958631qgn; Tue, 9 Jan 2018 04:26:01 -0800 (PST) X-Google-Smtp-Source: ACJfBosDgt3ShvAcygBqUQ4EluoPo9wTk13Fl5izhAS28hf+1zc96trCC4ABvO9I4vIrTcTFgEfg X-Received: by 10.37.232.1 with SMTP id k1mr14175816ybd.178.1515500761854; Tue, 09 Jan 2018 04:26:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515500761; cv=none; d=google.com; s=arc-20160816; b=CBx0W5eumsx9JQkEWOhtPhphlBNMH/kwzx/PeMXKPVTgJiGnsc9UHKCw/0WUkXiZfv nNFwUOXZAxj5DfaOVG9Aq3rrkbxcEUtMCYkab7QDpauXYIO5MyJH6eHy+2DJgb0hnbfs 4BwPANLgqtVIQJr6FJTu3AI98eFo1Ta5KkIPh95S6fAF7Vu/1yGjaEtayLFxp0ZOHtu3 i5+TKMbXUTTDNMWB7JpRYTnb1WBELFYfoQ/OffGmEQ0AbEDAttHC8bQsaNydkZ8WQgsm I/jxpgWWiEr2uy71LILvhjV9/OVIM9cP3kIVcLfHy9MqzkXV1lD4RgcTDypMO2mr9xsu wVIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=kFWWImcJFakK6Q/MS9IUPme+eMbtlWRk0/W9mj8nEvI=; b=SGgM0AnabDZmyDt4Q/muZLnjTCMU8IgO6bgHvYVvcZPd7bnssJ3nf/PYxgDytakk4V h+X9j1AIMDRVCFKMAuMWDWxjKGHk2mK8Tm3rqUyfRe0FOaiWJFUMJsvcmuIZYC2MTUxr 8JT9vrOR9UMkBqpHEINkauuYNFx0oR+hmMW+R8fEJdz/Rr6IkxKovUjxQo2Wo9Db8YX8 Y805iG34ZCqgmrfs8MhbRqDEgXH2kpHMcmNhYtZgfAmy0/KLVNzSjPl06KwGNWmQ/A3x xQ1+EuQn3PB0WEvgHbHCz27kE7b3WtBM/ynDhZCTxUY3XZC5x//Ue+XbSMDzdk2VOTjv XbvQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=LSBeNzBF; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id p190si3035081ybg.723.2018.01.09.04.26.01 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:26:01 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=LSBeNzBF; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49475 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYsyf-0000Oq-Be for patch@linaro.org; Tue, 09 Jan 2018 07:26:01 -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) 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-Received: by 10.28.16.211 with SMTP id 202mr11602347wmq.49.1515500574330; Tue, 09 Jan 2018 04:22:54 -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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This will be required when expanding the MINMAX() macro for 16 bit/half-precision operations. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- fpu/softfloat.c | 15 +++++++++++++++ include/fpu/softfloat.h | 1 + 2 files changed, 16 insertions(+) -- 2.15.1 Reviewed-by: Peter Maydell diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 433c5dad2d..3a4ab1355f 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3488,6 +3488,21 @@ static float16 roundAndPackFloat16(flag zSign, int zExp, return packFloat16(zSign, zExp, zSig >> 13); } +/*---------------------------------------------------------------------------- +| If `a' is denormal and we are in flush-to-zero mode then set the +| input-denormal exception and return zero. Otherwise just return the value. +*----------------------------------------------------------------------------*/ +float16 float16_squash_input_denormal(float16 a, float_status *status) +{ + if (status->flush_inputs_to_zero) { + if (extractFloat16Exp(a) == 0 && extractFloat16Frac(a) != 0) { + float_raise(float_flag_input_denormal, status); + return make_float16(float16_val(a) & 0x8000); + } + } + return a; +} + static void normalizeFloat16Subnormal(uint32_t aSig, int *zExpPtr, uint32_t *zSigPtr) { diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 0f96a0edd1..d5e99667b6 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -277,6 +277,7 @@ void float_raise(uint8_t flags, float_status *status); | If `a' is denormal and we are in flush-to-zero mode then set the | input-denormal exception and return zero. Otherwise just return the value. *----------------------------------------------------------------------------*/ +float16 float16_squash_input_denormal(float16 a, float_status *status); float32 float32_squash_input_denormal(float32 a, float_status *status); float64 float64_squash_input_denormal(float64 a, float_status *status); From patchwork Tue Jan 9 12:22:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123904 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3956086qgn; Tue, 9 Jan 2018 04:23:28 -0800 (PST) X-Google-Smtp-Source: ACJfBot1VEqh+ShVWvU19sHXwb5eaHEtO4dg7XIvXWTKG+OCzhl9c/Qq6yClkLi0eD6PoKrOZ/Cb X-Received: by 10.129.71.3 with SMTP id u3mr3249848ywa.218.1515500608137; Tue, 09 Jan 2018 04:23:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515500608; cv=none; d=google.com; s=arc-20160816; b=bUEj5fmMLzTZ6HClUy5ty7JrstN6D90OQUm16eMdRY0kMqcXZ0fbuYRLeqZjwaPVhB BQKPYwR5ovDzZQKi43sBOd3m+3oedZxVgxk+5QW5rDPRQIGkt4HQUW2mF5e8mkzjwbqK q5pawLd27nLPctu64NGbm6593+WMQUJ/vq0vJ+jmIfYaf9/SSORTwbkqv82fs5C938cP a/fQvTG5No81atrRr2YkutbBMufaJKduG1bpJzhLaaROz8uIXV9EtOEklVNG4mPTEt38 tqwmj+UzZw8N6uY8UrVXMdo9EBL+ffJHP5bmOC65zGrFScHF3K6WMJpb32LOnRn74OHf gr7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=o9l4F51J3K/m7rAhNxcgl01/dGyeul6MP8/bT8/jNP4=; b=L6mrvDmtVkKmIkRxzK+vK/NcD5hlMS27SRyRFfjXW2kgXVaa7zhNLMKT+x+J77R+RT 4BZhm8m4Zv9z6zulg8usUjveeBd1mNagxO7s7GYHlpJ4HaEVgPx7PYdtklKFb13JypeC J1xlXumQM8zrjHbAyg33lGbwqbnAGcCnmUmYxWx38Gqo3VFEy4KWVAIG3zQF4dqbPXjX S4gOHUizQ2ZqOoWWBC7qcRtB2FPSCKVWGioadXu/SZR7+Js8vDqOnOefMwzxiIC5HVvN JDOTGtBhXewsx+VTy2FnsLHvpHxeBe8vlfYs8fkZjhn9jlxbKZzbz8QswAqc0CgetXAT tt6w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=JqCn+PeI; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id j63si3050022yba.86.2018.01.09.04.23.28 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:23:28 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=JqCn+PeI; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49424 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYswB-0006bs-Kd for patch@linaro.org; Tue, 09 Jan 2018 07:23:27 -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) 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-Received: by 10.223.128.34 with SMTP id 31mr14505972wrk.248.1515500575299; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- include/fpu/softfloat.h | 27 --------------------------- 1 file changed, 27 deletions(-) -- 2.15.1 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 = {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 = {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 = {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; From patchwork Tue Jan 9 12:22:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123902 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3956070qgn; Tue, 9 Jan 2018 04:23:26 -0800 (PST) X-Google-Smtp-Source: ACJfBos6kcRV+lD0/yKU1/FS1aGdSEeRqpZYaPCWlH/vuZ+6cUAGlbOyAIyDG8Uo/KyeCU5qIJ9d X-Received: by 10.129.122.195 with SMTP id v186mr5077429ywc.95.1515500606783; Tue, 09 Jan 2018 04:23:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515500606; cv=none; d=google.com; s=arc-20160816; b=H5LtCys0bv4JFb/gEdCkKKnPPg4t3Szo9NYugzjE9nd8FZQjvGfAOtj4vAb/Egz64e sLD0ECC+Xo6X0b5keVfEj/mm7CwqlSitAiaccm0+Fs9/bgOwUCBHLtDj4JdBWZ+5YEjt qO9CWFF27sIJJJ1o1QAYuR/MLr1qhJSBmA8EZZJ6Ujh0n1KT83LZDM9FpS6zfoGNgN+l ggFhPQfWiZ1gwv2Crgj5TdYvQlHLTEJ60vkcq/hy6WQPOG4tWr7vay2QZMPvPSiQd/Bb uuz/sw8YQI1sSrylgMXP2yPEuNCh+BkRCz9imJfemdoC6gqvcMzbxnX4Igroiqkm+U9P gMyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=87/TgytgcRnsZ9ORu6HegwY7s5qXzy9GuhJ9dMbtH00=; b=QrAuHWthnA7l9smRu3J1oaRuXK8ueld1curJGjd1qUlPKfobL9naorJLtscFzN+yVW S8hAm5ct0CCY7imclcNYSkyUzX9d4teL5chekvQr/arz1vdlaAXSUXGA28YO4kjyfDn1 sTyH/q0djkyxSi3YqkphH7qBK8IAPNoNT6IeQHwWn4eLM/m+eO2Uc1f5aWa4WmmmOK9+ rtAK8q+2rXSmqcl4t6Ccg25YF3rKgCHxZcmAYvKcDueWbKGgfj9Kb6im5xfd/+/J8lAu LAvpNCVqHeNobpv4JDzZekyiPRU0As5f7bVhpsvXPGFgeV3msdbNrL41Feax8bUNDl8f +iEw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=iRaPK+Fc; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id u17si2927618ybk.367.2018.01.09.04.23.26 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:23:26 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=iRaPK+Fc; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49423 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYswA-0006bJ-8g for patch@linaro.org; Tue, 09 Jan 2018 07:23:26 -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) 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-Received: by 10.223.134.26 with SMTP id 26mr12417119wrv.218.1515500576407; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This will be required when expanding the MINMAX() macro for 16 bit/half-precision operations. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé --- include/fpu/softfloat.h | 7 +++++++ 1 file changed, 7 insertions(+) -- 2.15.1 Reviewed-by: Peter Maydell 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) == 0; } +static inline float16 float16_abs(float16 a) +{ + /* Note that abs does *not* handle NaN specially, nor does + * it flush denormal inputs to zero. + */ + return make_float16(float16_val(a) & 0x7fff); +} /*---------------------------------------------------------------------------- | The pattern for a default generated half-precision NaN. *----------------------------------------------------------------------------*/ From patchwork Tue Jan 9 12:22:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123910 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3963184qgn; Tue, 9 Jan 2018 04:31:02 -0800 (PST) X-Google-Smtp-Source: ACJfBos2EJ/FNr+oW/5qwZTMUktPAXM76FGFHNMVqDatdqNa5AJiSuFlB7xbPdOeGf+ZmvXSVv5B X-Received: by 10.129.51.150 with SMTP id z144mr3730777ywz.417.1515501062108; Tue, 09 Jan 2018 04:31:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501062; cv=none; d=google.com; s=arc-20160816; b=Df2RT5Ba6hxQvrTKBFL7HDICD/PoKiHk2rHjKk73phgscg7+KVEYr93AvFkUicYjKQ 2w64P8cK2a33TDTjhrd7MQZSd6oPzAl784R1XHIL7opiMWkQj0b9XBDGVyYx633lH8mA WHEm60efMV2C0/1XyX41uta1NmgeBZ2gRg4ZLATfbyPpERrQP44JL0ApRbn8yiOzVswJ uoKR33wpV+O8YrMV9tXG9D7T7PrIlMRhkP7JJfMA8jteCbeamcT4Dzdvr16UQWZZtcZd 4I+dqdFo/ZLssCwS5EOIGZRMMq6/6syqd9T3DyJhE9EqMcjVcnK1axHtbjmiQZEEr2sd GIqQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=KtfrcwYYHDPEWFKEmcYMWUVtcVxZcGJDHkDjYRTzgt8=; b=0RzByhC7Un1406l0dfiSkeLqQocr4NAv6hTpC0O68/qJw9+csR36j2hQ7gkhfUQQWm AteQJMKJX+/dYqbHuE5R2rmM/lBQqQN3CX+k4kYEyK6wE4lD4Uy39K/GsmekIcRylV1n CH9M7FyIbrPPb4GD7A3yZvLNsiDSFz/StS+wy7lfbhxloRFpXShU3pzhiyULIUCenvsM j+GLd159gWB4dw2CKMIAtZGyJecBsyFx4f/uprMy7oB0n8G13VYJYewJmUfU04QZjMEb pNHlcjZV2EaF/dLLdBUlxviTVJ10xfztv2nXBzfNtTbpjl/JK34ohwaulWijMcMEDtUL rXpw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=A4/erq9/; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id x199si3001933ybe.780.2018.01.09.04.31.02 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:31:02 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=A4/erq9/; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49525 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt3V-0003SS-FQ for patch@linaro.org; Tue, 09 Jan 2018 07:31:01 -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) 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-Received: by 10.223.187.8 with SMTP id r8mr6025777wrg.269.1515500579912; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- include/fpu/softfloat.h | 9 +++++++++ 1 file changed, 9 insertions(+) -- 2.15.1 Reviewed-by: Peter Maydell 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. *----------------------------------------------------------------------------*/ From patchwork Tue Jan 9 12:22:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123907 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3960446qgn; Tue, 9 Jan 2018 04:28:03 -0800 (PST) X-Google-Smtp-Source: ACJfBouqvFhDmjjOHccU0maZZMu7Ku1RP25JfrDBnrJjjd6ftGyqzD2JzmCB1p1tSLewW5Zl3YXB X-Received: by 10.13.202.19 with SMTP id m19mr6038663ywd.70.1515500883625; Tue, 09 Jan 2018 04:28:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515500883; cv=none; d=google.com; s=arc-20160816; b=tICUVQ2ubcUh1yyoFQaZmKyLtPDfbEpgwXc9sisrH8tuX06F4Zp4SxeS0P8pH/6Mn9 a2vZKep19QOfYuV0PpPHyvS/zTDoli/R8x/U9p2D9gZEJ8AXwqEgDlENToyJTrGwESfC teT7fgG6ujvOuwF7Z832SCmCF9oKn+WAAhKIvU+g/NoO0jZvgCxUjCfmapzmy3qCKep0 ca7H3GcYR3br/J0DHmhbx8Pm86eZ03PC8MNz+0a2VlAW7dSiDSLMpsg93YQBGtIO0lRb 0pEfFGoTORCmnzrRbhe1P8Djx5vpNelSZH7L/Yc0Lnx188W5FmqIqy8eeCMaaDEqmnbv Mf6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=kAN0+Gi2kG5Pzf3bBOa0T2FJ1NA02CRitdLzfGe1bDI=; b=znyAypePStuJzveDLYZmkTZsAdfUuG85zIAop94OoVsyvxJJD2xiS5/Q5T3CUsVBH7 BZK5M/e232Lfzj/VtnloyinwQlvAqO0/1PMMJkdTZOdlrT1sDN+sH37HjcM/OkXTV9Pv 6rRR/8MgS0N5qnsGbBJ3cpx5WQPzX021aN1o0nGUUz387kpU33JmrmPGY4qHyfpszjjB OUqtKY4uIVWJgSfWX4OKu7El2kwNIVaTCDVd62mqsSWJij3lMhIBzXei0YQATvmcPoDV DYoOOS5o+dj5w1OnnE2STbdUIS3gU3LlocG3X+MIR+bYiCaM39oeTi2DCH+zhd/rJLbj +VvQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=etFwRA5B; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id y71si1133175ywd.413.2018.01.09.04.28.03 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:28:03 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=etFwRA5B; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49486 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt0d-0001IO-4W for patch@linaro.org; Tue, 09 Jan 2018 07:28:03 -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) 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-Received: by 10.223.172.199 with SMTP id o65mr6375955wrc.215.1515500577414; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Alex Bennée --- include/fpu/softfloat.h | 5 +++++ 1 file changed, 5 insertions(+) -- 2.15.1 Reviewed-by: Peter Maydell 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); } +static inline float16 float16_set_sign(float16 a, int sign) +{ + return make_float16((float16_val(a) & 0x7fff) | (sign << 15)); +} + /*---------------------------------------------------------------------------- | The pattern for a default generated half-precision NaN. *----------------------------------------------------------------------------*/ From patchwork Tue Jan 9 12:22:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123906 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3960427qgn; Tue, 9 Jan 2018 04:28:02 -0800 (PST) X-Google-Smtp-Source: ACJfBou4ZmDF9o8UVeM/RRp6bJVFN4b9e9g7omIUyzvYC1Vq85yCO5o/yLZ/2IwmAl+ta0tgyu36 X-Received: by 10.37.183.142 with SMTP id n14mr13841211ybh.214.1515500882814; Tue, 09 Jan 2018 04:28:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515500882; cv=none; d=google.com; s=arc-20160816; b=Bq4JpbkR48OOFOnV8PqtLlHxcd97xGOO38W7E9IswEcw7/venmChPLJZQeDdx3OPnR YJWuOEeKWh24N6OibCX7gyxrC6VucPrdeaIKKdOBP5gMH8RrS8Ibw+m6WXt4+A2IsVJA nxZpsFkJ+/fz4lTvi74We4wJeN3ZgQO6hB3BRcNYlVRPM8TvqERPt8ITl/bB61zbJ1sb uopSB1TsPamojXdLGzVqrOKQvg46fkKDvv5z1OIXQvks2bf6FIr67e0K0CaU63JnbY9n df2iNhnJx9Cc6hNUwTV2G1+WHycwObQo1hcG0hrUYxfLcO4EQ1mWwARe4KwwAbo/xHej PSNg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=wZxx7z+WQCnQ78WbUwlXVYn9xXoslXabdFmm18Cqbbs=; b=W7TMnMivjHXUa67D7K0SvKQz2WelZBhhvYfBh3zhJCNgq++/RsinhOlR2JLuAyvEMJ KkKTNnaOvrBoN5t21pionpfDsrsnJeZQxrlut4xWVPrkpXQpm04ClNB2WZNoBlUSPw4B R8/ux3rAyb0PI9t/YPegwHyWxL8Lfz1NUAYJdZ6vIIBJGgsRvtSVEIz85iLu3KAtQ7v1 /88km0bP+A4VLqdV+TEgdnoGdJxRESkFtt833TL+fdPm1aekXgfz5OUL1MOM4BgsSgPO RL0LqBkWOZa7pzErJeqkZfyWjCKy1uvfOrfXHXeFXthE/cP1TJaoMaRn/6aXaW76jIKg bQwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Y0yGmolR; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id g184si2932966yba.548.2018.01.09.04.28.02 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:28:02 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Y0yGmolR; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49488 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt0c-0001IU-93 for patch@linaro.org; Tue, 09 Jan 2018 07:28:02 -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) 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-Received: by 10.223.158.144 with SMTP id a16mr14236070wrf.83.1515500578341; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This defines the same set of common constants for float 16 as defined for 32 and 64 bit floats. These are often used by target helper functions. I've also removed constants that are not used by anybody. Signed-off-by: Alex Bennée --- v2 - fixup constants, remove unused onces --- include/fpu/softfloat.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) -- 2.15.1 Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Peter Maydell 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)); } +#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 sign) #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) @@ -588,7 +591,6 @@ static inline float64 float64_set_sign(float64 a, int sign) #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) From patchwork Tue Jan 9 12:22:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123908 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3960803qgn; Tue, 9 Jan 2018 04:28:28 -0800 (PST) X-Google-Smtp-Source: ACJfBotCdU/qdfliJAQADOe+PNpnv20aeBfXvv17cHgq2NLUpY4tS2iJ2dKjEMa9J+mf45DInYCJ X-Received: by 10.13.222.130 with SMTP id h124mr13509629ywe.217.1515500908620; Tue, 09 Jan 2018 04:28:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515500908; cv=none; d=google.com; s=arc-20160816; b=rAAHyF0wJFs1sCz8O7h/GryEW6TXesQkKvW5EonZrP/U87jqRwt3Z+FCqJI0Zo9LYh a5fpITJi6nkDtIe9mXya/9bEzyGSTjyNDgZAaZc3PogzgONWWrSW4OOmINdeRwZAESBV 3vtMAdrUj94NMkB2nIthvCM9x0c9NQtuazNo0h9zyUDbiSjsUdIQF3YNzTbgxju1y8qs IyOpL2vsUuX/G+kebi6eB+4iaFRcCJE8lPSqMvbdtmJIFOK0y8bNYBl7FM3QBA1f0W1Y IHmfqbPkYcQD9Hv3Zlw+FfqoGUUCLGUSA7RZZ4S/akFEeN9BJBD7VRXjw29n32kjgwNu PoZg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=CMj7/OCLKuOKn1F/BoEznnKNy9Zs3Wj1+nU1V8x9KRo=; b=UAIuI5EyxrmAIP0C+Wgk29EOj5YZUqqSR18YU0nd4Mm9xWPzQpqE98q/LBOYDrSUWn QHVKArv4n4+YroJLVyFB/ClQPwP/XjzRRPLb4M7bvNCU9aOeVNI0pHzNTpE4INjSSgx+ dtu4iR26QD2gNFP5xyjdjnOyXDoTFoNMySM9oyB9eF8vulTEQN8lLB6Grzxz6JKXduTA mVAVEHM8ExNEmajf6WnGHNAnUbBblmo89EpGxdjZ55w0XrQNyWWdNroXI0JXuaasV3fq IWjip3uZ5IXKxDo055Iuh2h5uJ2Eui3wo0lGDMLmLkNaHM+R2C0p9ienc94To/vPxTTu yoZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ayaBk4gP; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id g62si3039867ybb.592.2018.01.09.04.28.28 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:28:28 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ayaBk4gP; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49509 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt12-0002Gl-2n for patch@linaro.org; Tue, 09 Jan 2018 07:28:28 -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) 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-Received: by 10.223.164.148 with SMTP id g20mr13218352wrb.177.1515500582427; Tue, 09 Jan 2018 04:23:02 -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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" While a comparison between a QNaN and a number will return the number it is not the same with a signaling NaN. In this case the SNaN will "win" and after potentially raising an exception it will be quietened. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- v2 - added return for propageFloat --- fpu/softfloat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3a4ab1355f..44c043924e 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -7683,6 +7683,7 @@ int float128_compare_quiet(float128 a, float128 b, float_status *status) * minnum() and maxnum() functions. These are similar to the min() * and max() functions but if one of the arguments is a QNaN and * the other is numerical then the numerical argument is returned. + * SNaNs will get quietened before being returned. * minnum() and maxnum correspond to the IEEE 754-2008 minNum() * and maxNum() operations. min() and max() are the typical min/max * semantics provided by many CPUs which predate that specification. @@ -7703,11 +7704,14 @@ static inline float ## s float ## s ## _minmax(float ## s a, float ## s b, \ if (float ## s ## _is_any_nan(a) || \ float ## s ## _is_any_nan(b)) { \ if (isieee) { \ - if (float ## s ## _is_quiet_nan(a, status) && \ + if (float ## s ## _is_signaling_nan(a, status) || \ + float ## s ## _is_signaling_nan(b, status)) { \ + return propagateFloat ## s ## NaN(a, b, status); \ + } else if (float ## s ## _is_quiet_nan(a, status) && \ !float ## s ##_is_any_nan(b)) { \ return b; \ } else if (float ## s ## _is_quiet_nan(b, status) && \ - !float ## s ## _is_any_nan(a)) { \ + !float ## s ## _is_any_nan(a)) { \ return a; \ } \ } \ From patchwork Tue Jan 9 12:22:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123917 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3967088qgn; Tue, 9 Jan 2018 04:34:43 -0800 (PST) X-Google-Smtp-Source: ACJfBotiRdTloEhcft/CDZbFjVnQw8fW8Zm+nmI+SqoGRMrzY2EWqQIBFd7N1ZSY4I0JsB4lN7MW X-Received: by 10.37.214.213 with SMTP id n204mr12094178ybg.67.1515501282995; Tue, 09 Jan 2018 04:34:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501282; cv=none; d=google.com; s=arc-20160816; b=aje9jQOOx/3GareYxKr/66AWWECDGjKRK4jZi1Zz04ik5l63TLhCH8BaXhNS4ykpI7 wcvjgZ5a9Hn2kPr+nptKICGLjQO+dn34z2ccENeEmtirF/SqI0p5138DeRArZoKHIHlq nfgJ/qhrqS4oJ9Lt6lqgOUCOXavMYE1OHlTiIH5srpCW+2z/y6DmPybOb+0Y3QyudGW5 Tu9At1Bs6lJTo7dYIbW19TWvrFvIMMiutlX/q2igBEUBm09244PPO6CBeYVh2aic7VEK G8SMj9OCorwKPAojnfL0G/XtqqygoIZmduRpaiww3WCYO36lFkwvHzpqvTe15o4pvTEf CVng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=w73w7ZZQIMHcKkvA79sIXqgUK5/buI45QDc8gpNpU+E=; b=cMNPalOpeqMQvNWVCJTW/O2dDZUga1fV+YnmLJDlOpYzMV1f5nOoPdsQBJSd03NOhd g2nmciIvtimoMEYY58j34FykeOzydW4WaO1yAOVCr16fWeRE6HdY0CvMRE4MikrtO40D TLAM9M+Ph0/N/IAHg6gfAkiU14hCjEzXhW1iTs+ozQ+mV7FFkmTqvWkRqO+R+e1x9J6t b6TcnFXrbgut8biWujbaMxp9rEqfZwcb/MOnWb7W6473HXWGp7+4JNIgJ7TIa0y2x+z+ NtS1yZFJblPUsB70/pIqSh1gkgKKg3X6rPDymENQcgUGu4+lr7k0mL9oHoZC6UH8//6P QY5A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=IfJKldQL; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id x15si999220ywd.123.2018.01.09.04.34.42 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:34:42 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=IfJKldQL; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49552 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt74-0007Rq-Cv for patch@linaro.org; Tue, 09 Jan 2018 07:34:42 -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) 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-Received: by 10.28.106.26 with SMTP id f26mr11098557wmc.40.1515500584601; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Mention the pseudo-code fragment from which this is based and correct the spelling of signalling. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- fpu/softfloat-specialize.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) -- 2.15.1 diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index de2c5d5702..3d507d8c77 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -445,14 +445,15 @@ static float32 commonNaNToFloat32(commonNaNT a, float_status *status) #if defined(TARGET_ARM) static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, - flag aIsLargerSignificand) + flag aIsLargerSignificand) { - /* ARM mandated NaN propagation rules: take the first of: - * 1. A if it is signaling - * 2. B if it is signaling + /* ARM mandated NaN propagation rules (see FPProcessNaNs()), take + * the first of: + * 1. A if it is signalling + * 2. B if it is signalling * 3. A (quiet) * 4. B (quiet) - * A signaling NaN is always quietened before returning it. + * A signalling NaN is always quietened before returning it. */ if (aIsSNaN) { return 0; From patchwork Tue Jan 9 12:22:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123915 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3966399qgn; Tue, 9 Jan 2018 04:34:05 -0800 (PST) X-Google-Smtp-Source: ACJfBov2oPbE14gwRmNduZTI2l+cdeFddcdhEit3/zqxT/YJec4DE5L48FArhnzz9Uoyai6Rxx57 X-Received: by 10.37.53.6 with SMTP id c6mr13866577yba.125.1515501245319; Tue, 09 Jan 2018 04:34:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501245; cv=none; d=google.com; s=arc-20160816; b=uC7OcjTm4PXkNTQjEgAFgwvkfaDSARRty8uiIU4Kps/B73jr3BdfvAuxEcVtDRZFoe tl6mwyYiLum/NpDcOuIUfVEkWASudM5OiZr4uzuDv9VgJJsi5IWelp22gbETYkJLSalW iLg6opG2MqFHJxQ7k8LbnZcHXvcMQIY2m2JH70PXHhjIzuyHsOwVpgrFh0jrCo3rX5T1 frwoVx5ymRMJCnv5HNYb2nApDLk1LKUdflQ0TvumHwu7PiRzr+bpEuk+xS2NGZwg/bwP PfJgVulLbTFAs10ltiHWM18Ntx8mgdA/u7LAPzXAKop5NDZ6J//HU45/ajC95A19sAmR ZPFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=0khpgXmq2qgbbb8kOfF1HJdjZVtA5n1xM++dq8n/wIA=; b=NtIbtadjY/ElkU8ETAXBLylKW/U3+dImYxPcZslfX6muaQVojQ54A/W4Pc0wp2zIrt Kle+hv/uszt1js3LrjJIGY053P4NG1jSu7pLeefjIMvjrTkEyZx4CtWGGZF5irFDrH6L RaMnX4m8Aw6dK0+6DbweWJUtC/E5i46sH/dKv+ReDjgRn0OARbrRmphlQS5aJbiviX2P 6j8lOQBnZkiO4rYCeOGKOoJTCbp2J5Ps0viw6zGaOafHzz0NgXaBZyp8TbKU5VJYw61J ixNNUSuzTf58WYDzWHm1y2YAGRsl9F6K8vOtD2gMzk6p+TK2/GR/FNrWDR7dvj90P4UV /7dg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Hy4poktA; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id w12si2990566ywj.582.2018.01.09.04.34.05 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:34:05 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Hy4poktA; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49543 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt6S-00062W-NV for patch@linaro.org; Tue, 09 Jan 2018 07:34:04 -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) 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-Received: by 10.28.183.8 with SMTP id h8mr10626199wmf.62.1515500585634; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This is pure code-motion during re-factoring as the helpers will be needed earlier. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- v2 - fix minor white space nit --- fpu/softfloat.c | 120 +++++++++++++++++++++++++------------------------------- 1 file changed, 54 insertions(+), 66 deletions(-) -- 2.15.1 Reviewed-by: Peter Maydell 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; } +/*---------------------------------------------------------------------------- +| 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; } -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline uint32_t extractFloat32Frac( float32 a ) -{ - - return float32_val(a) & 0x007FFFFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline int extractFloat32Exp(float32 a) -{ - - return ( float32_val(a)>>23 ) & 0xFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline flag extractFloat32Sign( float32 a ) -{ - - return float32_val(a)>>31; - -} - /*---------------------------------------------------------------------------- | If `a' is denormal and we are in flush-to-zero mode then set the | input-denormal exception and return zero. Otherwise just return the value. @@ -492,39 +513,6 @@ static float32 } -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline uint64_t extractFloat64Frac( float64 a ) -{ - - return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF ); - -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline int extractFloat64Exp(float64 a) -{ - - return ( float64_val(a)>>52 ) & 0x7FF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -static inline flag extractFloat64Sign( float64 a ) -{ - - return float64_val(a)>>63; - -} - /*---------------------------------------------------------------------------- | If `a' is denormal and we are in flush-to-zero mode then set the | input-denormal exception and return zero. Otherwise just return the value. From patchwork Tue Jan 9 12:22:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123911 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3963730qgn; Tue, 9 Jan 2018 04:31:35 -0800 (PST) X-Google-Smtp-Source: ACJfBovdkryarvsRTozy5aQOCXKXWkVoI/tyMHHHjJQ89KArWkyUWB9+t4ERFIReuoIj51Sc4fbu X-Received: by 10.129.72.204 with SMTP id v195mr6661579ywa.448.1515501095506; Tue, 09 Jan 2018 04:31:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501095; cv=none; d=google.com; s=arc-20160816; b=zSdhq8bwp5lf8AjTk6A+kVVabZvQpcl4jO9Edpsrp5h5CK+lYqj+crGMi8Sx1Dd1rJ SXVMEDuXRL4/n51IZel8Nkzrgsd5K2Tn8y8FNx97MvuKho2ZGt/zHcDW4Ke+st1EEgxz c506GRJ5r//rNlDL3kSruKIqrpkkGzt1i5dp6Qs73ihNB7Vz1wZIQTmyeJ8d5+j9V0SI aMm73hwjxg/C3Wt9AVpuCdGvhzOmTMYqJqistUjrzutOqFpn4Q07FFBZGG/oF/ieSnlH pSqAfGQSyQyQnMquzfGootYuqtpeQfvd2bpV98ABHehDVSdmsWO9pR+TEDYoTTzjITOL vcSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=TuqpRZxm6uXuRzIpBThQodutJC+WGgUS7fzwpNjLwqk=; b=NE6veu1dKkP4zWPqC1XKbICEO+71poZRey9Wcu4LewsF1GpUiySAPtIv172EjWNpT2 lH8Lzkk+qhOt9dIPsQBlnDKwGW/CqKGpcjycubIC0NkwSrh//K/YSHn1adykoSif+Bai oS/yweQbLHS8oTy1pkpvLrZizYKuQVgs4HF1BfxnWbfHsdHn1KsjBQzOHR2Lx0FkodCo cmKRirVJB0KSTfYThBfgSlVRp7prmmgRkFsrhlIi7CixN8cssrdYxY+oFzVYsyuM/+9M C6trj+FMrSeCGyTsNKAtWee8dsNu81t7vq/ecDGfedcEl/C88AuCXwGWx7qWSXMZIFwA 9JQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=A7S/kq8M; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id c190si772465ywh.761.2018.01.09.04.31.35 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:31:35 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=A7S/kq8M; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49538 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt43-0004tJ-0X for patch@linaro.org; Tue, 09 Jan 2018 07:31:35 -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) 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-Received: by 10.223.177.143 with SMTP id q15mr12524719wra.228.1515500583457; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" These structures pave the way for generic softfloat helper routines that will operate on fully decomposed numbers. Signed-off-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) -- 2.15.1 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" /* We only need stdlib for abort() */ @@ -186,6 +186,74 @@ static inline flag extractFloat64Sign(float64 a) return float64_val(a) >> 63; } +/*---------------------------------------------------------------------------- +| Classify a floating point number. +*----------------------------------------------------------------------------*/ + +typedef enum { + float_class_unclassified, + float_class_zero, + float_class_normal, + float_class_inf, + float_class_qnan, + float_class_snan, + float_class_dnan, + float_class_msnan, /* maybe silenced */ +} float_class; + +/*---------------------------------------------------------------------------- +| Structure holding all of the decomposed parts of a float. +| The exponent is unbiased and the fraction is normalized. +*----------------------------------------------------------------------------*/ + +typedef struct { + uint64_t frac : 64; + int exp : 32; + float_class cls : 8; + int : 23; + bool sign : 1; +} decomposed_parts; + +#define DECOMPOSED_BINARY_POINT (64 - 2) +#define DECOMPOSED_IMPLICIT_BIT (1ull << DECOMPOSED_BINARY_POINT) +#define DECOMPOSED_OVERFLOW_BIT (DECOMPOSED_IMPLICIT_BIT << 1) + +/* Structure holding all of the relevant parameters for a format. */ +typedef struct { + int exp_bias; + int exp_max; + int frac_shift; + uint64_t frac_lsb; + uint64_t frac_lsbm1; + uint64_t round_mask; + uint64_t roundeven_mask; +} decomposed_params; + +#define FRAC_PARAMS(F) \ + .frac_shift = F, \ + .frac_lsb = 1ull << (F), \ + .frac_lsbm1 = 1ull << ((F) - 1), \ + .round_mask = (1ull << (F)) - 1, \ + .roundeven_mask = (2ull << (F)) - 1 + +static const decomposed_params float16_params = { + .exp_bias = 0x0f, + .exp_max = 0x1f, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 10) +}; + +static const decomposed_params float32_params = { + .exp_bias = 0x7f, + .exp_max = 0xff, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 23) +}; + +static const decomposed_params float64_params = { + .exp_bias = 0x3ff, + .exp_max = 0x7ff, + FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 52) +}; + /*---------------------------------------------------------------------------- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to the From patchwork Tue Jan 9 12:22:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123916 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3967046qgn; Tue, 9 Jan 2018 04:34:41 -0800 (PST) X-Google-Smtp-Source: ACJfBovU7iizYL92iEQUioPTn7Bf3AJ0Z6LdOCArTWF5RJz4ed1zayVebC236kYauxz498kZ5Qbn X-Received: by 10.129.51.68 with SMTP id z65mr13463319ywz.475.1515501280915; Tue, 09 Jan 2018 04:34:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501280; cv=none; d=google.com; s=arc-20160816; b=hIIuYxWTT7xqqlJvfDZJc0ngX+KYsGTEw81ByYrXnI/pO0Cs23OzCQ2r9lRrUZBTZq tO1N6G0aBLU/ZiIrAJb1dnOiYXOYanDZsxk5MHFXennlXgU6Jtv8u46VewuoEs/AxI9U Bh19F98bHxtdKf25mtINpE3SbqZHPBIcWn48lzIfIOXQFmVR0ycg9BW2KrgZC54+yGkO y3b+9uEducup3E+eK2kIiwyn1cjsG3PjAZ4yHEVfyw6iu/mpjX5opZVZhrPrk2UtFh1x 06qOZ+up3470wKVenVzfRPN/7CQQPLf1DQUGNK8ZG0q0zf5t4F0xf4zCf+j1b0EDNdXS j4rw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=4azIq6vBvtc1ef4ukor3jmbdpMza9m9Op+G8OFa13YY=; b=lVYLIii5JJ41s90Qod7HiHiibJIR6k1C+y7jmXDP23vIi9U2qbagLxn5dDyo5wkxzC u1gMPhswkGTB66+rQXqLDqRByPdfLL9AAxQBkYSf5vaq8FabFIyQ9l51nLJjyV2u1lx8 Vpoj9tJnOSBlmA/pZB1ajhQBWncY9iM4iktzjbhTRLY6HbGQBiW14UjrQ940swrMNin5 BdHuARAoRg8EJiX16ZpMw9rjoK8uWjz6G2iJY72QvrSyODLfpUBSi+9OeI2w23fIxOTj Nnzqm+CcLoBUpmsc3Zm4yzai+KdFN5Q/LVTXl6GFFxwqYSxw+WXomDSeV5zBLogiXGoM aIOA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=FxtQNtT4; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id z62si2971853ybz.187.2018.01.09.04.34.40 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:34:40 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=FxtQNtT4; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49550 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt72-0007OL-AG for patch@linaro.org; Tue, 09 Jan 2018 07:34:40 -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) 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-Received: by 10.28.6.6 with SMTP id 6mr11156500wmg.8.1515500587714; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" We can now add float16_add/sub and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 add and sub functions. Signed-off-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 904 +++++++++++++++++++++++++----------------------- include/fpu/softfloat.h | 4 + 2 files changed, 481 insertions(+), 427 deletions(-) -- 2.15.1 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 = { FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 52) }; +/* Unpack a float16 to parts, but do not canonicalize. */ +static inline decomposed_parts float16_unpack_raw(float16 f) +{ + return (decomposed_parts){ + .cls = float_class_unclassified, + .sign = extract32(f, 15, 1), + .exp = extract32(f, 10, 5), + .frac = extract32(f, 0, 10) + }; +} + +/* Unpack a float32 to parts, but do not canonicalize. */ +static inline decomposed_parts float32_unpack_raw(float32 f) +{ + return (decomposed_parts){ + .cls = float_class_unclassified, + .sign = extract32(f, 31, 1), + .exp = extract32(f, 23, 8), + .frac = extract32(f, 0, 23) + }; +} + +/* Unpack a float64 to parts, but do not canonicalize. */ +static inline decomposed_parts float64_unpack_raw(float64 f) +{ + return (decomposed_parts){ + .cls = float_class_unclassified, + .sign = extract64(f, 63, 1), + .exp = extract64(f, 52, 11), + .frac = extract64(f, 0, 52), + }; +} + +/* Pack a float32 from parts, but do not canonicalize. */ +static inline float16 float16_pack_raw(decomposed_parts p) +{ + uint32_t ret = p.frac; + ret = deposit32(ret, 10, 5, p.exp); + ret = deposit32(ret, 15, 1, p.sign); + return make_float16(ret); +} + +/* Pack a float32 from parts, but do not canonicalize. */ +static inline float32 float32_pack_raw(decomposed_parts p) +{ + uint32_t ret = p.frac; + ret = deposit32(ret, 23, 8, p.exp); + ret = deposit32(ret, 31, 1, p.sign); + return make_float32(ret); +} + +/* Pack a float64 from parts, but do not canonicalize. */ +static inline float64 float64_pack_raw(decomposed_parts p) +{ + uint64_t ret = p.frac; + ret = deposit64(ret, 52, 11, p.exp); + ret = deposit64(ret, 63, 1, p.sign); + return make_float64(ret); +} + +/* Canonicalize EXP and FRAC, setting CLS. */ +static decomposed_parts decomposed_canonicalize(decomposed_parts part, + const decomposed_params *parm, + float_status *status) +{ + if (part.exp == parm->exp_max) { + if (part.frac == 0) { + part.cls = float_class_inf; + } else { +#ifdef NO_SIGNALING_NANS + part.cls = float_class_qnan; +#else + int64_t msb = part.frac << (parm->frac_shift + 2); + if ((msb < 0) == status->snan_bit_is_one) { + part.cls = float_class_snan; + } else { + part.cls = float_class_qnan; + } +#endif + } + } else if (part.exp == 0) { + if (likely(part.frac == 0)) { + part.cls = float_class_zero; + } else if (status->flush_inputs_to_zero) { + float_raise(float_flag_input_denormal, status); + part.cls = float_class_zero; + part.frac = 0; + } else { + int shift = clz64(part.frac) - 1; + part.cls = float_class_normal; + part.exp = parm->frac_shift - parm->exp_bias - shift + 1; + part.frac <<= shift; + } + } else { + part.cls = float_class_normal; + part.exp -= parm->exp_bias; + part.frac = DECOMPOSED_IMPLICIT_BIT + (part.frac << parm->frac_shift); + } + return part; +} + +/* Round and uncanonicalize a floating-point number by parts. + There are FRAC_SHIFT bits that may require rounding at the bottom + of the fraction; these bits will be removed. The exponent will be + biased by EXP_BIAS and must be bounded by [EXP_MAX-1, 0]. */ +static decomposed_parts decomposed_round_canonical(decomposed_parts p, + float_status *s, + const decomposed_params *parm) +{ + const uint64_t frac_lsbm1 = parm->frac_lsbm1; + const uint64_t round_mask = parm->round_mask; + const uint64_t roundeven_mask = parm->roundeven_mask; + const int exp_max = parm->exp_max; + const int frac_shift = parm->frac_shift; + uint64_t frac, inc; + int exp, flags = 0; + bool overflow_norm; + + frac = p.frac; + exp = p.exp; + + switch (p.cls) { + case float_class_normal: + switch (s->float_rounding_mode) { + case float_round_nearest_even: + overflow_norm = false; + inc = ((frac & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0); + break; + case float_round_ties_away: + overflow_norm = false; + inc = frac_lsbm1; + break; + case float_round_to_zero: + overflow_norm = true; + inc = 0; + break; + case float_round_up: + inc = p.sign ? 0 : round_mask; + overflow_norm = p.sign; + break; + case float_round_down: + inc = p.sign ? round_mask : 0; + overflow_norm = !p.sign; + break; + default: + g_assert_not_reached(); + } + + exp += parm->exp_bias; + if (likely(exp > 0)) { + if (frac & round_mask) { + flags |= float_flag_inexact; + frac += inc; + if (frac & DECOMPOSED_OVERFLOW_BIT) { + frac >>= 1; + exp++; + } + } + frac >>= frac_shift; + + if (unlikely(exp >= exp_max)) { + flags |= float_flag_overflow | float_flag_inexact; + if (overflow_norm) { + exp = exp_max - 1; + frac = -1; + } else { + p.cls = float_class_inf; + goto do_inf; + } + } + } else if (s->flush_to_zero) { + flags |= float_flag_output_denormal; + p.cls = float_class_zero; + goto do_zero; + } else { + bool is_tiny = (s->float_detect_tininess + == float_tininess_before_rounding) + || (exp < 0) + || !((frac + inc) & DECOMPOSED_OVERFLOW_BIT); + + shift64RightJamming(frac, 1 - exp, &frac); + if (frac & round_mask) { + /* Need to recompute round-to-even. */ + if (s->float_rounding_mode == float_round_nearest_even) { + inc = ((frac & roundeven_mask) != frac_lsbm1 + ? frac_lsbm1 : 0); + } + flags |= float_flag_inexact; + frac += inc; + } + + exp = (frac & DECOMPOSED_IMPLICIT_BIT ? 1 : 0); + frac >>= frac_shift; + + if (is_tiny && (flags & float_flag_inexact)) { + flags |= float_flag_underflow; + } + if (exp == 0 && frac == 0) { + p.cls = float_class_zero; + } + } + break; + + case float_class_zero: + do_zero: + exp = 0; + frac = 0; + break; + + case float_class_inf: + do_inf: + exp = exp_max; + frac = 0; + break; + + case float_class_qnan: + case float_class_snan: + exp = exp_max; + break; + + default: + g_assert_not_reached(); + } + + float_raise(flags, s); + p.exp = exp; + p.frac = frac; + return p; +} + +static decomposed_parts float16_unpack_canonical(float16 f, float_status *s) +{ + return decomposed_canonicalize(float16_unpack_raw(f), &float16_params, s); +} + +static float16 float16_round_pack_canonical(decomposed_parts p, float_status *s) +{ + switch (p.cls) { + case float_class_dnan: + return float16_default_nan(s); + case float_class_msnan: + return float16_maybe_silence_nan(float16_pack_raw(p), s); + default: + p = decomposed_round_canonical(p, s, &float16_params); + return float16_pack_raw(p); + } +} + +static decomposed_parts float32_unpack_canonical(float32 f, float_status *s) +{ + return decomposed_canonicalize(float32_unpack_raw(f), &float32_params, s); +} + +static float32 float32_round_pack_canonical(decomposed_parts p, float_status *s) +{ + switch (p.cls) { + case float_class_dnan: + return float32_default_nan(s); + case float_class_msnan: + return float32_maybe_silence_nan(float32_pack_raw(p), s); + default: + p = decomposed_round_canonical(p, s, &float32_params); + return float32_pack_raw(p); + } +} + +static decomposed_parts float64_unpack_canonical(float64 f, float_status *s) +{ + return decomposed_canonicalize(float64_unpack_raw(f), &float64_params, s); +} + +static float64 float64_round_pack_canonical(decomposed_parts p, float_status *s) +{ + switch (p.cls) { + case float_class_dnan: + return float64_default_nan(s); + case float_class_msnan: + return float64_maybe_silence_nan(float64_pack_raw(p), s); + default: + p = decomposed_round_canonical(p, s, &float64_params); + return float64_pack_raw(p); + } +} + +static decomposed_parts pick_nan_parts(decomposed_parts a, decomposed_parts b, + float_status *s) +{ + if (a.cls == float_class_snan || b.cls == float_class_snan) { + s->float_exception_flags |= float_flag_invalid; + } + + if (s->default_nan_mode) { + a.cls = float_class_dnan; + } else { + if (pickNaN(a.cls == float_class_qnan, + a.cls == float_class_snan, + b.cls == float_class_qnan, + b.cls == float_class_snan, + a.frac > b.frac + || (a.frac == b.frac && a.sign < b.sign))) { + a = b; + } + a.cls = float_class_msnan; + } + return a; +} + + +/* + * Returns the result of adding the absolute values of the + * floating-point values `a' and `b'. If `subtract' is set, the sum is + * negated before being returned. `subtract' is ignored if the result + * is a NaN. The addition is performed according to the IEC/IEEE + * Standard for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts add_decomposed(decomposed_parts a, decomposed_parts b, + bool subtract, float_status *s) +{ + bool a_sign = a.sign; + bool b_sign = b.sign ^ subtract; + + if (a_sign != b_sign) { + /* Subtraction */ + + if (a.cls == float_class_normal && b.cls == float_class_normal) { + int a_exp = a.exp; + int b_exp = b.exp; + uint64_t a_frac = a.frac; + uint64_t b_frac = b.frac; + + if (a_exp > b_exp || (a_exp == b_exp && a_frac >= b_frac)) { + shift64RightJamming(b_frac, a_exp - b_exp, &b_frac); + a_frac = a_frac - b_frac; + } else { + shift64RightJamming(a_frac, b_exp - a_exp, &a_frac); + a_frac = b_frac - a_frac; + a_exp = b_exp; + a_sign ^= 1; + } + + if (a_frac == 0) { + a.cls = float_class_zero; + a.sign = s->float_rounding_mode == float_round_down; + } else { + int shift = clz64(a_frac) - 1; + a.frac = a_frac << shift; + a.exp = a_exp - shift; + a.sign = a_sign; + } + return a; + } + if (a.cls >= float_class_qnan + || + b.cls >= float_class_qnan) + { + return pick_nan_parts(a, b, s); + } + if (a.cls == float_class_inf) { + if (b.cls == float_class_inf) { + float_raise(float_flag_invalid, s); + a.cls = float_class_dnan; + } + return a; + } + if (a.cls == float_class_zero && b.cls == float_class_zero) { + a.sign = s->float_rounding_mode == float_round_down; + return a; + } + if (a.cls == float_class_zero || b.cls == float_class_inf) { + b.sign = a_sign ^ 1; + return b; + } + if (b.cls == float_class_zero) { + return a; + } + } else { + /* Addition */ + if (a.cls == float_class_normal && b.cls == float_class_normal) { + int a_exp = a.exp; + int b_exp = b.exp; + uint64_t a_frac = a.frac; + uint64_t b_frac = b.frac; + + if (a_exp > b_exp) { + shift64RightJamming(b_frac, a_exp - b_exp, &b_frac); + } else if (a_exp < b_exp) { + shift64RightJamming(a_frac, b_exp - a_exp, &a_frac); + a_exp = b_exp; + } + a_frac += b_frac; + if (a_frac & DECOMPOSED_OVERFLOW_BIT) { + a_frac >>= 1; + a_exp += 1; + } + + a.exp = a_exp; + a.frac = a_frac; + return a; + } + if (a.cls >= float_class_qnan + || + b.cls >= float_class_qnan) { + return pick_nan_parts(a, b, s); + } + if (a.cls == float_class_inf || b.cls == float_class_zero) { + return a; + } + if (b.cls == float_class_inf || a.cls == float_class_zero) { + b.sign = b_sign; + return b; + } + } + g_assert_not_reached(); +} + +/* + * Returns the result of adding or subtracting the floating-point + * values `a' and `b'. The operation is performed according to the + * IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +float16 float16_add(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pb = float16_unpack_canonical(b, status); + decomposed_parts pr = add_decomposed(pa, pb, false, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_add(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa = float32_unpack_canonical(a, status); + decomposed_parts pb = float32_unpack_canonical(b, status); + decomposed_parts pr = add_decomposed(pa, pb, false, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_add(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa = float64_unpack_canonical(a, status); + decomposed_parts pb = float64_unpack_canonical(b, status); + decomposed_parts pr = add_decomposed(pa, pb, false, status); + + return float64_round_pack_canonical(pr, status); +} + +float16 float16_sub(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pb = float16_unpack_canonical(b, status); + decomposed_parts pr = add_decomposed(pa, pb, true, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_sub(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa = float32_unpack_canonical(a, status); + decomposed_parts pb = float32_unpack_canonical(b, status); + decomposed_parts pr = add_decomposed(pa, pb, true, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_sub(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa = float64_unpack_canonical(a, status); + decomposed_parts pb = float64_unpack_canonical(b, status); + decomposed_parts pr = add_decomposed(pa, pb, true, status); + + return float64_round_pack_canonical(pr, status); +} + /*---------------------------------------------------------------------------- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | 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_status *status) } -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the single-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float32 addFloat32Sigs(float32 a, float32 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint32_t aSig, bSig, zSig; - int expDiff; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - expDiff = aExp - bExp; - aSig <<= 6; - bSig <<= 6; - if ( 0 < expDiff ) { - if ( aExp == 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= 0x20000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= 0x20000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - zExp = bExp; - } - else { - if ( aExp == 0xFF ) { - if (aSig | bSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( aExp == 0 ) { - if (status->flush_to_zero) { - if (aSig | bSig) { - float_raise(float_flag_output_denormal, status); - } - return packFloat32(zSign, 0, 0); - } - return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); - } - zSig = 0x40000000 + aSig + bSig; - zExp = aExp; - goto roundAndPack; - } - aSig |= 0x20000000; - zSig = ( aSig + bSig )<<1; - --zExp; - if ( (int32_t) zSig < 0 ) { - zSig = aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the single- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float32 subFloat32Sigs(float32 a, float32 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint32_t aSig, bSig, zSig; - int expDiff; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - expDiff = aExp - bExp; - aSig <<= 7; - bSig <<= 7; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0xFF ) { - if (aSig | bSig) { - return propagateFloat32NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat32(status->float_rounding_mode == float_round_down, 0, 0); - bExpBigger: - if ( bExp == 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign ^ 1, 0xFF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= 0x40000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - bSig |= 0x40000000; - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= 0x40000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - aSig |= 0x40000000; - aBigger: - zSig = aSig - bSig; - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat32(zSign, zExp, zSig, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the single-precision floating-point values `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_add(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign; - a = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign == bSign ) { - return addFloat32Sigs(a, b, aSign, status); - } - else { - return subFloat32Sigs(a, b, aSign, status); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the single-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_sub(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign; - a = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign == bSign ) { - return subFloat32Sigs(a, b, aSign, status); - } - else { - return addFloat32Sigs(a, b, aSign, status); - } - -} /*---------------------------------------------------------------------------- | Returns the result of multiplying the single-precision floating-point values @@ -3875,219 +4138,6 @@ float64 float64_trunc_to_int(float64 a, float_status *status) return res; } -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the double-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float64 addFloat64Sigs(float64 a, float64 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig; - int expDiff; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - expDiff = aExp - bExp; - aSig <<= 9; - bSig <<= 9; - if ( 0 < expDiff ) { - if ( aExp == 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= LIT64( 0x2000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= LIT64( 0x2000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - zExp = bExp; - } - else { - if ( aExp == 0x7FF ) { - if (aSig | bSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( aExp == 0 ) { - if (status->flush_to_zero) { - if (aSig | bSig) { - float_raise(float_flag_output_denormal, status); - } - return packFloat64(zSign, 0, 0); - } - return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); - } - zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; - zExp = aExp; - goto roundAndPack; - } - aSig |= LIT64( 0x2000000000000000 ); - zSig = ( aSig + bSig )<<1; - --zExp; - if ( (int64_t) zSig < 0 ) { - zSig = aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat64(zSign, zExp, zSig, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float64 subFloat64Sigs(float64 a, float64 b, flag zSign, - float_status *status) -{ - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig; - int expDiff; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - expDiff = aExp - bExp; - aSig <<= 10; - bSig <<= 10; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FF ) { - if (aSig | bSig) { - return propagateFloat64NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat64(status->float_rounding_mode == float_round_down, 0, 0); - bExpBigger: - if ( bExp == 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign ^ 1, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= LIT64( 0x4000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - bSig |= LIT64( 0x4000000000000000 ); - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= LIT64( 0x4000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - aSig |= LIT64( 0x4000000000000000 ); - aBigger: - zSig = aSig - bSig; - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat64(zSign, zExp, zSig, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the double-precision floating-point values `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_add(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign; - a = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign == bSign ) { - return addFloat64Sigs(a, b, aSign, status); - } - else { - return subFloat64Sigs(a, b, aSign, status); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the double-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_sub(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign; - a = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign == bSign ) { - return subFloat64Sigs(a, b, aSign, status); - } - else { - return addFloat64Sigs(a, b, aSign, status); - } - -} /*---------------------------------------------------------------------------- | Returns the result of multiplying the double-precision floating-point values diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 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); From patchwork Tue Jan 9 12:22:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123909 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3960829qgn; Tue, 9 Jan 2018 04:28:30 -0800 (PST) X-Google-Smtp-Source: ACJfBouiB6miM1h52ufarXvzr+/r+kN1jDNo3oM8hAwZbqi01y0qBJs48KtTCpSrwARQtBfoEDVW X-Received: by 10.37.194.195 with SMTP id s186mr14047984ybf.381.1515500910509; Tue, 09 Jan 2018 04:28:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515500910; cv=none; d=google.com; s=arc-20160816; b=G+iywZATizJNgCmdxhJ4pQqS/WTD3uGc+c2/8U3WelWuHdCwgOAg8rMlsN8V7o6Jgu Dln2FFeeIPOKkAKU2YYm1E8RNUA7elHf0GMaClf3Mh6tLCXqZHN0AP2gu6v1ChNIUP7H 4N5Qy457Fl2iagdIh33/ISceyJsxg64K3G0XL4946mysVZt9FEuqD2GWUH5CAqfc/xlx UslZ13k/6JjFm0k+KmqkWuBSWyXEPVqbsdVs8HGU0C80WY2x/jZOIcyOzNw83fHZXsLD 7l740KjtmeJpb23VAEEVLuKJC7DbhgteLqmc3rAbb+EoLAfCRhMdkmhhttS7JdLOoHQv B7hA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=mJy0Ou8oHgPU1r6rmJO8Ul+ReONVCxYllLdFXdtsb1M=; b=B14e0Kw4kqddhW05fXRWZOI//2/leaqjoTAKAuNRsHXShYz6urmQpkkJ6dT/HyItAd Q3bytfe2jB9NJ2AUiWRdzEAB9KgzD+u1jEv1Jv2IeL+cYHMU3rzlAnICpUjDYj+DiznI BVF0c4IIJF63QS45eKQh175yg12x1ElpXeGJwI7FXtrq1h9MkwQ6r6E6UpDAKXrYu+Qs nprDYb98HWKpBIR38bvsEadRQZFakkYX7jsLRVv+LHWcI4jKIqmQ37hbr75HG+Fk8dYu 0+WVpcOlkHVJ4UhttMeKmSGvNhUWqkiMk6Idc9EeDpNeqrYxEuYyYopTdTsdV2dhD9T/ Fbrg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Rh361zc3; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id 185si2056694ybk.248.2018.01.09.04.28.30 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:28:30 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Rh361zc3; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49517 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt13-0002IP-VJ for patch@linaro.org; Tue, 09 Jan 2018 07:28:30 -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) 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-Received: by 10.223.137.1 with SMTP id s1mr9833991wrs.53.1515500586666; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" We can now add float16_mul and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 versions. Signed-off-by: Alex Bennée 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(-) -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index f89e47e3ef..6e9d4c172c 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -730,6 +730,85 @@ float64 float64_sub(float64 a, float64 b, float_status *status) return float64_round_pack_canonical(pr, status); } +/* + * Returns the result of multiplying the floating-point values `a' and + * `b'. The operation is performed according to the IEC/IEEE Standard + * for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts mul_decomposed(decomposed_parts a, decomposed_parts b, + float_status *s) +{ + bool sign = a.sign ^ b.sign; + + if (a.cls == float_class_normal && b.cls == float_class_normal) { + uint64_t hi, lo; + int exp = a.exp + b.exp; + + mul64To128(a.frac, b.frac, &hi, &lo); + shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, &hi, &lo); + if (lo & DECOMPOSED_OVERFLOW_BIT) { + shift64RightJamming(lo, 1, &lo); + exp += 1; + } + + /* Re-use a */ + a.exp = exp; + a.sign = sign; + a.frac = lo; + return a; + } + /* handle all the NaN cases */ + if (a.cls >= float_class_qnan || b.cls >= float_class_qnan) { + return pick_nan_parts(a, b, s); + } + /* Inf * Zero == NaN */ + if (((1 << a.cls) | (1 << b.cls)) == + ((1 << float_class_inf) | (1 << float_class_zero))) { + s->float_exception_flags |= float_flag_invalid; + a.cls = float_class_dnan; + a.sign = sign; + return a; + } + /* Multiply by 0 or Inf */ + if (a.cls == float_class_inf || a.cls == float_class_zero) { + a.sign = sign; + return a; + } + if (b.cls == float_class_inf || b.cls == float_class_zero) { + b.sign = sign; + return b; + } + g_assert_not_reached(); +} + +float16 float16_mul(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pb = float16_unpack_canonical(b, status); + decomposed_parts pr = mul_decomposed(pa, pb, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_mul(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa = float32_unpack_canonical(a, status); + decomposed_parts pb = float32_unpack_canonical(b, status); + decomposed_parts pr = mul_decomposed(pa, pb, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_mul(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa = float64_unpack_canonical(a, status); + decomposed_parts pb = float64_unpack_canonical(b, status); + decomposed_parts pr = mul_decomposed(pa, pb, status); + + return float64_round_pack_canonical(pr, status); +} + /*---------------------------------------------------------------------------- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to the @@ -2542,70 +2621,6 @@ float32 float32_round_to_int(float32 a, float_status *status) } -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the single-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_mul(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint32_t aSig, bSig; - uint64_t zSig64; - uint32_t zSig; - - a = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - bSign = extractFloat32Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0xFF ) { - if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { - return propagateFloat32NaN(a, b, status); - } - if ( ( bExp | bSig ) == 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp == 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - if ( ( aExp | aSig ) == 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x7F; - aSig = ( aSig | 0x00800000 )<<7; - bSig = ( bSig | 0x00800000 )<<8; - shift64RightJamming( ( (uint64_t) aSig ) * bSig, 32, &zSig64 ); - zSig = zSig64; - if ( 0 <= (int32_t) ( zSig<<1 ) ) { - zSig <<= 1; - --zExp; - } - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} /*---------------------------------------------------------------------------- | Returns the result of dividing the single-precision floating-point value `a' @@ -4138,70 +4153,6 @@ float64 float64_trunc_to_int(float64 a, float_status *status) return res; } - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the double-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_mul(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig0, zSig1; - - a = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - bSign = extractFloat64Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FF ) { - if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { - return propagateFloat64NaN(a, b, status); - } - if ( ( bExp | bSig ) == 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp == 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - if ( ( aExp | aSig ) == 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x3FF; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - zSig0 |= ( zSig1 != 0 ); - if ( 0 <= (int64_t) ( zSig0<<1 ) ) { - zSig0 <<= 1; - --zExp; - } - return roundAndPackFloat64(zSign, zExp, zSig0, status); - -} - /*---------------------------------------------------------------------------- | Returns the result of dividing the double-precision floating-point value `a' | by the corresponding value `b'. The operation is performed according to diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 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); float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); +float16 float16_mul(float16, float16, float_status *status); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); From patchwork Tue Jan 9 12:22:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123913 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3964414qgn; Tue, 9 Jan 2018 04:32:14 -0800 (PST) X-Google-Smtp-Source: ACJfBot8RTmWbw/DP2RWMWRRgV/iDEd4b0rW2e57Za8rWeordkHMZB53h9U5c9vXm2p337at0MDB X-Received: by 10.129.193.76 with SMTP id e12mr13389819ywl.323.1515501134881; Tue, 09 Jan 2018 04:32:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501134; cv=none; d=google.com; s=arc-20160816; b=c/nhHlEJ0jl1Y1EKw/Jt8fCUerodjXiX/B4yHZr3DQHSqKBNWFnaJJqiUXbxWYpRVJ Rr/F1gxCE2Vvm1g0rh0v8oIlQSfoI2g4dFDcZYxjKg06BTFcQU5bkMWUCDDbRGsmEclf l+0f3bTpZ4j3BcHTC16WIo10SVJf5FTKRZIHvoXq5ZVCbdzA6sHFRHjNTkpVL0f86e0T vMQX0YlKkjtF4DlZ/1ghCJi3dFj7MchD55O2HBNhFtvcr+G2D0Rko30FgoGJmRKSRB+F 1dW5NzlpS8oTXO3cDmXQCFSEL/PAgvG53ijwuFDoXJR0ZyxutluHtPCtK4Q/rfmi4Po0 wOGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=gY4Pw0/J5CvztqQ5CA9vHCcbOrXRpr6mRK8t/cdEnK8=; b=n/rAXe++6fTBVCOAo3Omc2c+XORA1VCP7rugxqKEeJWLGsXdX8PXRXSHiTqw0eGLOE Vqq7w9o986xIP7iSyOVM+qNzVqshGxlqyV3yKxiySO6YcttCiN8r5/hTMgUdQTGUfZKk CidfGeiGGzyr4fChxkAXpYBx2VqFvQQlwPenqsveso6JlUoMI2Lincq5VADIsZo1W6rT edBmH7AF40OwOvZ8hpbg54ciD63azhWKsUur4QgfbJY4FdL8PjIqYKpOn2ode+4KdhQg CPx8PsGef4nmLIGVl3+qztjTWUqyIYgc/H/+nNMRxkveowUHO2zG2jV89DXDrTPoIIT1 fk6Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Zvyc9Ztt; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id j15si3042369ywm.269.2018.01.09.04.32.14 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:32:14 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Zvyc9Ztt; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49541 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt4g-0005K9-Ai for patch@linaro.org; Tue, 09 Jan 2018 07:32:14 -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) 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-Received: by 10.28.87.146 with SMTP id l140mr11109805wmb.86.1515500907035; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" We can now add float16_div and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 versions. Signed-off-by: Alex Bennée 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(-) -- 2.15.1 diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h index 9cc6158cb4..980be2c051 100644 --- a/fpu/softfloat-macros.h +++ b/fpu/softfloat-macros.h @@ -625,6 +625,50 @@ static uint64_t estimateDiv128To64( uint64_t a0, uint64_t a1, uint64_t b ) } +/* Nicked from gmp longlong.h __udiv_qrnnd */ +static uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d) +{ + uint64_t d0, d1, q0, q1, r1, r0, m; + + d0 = (uint32_t)d; + d1 = d >> 32; + + r1 = n1 % d1; + q1 = n1 / d1; + m = q1 * d0; + r1 = (r1 << 32) | (n0 >> 32); + if (r1 < m) { + q1 -= 1; + r1 += d; + if (r1 >= d) { + if (r1 < m) { + q1 -= 1; + r1 += d; + } + } + } + r1 -= m; + + r0 = r1 % d1; + q0 = r1 / d1; + m = q0 * d0; + r0 = (r0 << 32) | (uint32_t)n0; + if (r0 < m) { + q0 -= 1; + r0 += d; + if (r0 >= d) { + if (r0 < m) { + q0 -= 1; + r0 += d; + } + } + } + r0 -= m; + + /* Return remainder in LSB */ + return (q1 << 32) | q0 | (r0 != 0); +} + /*---------------------------------------------------------------------------- | Returns an approximation to the square root of the 32-bit significand given | by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 6e9d4c172c..2b703c12ed 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -809,6 +809,95 @@ float64 float64_mul(float64 a, float64 b, float_status *status) return float64_round_pack_canonical(pr, status); } +/* + * Returns the result of dividing the floating-point value `a' by the + * corresponding value `b'. The operation is performed according to + * the IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts div_decomposed(decomposed_parts a, decomposed_parts b, + float_status *s) +{ + bool sign = a.sign ^ b.sign; + + if (a.cls == float_class_normal && b.cls == float_class_normal) { + uint64_t temp_lo, temp_hi; + int exp = a.exp - b.exp; + if (a.frac < b.frac) { + exp -= 1; + shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT + 1, + &temp_hi, &temp_lo); + } else { + shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT, + &temp_hi, &temp_lo); + } + /* LSB of quot is set if inexact which roundandpack will use + * to set flags. Yet again we re-use a for the result */ + a.frac = div128To64(temp_lo, temp_hi, b.frac); + a.sign = sign; + a.exp = exp; + return a; + } + /* handle all the NaN cases */ + if (a.cls >= float_class_qnan || b.cls >= float_class_qnan) { + return pick_nan_parts(a, b, s); + } + /* 0/0 or Inf/Inf */ + if (a.cls == b.cls + && + (a.cls == float_class_inf || a.cls == float_class_zero)) { + s->float_exception_flags |= float_flag_invalid; + a.cls = float_class_dnan; + return a; + } + /* Div 0 => Inf */ + if (b.cls == float_class_zero) { + s->float_exception_flags |= float_flag_divbyzero; + a.cls = float_class_inf; + a.sign = sign; + return a; + } + /* Inf / x or 0 / x */ + if (a.cls == float_class_inf || a.cls == float_class_zero) { + a.sign = sign; + return a; + } + /* Div by Inf */ + if (b.cls == float_class_inf) { + a.cls = float_class_zero; + a.sign = sign; + return a; + } + g_assert_not_reached(); +} + +float16 float16_div(float16 a, float16 b, float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pb = float16_unpack_canonical(b, status); + decomposed_parts pr = div_decomposed(pa, pb, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_div(float32 a, float32 b, float_status *status) +{ + decomposed_parts pa = float32_unpack_canonical(a, status); + decomposed_parts pb = float32_unpack_canonical(b, status); + decomposed_parts pr = div_decomposed(pa, pb, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_div(float64 a, float64 b, float_status *status) +{ + decomposed_parts pa = float64_unpack_canonical(a, status); + decomposed_parts pb = float64_unpack_canonical(b, status); + decomposed_parts pr = div_decomposed(pa, pb, status); + + return float64_round_pack_canonical(pr, status); +} + /*---------------------------------------------------------------------------- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to the @@ -2622,75 +2711,6 @@ float32 float32_round_to_int(float32 a, float_status *status) -/*---------------------------------------------------------------------------- -| Returns the result of dividing the single-precision floating-point value `a' -| by the corresponding value `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_div(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint32_t aSig, bSig, zSig; - a = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - bSign = extractFloat32Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, b, status); - } - if ( bExp == 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp == 0xFF ) { - if (bSig) { - return propagateFloat32NaN(a, b, status); - } - return packFloat32( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - float_raise(float_flag_divbyzero, status); - return packFloat32( zSign, 0xFF, 0 ); - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x7D; - aSig = ( aSig | 0x00800000 )<<7; - bSig = ( bSig | 0x00800000 )<<8; - if ( bSig <= ( aSig + aSig ) ) { - aSig >>= 1; - ++zExp; - } - zSig = ( ( (uint64_t) aSig )<<32 ) / bSig; - if ( ( zSig & 0x3F ) == 0 ) { - zSig |= ( (uint64_t) bSig * zSig != ( (uint64_t) aSig )<<32 ); - } - return roundAndPackFloat32(zSign, zExp, zSig, status); - -} /*---------------------------------------------------------------------------- | Returns the remainder of the single-precision floating-point value `a' @@ -4153,83 +4173,6 @@ float64 float64_trunc_to_int(float64 a, float_status *status) return res; } -/*---------------------------------------------------------------------------- -| Returns the result of dividing the double-precision floating-point value `a' -| by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_div(float64 a, float64 b, float_status *status) -{ - flag aSign, bSign, zSign; - int aExp, bExp, zExp; - uint64_t aSig, bSig, zSig; - uint64_t rem0, rem1; - uint64_t term0, term1; - a = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - bSign = extractFloat64Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FF ) { - if (aSig) { - return propagateFloat64NaN(a, b, status); - } - if ( bExp == 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp == 0x7FF ) { - if (bSig) { - return propagateFloat64NaN(a, b, status); - } - return packFloat64( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - float_raise(float_flag_divbyzero, status); - return packFloat64( zSign, 0x7FF, 0 ); - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x3FD; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - if ( bSig <= ( aSig + aSig ) ) { - aSig >>= 1; - ++zExp; - } - zSig = estimateDiv128To64( aSig, 0, bSig ); - if ( ( zSig & 0x1FF ) <= 2 ) { - mul64To128( bSig, zSig, &term0, &term1 ); - sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (int64_t) rem0 < 0 ) { - --zSig; - add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); - } - zSig |= ( rem1 != 0 ); - } - return roundAndPackFloat64(zSign, zExp, zSig, status); - -} /*---------------------------------------------------------------------------- | Returns the remainder of the double-precision floating-point value `a' diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 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); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); From patchwork Tue Jan 9 12:22:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123919 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3970047qgn; Tue, 9 Jan 2018 04:37:49 -0800 (PST) X-Google-Smtp-Source: ACJfBouZd0muQ0geSI9um88TaaBkKx61PpDaAG6os4Pb47wrorS08RerzJw3fi7YRLiwZJaxMuEZ X-Received: by 10.129.104.214 with SMTP id d205mr13194893ywc.276.1515501469052; Tue, 09 Jan 2018 04:37:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501469; cv=none; d=google.com; s=arc-20160816; b=uch+QDOQtLKlFxFXHE4c16UmuwqtrRZhCyfT5CBSszLrnpzXEwV0N2imUWRpUI0Vb5 rl5yaAPHHOLZyv/u2vwIwp2NtBnWqESM7mnKvOB/9lE7v8Iu0TM0IRa9LvsDY+OekrWH kYdtnO7gPuM+OG2Yfhk579Ty5hmSmARusyva6h3So0jp0QjbLOTDIwtYcjuhGhRqPkEy zR4I2sSD/YyM96PFbRrnsyYeVqmkJeaUwyUnnl9lVsZJzrP1fjLWdehBWsiMAHpIHD39 nXvw9dlFlKdhAbhEITdEIFACcdBzYY8om3i+Vj45iiUH0bHj0aAmX0+/V5OlXx7MhJG6 gDNg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=zmNIouwe1+7YZQyIGNBXgw1pykG59RbUL33SXn0AUAw=; b=GSh0H1g6P4FSapu2gxOkza3AMA9V5J3GdqZl1dJ6SOxZK659IC8X+/tGqXgWiCgn6+ m110yx5tmzYFskpu0QutMe4Cn7zeN6vkLFR7r5rD3gFZQrhd3Bv6KyKbgtCbI/ksMY79 QYL0qRwbL286HjQ5i4ZMH89ulfzGU5bpRBSosMAjFgqkqIPSuOXu5aSMzVclXDcGv6Lq +4IobcDT4MES7oYdFQZ2gBMGESH/KILyra29DqYLqedIIL9szU5Bs65TzZc2KdrMZ5Y8 D3qqSWM6lG7i6RrVtXTGctY8YzQuuY0CQy69DTNxFpHb28uhlh1BqVS+5SrP5H0pvxOZ AIyA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=a+Zv/0pt; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id n82si3001375ybf.832.2018.01.09.04.37.48 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:37:49 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=a+Zv/0pt; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49574 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYtA4-0001Rf-Af for patch@linaro.org; Tue, 09 Jan 2018 07:37:48 -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) 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-Received: by 10.223.139.24 with SMTP id n24mr5012659wra.23.1515500589031; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" We can now add float16_muladd and use the common decompose and canonicalize functions to have a single implementation for float16/32/64 muladd functions. Signed-off-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat-specialize.h | 104 ------- fpu/softfloat.c | 756 +++++++++++++++++---------------------------- include/fpu/softfloat.h | 1 + 3 files changed, 286 insertions(+), 575 deletions(-) -- 2.15.1 Reviewed-by: Peter Maydell diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 3d507d8c77..98fb0e7001 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -729,58 +729,6 @@ static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status) } } -/*---------------------------------------------------------------------------- -| Takes three single-precision floating-point values `a', `b' and `c', one of -| which is a NaN, and returns the appropriate NaN result. If any of `a', -| `b' or `c' is a signaling NaN, the invalid exception is raised. -| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case -| obviously c is a NaN, and whether to propagate c or some other NaN is -| implementation defined). -*----------------------------------------------------------------------------*/ - -static float32 propagateFloat32MulAddNaN(float32 a, float32 b, - float32 c, flag infzero, - float_status *status) -{ - flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN; - int which; - - aIsQuietNaN = float32_is_quiet_nan(a, status); - aIsSignalingNaN = float32_is_signaling_nan(a, status); - bIsQuietNaN = float32_is_quiet_nan(b, status); - bIsSignalingNaN = float32_is_signaling_nan(b, status); - cIsQuietNaN = float32_is_quiet_nan(c, status); - cIsSignalingNaN = float32_is_signaling_nan(c, status); - - if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { - float_raise(float_flag_invalid, status); - } - - which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN, - bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN, infzero, status); - - if (status->default_nan_mode) { - /* Note that this check is after pickNaNMulAdd so that function - * has an opportunity to set the Invalid flag. - */ - return float32_default_nan(status); - } - - switch (which) { - case 0: - return float32_maybe_silence_nan(a, status); - case 1: - return float32_maybe_silence_nan(b, status); - case 2: - return float32_maybe_silence_nan(c, status); - case 3: - default: - return float32_default_nan(status); - } -} - #ifdef NO_SIGNALING_NANS int float64_is_quiet_nan(float64 a_, float_status *status) { @@ -936,58 +884,6 @@ static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status) } } -/*---------------------------------------------------------------------------- -| Takes three double-precision floating-point values `a', `b' and `c', one of -| which is a NaN, and returns the appropriate NaN result. If any of `a', -| `b' or `c' is a signaling NaN, the invalid exception is raised. -| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case -| obviously c is a NaN, and whether to propagate c or some other NaN is -| implementation defined). -*----------------------------------------------------------------------------*/ - -static float64 propagateFloat64MulAddNaN(float64 a, float64 b, - float64 c, flag infzero, - float_status *status) -{ - flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN; - int which; - - aIsQuietNaN = float64_is_quiet_nan(a, status); - aIsSignalingNaN = float64_is_signaling_nan(a, status); - bIsQuietNaN = float64_is_quiet_nan(b, status); - bIsSignalingNaN = float64_is_signaling_nan(b, status); - cIsQuietNaN = float64_is_quiet_nan(c, status); - cIsSignalingNaN = float64_is_signaling_nan(c, status); - - if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { - float_raise(float_flag_invalid, status); - } - - which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN, - bIsQuietNaN, bIsSignalingNaN, - cIsQuietNaN, cIsSignalingNaN, infzero, status); - - if (status->default_nan_mode) { - /* Note that this check is after pickNaNMulAdd so that function - * has an opportunity to set the Invalid flag. - */ - return float64_default_nan(status); - } - - switch (which) { - case 0: - return float64_maybe_silence_nan(a, status); - case 1: - return float64_maybe_silence_nan(b, status); - case 2: - return float64_maybe_silence_nan(c, status); - case 3: - default: - return float64_default_nan(status); - } -} - #ifdef NO_SIGNALING_NANS int floatx80_is_quiet_nan(floatx80 a_, float_status *status) { diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 2b703c12ed..84386f354b 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -561,6 +561,50 @@ static decomposed_parts pick_nan_parts(decomposed_parts a, decomposed_parts b, return a; } +static decomposed_parts pick_nan_muladd_parts(decomposed_parts a, + decomposed_parts b, + decomposed_parts c, + bool inf_zero, + float_status *s) +{ + if (a.cls == float_class_snan + || + b.cls == float_class_snan + || + c.cls == float_class_snan) { + s->float_exception_flags |= float_flag_invalid; + } + + if (s->default_nan_mode) { + a.cls = float_class_dnan; + } else { + switch (pickNaNMulAdd(a.cls == float_class_qnan, + a.cls == float_class_snan, + b.cls == float_class_qnan, + b.cls == float_class_snan, + c.cls == float_class_qnan, + c.cls == float_class_snan, + inf_zero, s)) { + case 0: + break; + case 1: + a = b; + break; + case 2: + a = c; + break; + case 3: + a.cls = float_class_dnan; + return a; + default: + g_assert_not_reached(); + } + + a.cls = float_class_msnan; + } + return a; +} + /* * Returns the result of adding the absolute values of the @@ -809,6 +853,247 @@ float64 float64_mul(float64 a, float64 b, float_status *status) return float64_round_pack_canonical(pr, status); } +/* + * Returns the result of multiplying the floating-point values `a' and + * `b' then adding 'c', with no intermediate rounding step after the + * multiplication. The operation is performed according to the + * IEC/IEEE Standard for Binary Floating-Point Arithmetic 754-2008. + * The flags argument allows the caller to select negation of the + * addend, the intermediate product, or the final result. (The + * difference between this and having the caller do a separate + * negation is that negating externally will flip the sign bit on + * NaNs.) + */ + +static decomposed_parts muladd_decomposed(decomposed_parts a, + decomposed_parts b, + decomposed_parts c, int flags, + float_status *s) +{ + bool inf_zero = ((1 << a.cls) | (1 << b.cls)) == + ((1 << float_class_inf) | (1 << float_class_zero)); + bool p_sign; + bool sign_flip = flags & float_muladd_negate_result; + float_class p_class; + uint64_t hi, lo; + int p_exp; + + /* It is implementation-defined whether the cases of (0,inf,qnan) + * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN + * they return if they do), so we have to hand this information + * off to the target-specific pick-a-NaN routine. + */ + if (a.cls >= float_class_qnan || + b.cls >= float_class_qnan || + c.cls >= float_class_qnan) { + return pick_nan_muladd_parts(a, b, c, inf_zero, s); + } + + if (inf_zero) { + s->float_exception_flags |= float_flag_invalid; + a.cls = float_class_dnan; + return a; + } + + if (flags & float_muladd_negate_c) { + c.sign ^= 1; + } + + p_sign = a.sign ^ b.sign; + + if (flags & float_muladd_negate_product) { + p_sign ^= 1; + } + + if (a.cls == float_class_inf || b.cls == float_class_inf) { + p_class = float_class_inf; + } else if (a.cls == float_class_zero || b.cls == float_class_zero) { + p_class = float_class_zero; + } else { + p_class = float_class_normal; + } + + if (c.cls == float_class_inf) { + if (p_class == float_class_inf && p_sign != c.sign) { + s->float_exception_flags |= float_flag_invalid; + a.cls = float_class_dnan; + } else { + a.cls = float_class_inf; + a.sign = c.sign ^ sign_flip; + } + return a; + } + + if (p_class == float_class_inf) { + a.cls = float_class_inf; + a.sign = p_sign ^ sign_flip; + return a; + } + + if (p_class == float_class_zero) { + if (c.cls == float_class_zero) { + if (p_sign != c.sign) { + p_sign = s->float_rounding_mode == float_round_down; + } + c.sign = p_sign; + } else if (flags & float_muladd_halve_result) { + c.exp -= 1; + } + c.sign ^= sign_flip; + return c; + } + + /* a & b should be normals now... */ + assert(a.cls == float_class_normal && + b.cls == float_class_normal); + + p_exp = a.exp + b.exp; + + /* Multiply of 2 62-bit numbers produces a (2*62) == 124-bit + * result. + */ + mul64To128(a.frac, b.frac, &hi, &lo); + /* binary point now at bit 124 */ + + /* check for overflow */ + if (hi & (1ULL << (DECOMPOSED_BINARY_POINT * 2 + 1 - 64))) { + shift128RightJamming(hi, lo, 1, &hi, &lo); + p_exp += 1; + } + + /* + add/sub */ + if (c.cls == float_class_zero) { + /* move binary point back to 62 */ + shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, &hi, &lo); + } else { + int exp_diff = p_exp - c.exp; + if (p_sign == c.sign) { + /* Addition */ + if (exp_diff <= 0) { + shift128RightJamming(hi, lo, + DECOMPOSED_BINARY_POINT - exp_diff, + &hi, &lo); + lo += c.frac; + p_exp = c.exp; + } else { + uint64_t c_hi, c_lo; + /* shift c to the same binary point as the product (124) */ + c_hi = c.frac >> 2; + c_lo = 0; + shift128RightJamming(c_hi, c_lo, + exp_diff, + &c_hi, &c_lo); + add128(hi, lo, c_hi, c_lo, &hi, &lo); + /* move binary point back to 62 */ + shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, &hi, &lo); + } + + if (lo & DECOMPOSED_OVERFLOW_BIT) { + shift64RightJamming(lo, 1, &lo); + p_exp += 1; + } + + } else { + /* Subtraction */ + uint64_t c_hi, c_lo; + /* make C binary point match product at bit 124 */ + c_hi = c.frac >> 2; + c_lo = 0; + + if (exp_diff <= 0) { + shift128RightJamming(hi, lo, -exp_diff, &hi, &lo); + if (exp_diff == 0 + && + (hi > c_hi || (hi == c_hi && lo >= c_lo))) { + sub128(hi, lo, c_hi, c_lo, &hi, &lo); + } else { + sub128(c_hi, c_lo, hi, lo, &hi, &lo); + p_sign ^= 1; + p_exp = c.exp; + } + } else { + shift128RightJamming(c_hi, c_lo, + exp_diff, + &c_hi, &c_lo); + sub128(hi, lo, c_hi, c_lo, &hi, &lo); + } + + if (hi == 0 && lo == 0) { + a.cls = float_class_zero; + a.sign = s->float_rounding_mode == float_round_down; + a.sign ^= sign_flip; + return a; + } else { + int shift; + if (hi != 0) { + shift = clz64(hi); + } else { + shift = clz64(lo) + 64; + } + /* Normalizing to a binary point of 124 is the + correct adjust for the exponent. However since we're + shifting, we might as well put the binary point back + at 62 where we really want it. Therefore shift as + if we're leaving 1 bit at the top of the word, but + adjust the exponent as if we're leaving 3 bits. */ + shift -= 1; + if (shift >= 64) { + lo = lo << (shift - 64); + } else { + hi = (hi << shift) | (lo >> (64 - shift)); + lo = hi | ((lo << shift) != 0); + } + p_exp -= shift - 2; + } + } + } + + if (flags & float_muladd_halve_result) { + p_exp -= 1; + } + + /* finally prepare our result */ + a.cls = float_class_normal; + a.sign = p_sign ^ sign_flip; + a.exp = p_exp; + a.frac = lo; + + return a; +} + +float16 float16_muladd(float16 a, float16 b, float16 c, int flags, + float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pb = float16_unpack_canonical(b, status); + decomposed_parts pc = float16_unpack_canonical(c, status); + decomposed_parts pr = muladd_decomposed(pa, pb, pc, flags, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_muladd(float32 a, float32 b, float32 c, int flags, + float_status *status) +{ + decomposed_parts pa = float32_unpack_canonical(a, status); + decomposed_parts pb = float32_unpack_canonical(b, status); + decomposed_parts pc = float32_unpack_canonical(c, status); + decomposed_parts pr = muladd_decomposed(pa, pb, pc, flags, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_muladd(float64 a, float64 b, float64 c, int flags, + float_status *status) +{ + decomposed_parts pa = float64_unpack_canonical(a, status); + decomposed_parts pb = float64_unpack_canonical(b, status); + decomposed_parts pc = float64_unpack_canonical(c, status); + decomposed_parts pr = muladd_decomposed(pa, pb, pc, flags, status); + + return float64_round_pack_canonical(pr, status); +} + /* * Returns the result of dividing the floating-point value `a' by the * corresponding value `b'. The operation is performed according to @@ -2814,231 +3099,6 @@ float32 float32_rem(float32 a, float32 b, float_status *status) return normalizeRoundAndPackFloat32(aSign ^ zSign, bExp, aSig, status); } -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the single-precision floating-point values -| `a' and `b' then adding 'c', with no intermediate rounding step after the -| multiplication. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic 754-2008. -| The flags argument allows the caller to select negation of the -| addend, the intermediate product, or the final result. (The difference -| between this and having the caller do a separate negation is that negating -| externally will flip the sign bit on NaNs.) -*----------------------------------------------------------------------------*/ - -float32 float32_muladd(float32 a, float32 b, float32 c, int flags, - float_status *status) -{ - flag aSign, bSign, cSign, zSign; - int aExp, bExp, cExp, pExp, zExp, expDiff; - uint32_t aSig, bSig, cSig; - flag pInf, pZero, pSign; - uint64_t pSig64, cSig64, zSig64; - uint32_t pSig; - int shiftcount; - flag signflip, infzero; - - a = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - c = float32_squash_input_denormal(c, status); - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - bSig = extractFloat32Frac(b); - bExp = extractFloat32Exp(b); - bSign = extractFloat32Sign(b); - cSig = extractFloat32Frac(c); - cExp = extractFloat32Exp(c); - cSign = extractFloat32Sign(c); - - infzero = ((aExp == 0 && aSig == 0 && bExp == 0xff && bSig == 0) || - (aExp == 0xff && aSig == 0 && bExp == 0 && bSig == 0)); - - /* It is implementation-defined whether the cases of (0,inf,qnan) - * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN - * they return if they do), so we have to hand this information - * off to the target-specific pick-a-NaN routine. - */ - if (((aExp == 0xff) && aSig) || - ((bExp == 0xff) && bSig) || - ((cExp == 0xff) && cSig)) { - return propagateFloat32MulAddNaN(a, b, c, infzero, status); - } - - if (infzero) { - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - - if (flags & float_muladd_negate_c) { - cSign ^= 1; - } - - signflip = (flags & float_muladd_negate_result) ? 1 : 0; - - /* Work out the sign and type of the product */ - pSign = aSign ^ bSign; - if (flags & float_muladd_negate_product) { - pSign ^= 1; - } - pInf = (aExp == 0xff) || (bExp == 0xff); - pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0); - - if (cExp == 0xff) { - if (pInf && (pSign ^ cSign)) { - /* addition of opposite-signed infinities => InvalidOperation */ - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - /* Otherwise generate an infinity of the same sign */ - return packFloat32(cSign ^ signflip, 0xff, 0); - } - - if (pInf) { - return packFloat32(pSign ^ signflip, 0xff, 0); - } - - if (pZero) { - if (cExp == 0) { - if (cSig == 0) { - /* Adding two exact zeroes */ - if (pSign == cSign) { - zSign = pSign; - } else if (status->float_rounding_mode == float_round_down) { - zSign = 1; - } else { - zSign = 0; - } - return packFloat32(zSign ^ signflip, 0, 0); - } - /* Exact zero plus a denorm */ - if (status->flush_to_zero) { - float_raise(float_flag_output_denormal, status); - return packFloat32(cSign ^ signflip, 0, 0); - } - } - /* Zero plus something non-zero : just return the something */ - if (flags & float_muladd_halve_result) { - if (cExp == 0) { - normalizeFloat32Subnormal(cSig, &cExp, &cSig); - } - /* Subtract one to halve, and one again because roundAndPackFloat32 - * wants one less than the true exponent. - */ - cExp -= 2; - cSig = (cSig | 0x00800000) << 7; - return roundAndPackFloat32(cSign ^ signflip, cExp, cSig, status); - } - return packFloat32(cSign ^ signflip, cExp, cSig); - } - - if (aExp == 0) { - normalizeFloat32Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - normalizeFloat32Subnormal(bSig, &bExp, &bSig); - } - - /* Calculate the actual result a * b + c */ - - /* Multiply first; this is easy. */ - /* NB: we subtract 0x7e where float32_mul() subtracts 0x7f - * because we want the true exponent, not the "one-less-than" - * flavour that roundAndPackFloat32() takes. - */ - pExp = aExp + bExp - 0x7e; - aSig = (aSig | 0x00800000) << 7; - bSig = (bSig | 0x00800000) << 8; - pSig64 = (uint64_t)aSig * bSig; - if ((int64_t)(pSig64 << 1) >= 0) { - pSig64 <<= 1; - pExp--; - } - - zSign = pSign ^ signflip; - - /* Now pSig64 is the significand of the multiply, with the explicit bit in - * position 62. - */ - if (cExp == 0) { - if (!cSig) { - /* Throw out the special case of c being an exact zero now */ - shift64RightJamming(pSig64, 32, &pSig64); - pSig = pSig64; - if (flags & float_muladd_halve_result) { - pExp--; - } - return roundAndPackFloat32(zSign, pExp - 1, - pSig, status); - } - normalizeFloat32Subnormal(cSig, &cExp, &cSig); - } - - cSig64 = (uint64_t)cSig << (62 - 23); - cSig64 |= LIT64(0x4000000000000000); - expDiff = pExp - cExp; - - if (pSign == cSign) { - /* Addition */ - if (expDiff > 0) { - /* scale c to match p */ - shift64RightJamming(cSig64, expDiff, &cSig64); - zExp = pExp; - } else if (expDiff < 0) { - /* scale p to match c */ - shift64RightJamming(pSig64, -expDiff, &pSig64); - zExp = cExp; - } else { - /* no scaling needed */ - zExp = cExp; - } - /* Add significands and make sure explicit bit ends up in posn 62 */ - zSig64 = pSig64 + cSig64; - if ((int64_t)zSig64 < 0) { - shift64RightJamming(zSig64, 1, &zSig64); - } else { - zExp--; - } - } else { - /* Subtraction */ - if (expDiff > 0) { - shift64RightJamming(cSig64, expDiff, &cSig64); - zSig64 = pSig64 - cSig64; - zExp = pExp; - } else if (expDiff < 0) { - shift64RightJamming(pSig64, -expDiff, &pSig64); - zSig64 = cSig64 - pSig64; - zExp = cExp; - zSign ^= 1; - } else { - zExp = pExp; - if (cSig64 < pSig64) { - zSig64 = pSig64 - cSig64; - } else if (pSig64 < cSig64) { - zSig64 = cSig64 - pSig64; - zSign ^= 1; - } else { - /* Exact zero */ - zSign = signflip; - if (status->float_rounding_mode == float_round_down) { - zSign ^= 1; - } - return packFloat32(zSign, 0, 0); - } - } - --zExp; - /* Normalize to put the explicit bit back into bit 62. */ - shiftcount = countLeadingZeros64(zSig64) - 1; - zSig64 <<= shiftcount; - zExp -= shiftcount; - } - if (flags & float_muladd_halve_result) { - zExp--; - } - - shift64RightJamming(zSig64, 32, &zSig64); - return roundAndPackFloat32(zSign, zExp, zSig64, status); -} - /*---------------------------------------------------------------------------- | Returns the square root of the single-precision floating-point value `a'. @@ -4262,252 +4322,6 @@ float64 float64_rem(float64 a, float64 b, float_status *status) } -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the double-precision floating-point values -| `a' and `b' then adding 'c', with no intermediate rounding step after the -| multiplication. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic 754-2008. -| The flags argument allows the caller to select negation of the -| addend, the intermediate product, or the final result. (The difference -| between this and having the caller do a separate negation is that negating -| externally will flip the sign bit on NaNs.) -*----------------------------------------------------------------------------*/ - -float64 float64_muladd(float64 a, float64 b, float64 c, int flags, - float_status *status) -{ - flag aSign, bSign, cSign, zSign; - int aExp, bExp, cExp, pExp, zExp, expDiff; - uint64_t aSig, bSig, cSig; - flag pInf, pZero, pSign; - uint64_t pSig0, pSig1, cSig0, cSig1, zSig0, zSig1; - int shiftcount; - flag signflip, infzero; - - a = float64_squash_input_denormal(a, status); - b = float64_squash_input_denormal(b, status); - c = float64_squash_input_denormal(c, status); - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - bSig = extractFloat64Frac(b); - bExp = extractFloat64Exp(b); - bSign = extractFloat64Sign(b); - cSig = extractFloat64Frac(c); - cExp = extractFloat64Exp(c); - cSign = extractFloat64Sign(c); - - infzero = ((aExp == 0 && aSig == 0 && bExp == 0x7ff && bSig == 0) || - (aExp == 0x7ff && aSig == 0 && bExp == 0 && bSig == 0)); - - /* It is implementation-defined whether the cases of (0,inf,qnan) - * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN - * they return if they do), so we have to hand this information - * off to the target-specific pick-a-NaN routine. - */ - if (((aExp == 0x7ff) && aSig) || - ((bExp == 0x7ff) && bSig) || - ((cExp == 0x7ff) && cSig)) { - return propagateFloat64MulAddNaN(a, b, c, infzero, status); - } - - if (infzero) { - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - - if (flags & float_muladd_negate_c) { - cSign ^= 1; - } - - signflip = (flags & float_muladd_negate_result) ? 1 : 0; - - /* Work out the sign and type of the product */ - pSign = aSign ^ bSign; - if (flags & float_muladd_negate_product) { - pSign ^= 1; - } - pInf = (aExp == 0x7ff) || (bExp == 0x7ff); - pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0); - - if (cExp == 0x7ff) { - if (pInf && (pSign ^ cSign)) { - /* addition of opposite-signed infinities => InvalidOperation */ - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - /* Otherwise generate an infinity of the same sign */ - return packFloat64(cSign ^ signflip, 0x7ff, 0); - } - - if (pInf) { - return packFloat64(pSign ^ signflip, 0x7ff, 0); - } - - if (pZero) { - if (cExp == 0) { - if (cSig == 0) { - /* Adding two exact zeroes */ - if (pSign == cSign) { - zSign = pSign; - } else if (status->float_rounding_mode == float_round_down) { - zSign = 1; - } else { - zSign = 0; - } - return packFloat64(zSign ^ signflip, 0, 0); - } - /* Exact zero plus a denorm */ - if (status->flush_to_zero) { - float_raise(float_flag_output_denormal, status); - return packFloat64(cSign ^ signflip, 0, 0); - } - } - /* Zero plus something non-zero : just return the something */ - if (flags & float_muladd_halve_result) { - if (cExp == 0) { - normalizeFloat64Subnormal(cSig, &cExp, &cSig); - } - /* Subtract one to halve, and one again because roundAndPackFloat64 - * wants one less than the true exponent. - */ - cExp -= 2; - cSig = (cSig | 0x0010000000000000ULL) << 10; - return roundAndPackFloat64(cSign ^ signflip, cExp, cSig, status); - } - return packFloat64(cSign ^ signflip, cExp, cSig); - } - - if (aExp == 0) { - normalizeFloat64Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - normalizeFloat64Subnormal(bSig, &bExp, &bSig); - } - - /* Calculate the actual result a * b + c */ - - /* Multiply first; this is easy. */ - /* NB: we subtract 0x3fe where float64_mul() subtracts 0x3ff - * because we want the true exponent, not the "one-less-than" - * flavour that roundAndPackFloat64() takes. - */ - pExp = aExp + bExp - 0x3fe; - aSig = (aSig | LIT64(0x0010000000000000))<<10; - bSig = (bSig | LIT64(0x0010000000000000))<<11; - mul64To128(aSig, bSig, &pSig0, &pSig1); - if ((int64_t)(pSig0 << 1) >= 0) { - shortShift128Left(pSig0, pSig1, 1, &pSig0, &pSig1); - pExp--; - } - - zSign = pSign ^ signflip; - - /* Now [pSig0:pSig1] is the significand of the multiply, with the explicit - * bit in position 126. - */ - if (cExp == 0) { - if (!cSig) { - /* Throw out the special case of c being an exact zero now */ - shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1); - if (flags & float_muladd_halve_result) { - pExp--; - } - return roundAndPackFloat64(zSign, pExp - 1, - pSig1, status); - } - normalizeFloat64Subnormal(cSig, &cExp, &cSig); - } - - /* Shift cSig and add the explicit bit so [cSig0:cSig1] is the - * significand of the addend, with the explicit bit in position 126. - */ - cSig0 = cSig << (126 - 64 - 52); - cSig1 = 0; - cSig0 |= LIT64(0x4000000000000000); - expDiff = pExp - cExp; - - if (pSign == cSign) { - /* Addition */ - if (expDiff > 0) { - /* scale c to match p */ - shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); - zExp = pExp; - } else if (expDiff < 0) { - /* scale p to match c */ - shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); - zExp = cExp; - } else { - /* no scaling needed */ - zExp = cExp; - } - /* Add significands and make sure explicit bit ends up in posn 126 */ - add128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - if ((int64_t)zSig0 < 0) { - shift128RightJamming(zSig0, zSig1, 1, &zSig0, &zSig1); - } else { - zExp--; - } - shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1); - if (flags & float_muladd_halve_result) { - zExp--; - } - return roundAndPackFloat64(zSign, zExp, zSig1, status); - } else { - /* Subtraction */ - if (expDiff > 0) { - shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); - sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - zExp = pExp; - } else if (expDiff < 0) { - shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); - sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); - zExp = cExp; - zSign ^= 1; - } else { - zExp = pExp; - if (lt128(cSig0, cSig1, pSig0, pSig1)) { - sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); - } else if (lt128(pSig0, pSig1, cSig0, cSig1)) { - sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); - zSign ^= 1; - } else { - /* Exact zero */ - zSign = signflip; - if (status->float_rounding_mode == float_round_down) { - zSign ^= 1; - } - return packFloat64(zSign, 0, 0); - } - } - --zExp; - /* Do the equivalent of normalizeRoundAndPackFloat64() but - * starting with the significand in a pair of uint64_t. - */ - if (zSig0) { - shiftcount = countLeadingZeros64(zSig0) - 1; - shortShift128Left(zSig0, zSig1, shiftcount, &zSig0, &zSig1); - if (zSig1) { - zSig0 |= 1; - } - zExp -= shiftcount; - } else { - shiftcount = countLeadingZeros64(zSig1); - if (shiftcount == 0) { - zSig0 = (zSig1 >> 1) | (zSig1 & 1); - zExp -= 63; - } else { - shiftcount--; - zSig0 = zSig1 << shiftcount; - zExp -= (shiftcount + 64); - } - } - if (flags & float_muladd_halve_result) { - zExp--; - } - return roundAndPackFloat64(zSign, zExp, zSig0, status); - } -} /*---------------------------------------------------------------------------- | Returns the square root of the double-precision floating-point value `a'. diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 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 *status); float16 float16_div(float16, float16, float_status *status); int float16_is_quiet_nan(float16, float_status *status); From patchwork Tue Jan 9 12:22:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123929 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3975551qgn; Tue, 9 Jan 2018 04:43:52 -0800 (PST) X-Google-Smtp-Source: ACJfBos8XlBe0qhMscOWjL1NuolAK+wm9oBL5cRSWUA0r3wCau/cqILR4zKjEdxNdEByCe8xcxOf X-Received: by 10.13.216.214 with SMTP id a205mr13229394ywe.247.1515501832187; Tue, 09 Jan 2018 04:43:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501832; cv=none; d=google.com; s=arc-20160816; b=ra256mk4gVy8uknzZjGmnyO0vHNuCfYpVesmPf100xWOumdLaLlW01V8Pi2ns8pgj8 8Eoz+dddltLjJhAA4VXoR+q94vPTgiFzdL2aqoa5ZlMA/FmYvF3IpEeXKNUYKZMqXH7p cSaajxBF559ZyVlCs2Ty6qVYP1Fo9Ka06q8JSCbMsf16ln8/kYw0vee9e0150uzI9/2f tpZJkZQBKQDW2PzqjmL7HftzQqzGQcYgWMGE7615MvrtOnNp+Rkb8Z/akIj3rQKiXixM cPCGqyRWiLKls+Q7plSQztEEdtSrdVRCny4eDLwMQmdBpsGQqj49W7XlC9qM1XZn+Vo2 caXw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=gZUuItoMCkv+JpgUBtuyfqdsiVU3EEiyMFXhGaZpH1Q=; b=lJgj+YZQaF6wjMHg7pDZ3YezLhqo7m/0eNr3nIB3nIxNGmNCSzG5HuNVNcHOx3jLkc 7BrnOEWeea0pKXsVhGY/NpFgc/5t3bzpu6Bw5JAJj4DblCHpqF4konFH3cPgklRt/z/T LFC7bgSQZUuqRaDRQUOfMqj//DMXQaPu47+g5/EByTqXgPpzqMT7qRc7wHZdx0RtrMjJ M62XJUQb5esI6NIa55FVp0Wd3RUeDm9mE3zVFZWsmjyCf8ewZQZT0dXGGga2Ed8jYsBt RC5pY2FZrIkT38M4VVN9dqxtkwlyrK1zXGkWosZC94lvGHe5cVFFPxB2hiSqBwN8C+vP MZeQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ksV13FY2; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id v2si2999314ybk.645.2018.01.09.04.43.52 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:43:52 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ksV13FY2; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:50125 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYtFv-0006p9-Ld for patch@linaro.org; Tue, 09 Jan 2018 07:43:51 -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) 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-Received: by 10.223.160.139 with SMTP id m11mr13092185wrm.119.1515500906249; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" We can now add float16_round_to_int and use the common round_decomposed and canonicalize functions to have a single implementation for float16/32/64 round_to_int functions. Signed-off-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat.c | 304 ++++++++++++++++++++---------------------------- include/fpu/softfloat.h | 1 + 2 files changed, 130 insertions(+), 175 deletions(-) -- 2.15.1 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_status *status) return float64_round_pack_canonical(pr, status); } +/* + * Rounds the floating-point value `a' to an integer, and returns the + * result as a floating-point value. The operation is performed + * according to the IEC/IEEE Standard for Binary Floating-Point + * Arithmetic. + */ + +static decomposed_parts round_decomposed(decomposed_parts a, int rounding_mode, + float_status *s) +{ + + switch (a.cls) { + case float_class_snan: + a.cls = s->default_nan_mode ? float_class_dnan : float_class_msnan; + s->float_exception_flags |= float_flag_invalid; + break; + case float_class_zero: + case float_class_inf: + case float_class_qnan: + /* already "integral" */ + break; + case float_class_normal: + if (a.exp >= DECOMPOSED_BINARY_POINT) { + /* already integral */ + break; + } + if (a.exp < 0) { + bool one; + /* all fractional */ + s->float_exception_flags |= float_flag_inexact; + switch (rounding_mode) { + case float_round_nearest_even: + one = a.exp == -1 && a.frac > DECOMPOSED_IMPLICIT_BIT; + break; + case float_round_ties_away: + one = a.exp == -1 && a.frac >= DECOMPOSED_IMPLICIT_BIT; + break; + case float_round_to_zero: + one = false; + break; + case float_round_up: + one = !a.sign; + break; + case float_round_down: + one = a.sign; + break; + default: + g_assert_not_reached(); + } + + if (one) { + a.frac = DECOMPOSED_IMPLICIT_BIT; + a.exp = 0; + } else { + a.cls = float_class_zero; + } + } else { + uint64_t frac_lsb, frac_lsbm1, round_mask, roundeven_mask, inc; + + frac_lsb = DECOMPOSED_IMPLICIT_BIT >> a.exp; + frac_lsbm1 = frac_lsb >> 1; + roundeven_mask = (frac_lsb - 1) | frac_lsb; + round_mask = roundeven_mask >> 1; + + switch (rounding_mode) { + case float_round_nearest_even: + inc = ((a.frac & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0); + break; + case float_round_ties_away: + inc = frac_lsbm1; + break; + case float_round_to_zero: + inc = 0; + break; + case float_round_up: + inc = a.sign ? 0 : round_mask; + break; + case float_round_down: + inc = a.sign ? round_mask : 0; + break; + default: + g_assert_not_reached(); + } + + if (a.frac & round_mask) { + s->float_exception_flags |= float_flag_inexact; + a.frac += inc; + a.frac &= ~round_mask; + if (a.frac & DECOMPOSED_OVERFLOW_BIT) { + a.frac >>= 1; + a.exp++; + } + } + } + break; + default: + g_assert_not_reached(); + } + return a; +} + +float16 float16_round_to_int(float16 a, float_status *s) +{ + decomposed_parts pa = float16_unpack_canonical(a, s); + decomposed_parts pr = round_decomposed(pa, s->float_rounding_mode, s); + return float16_round_pack_canonical(pr, s); +} + +float32 float32_round_to_int(float32 a, float_status *s) +{ + decomposed_parts pa = float32_unpack_canonical(a, s); + decomposed_parts pr = round_decomposed(pa, s->float_rounding_mode, s); + return float32_round_pack_canonical(pr, s); +} + +float64 float64_round_to_int(float64 a, float_status *s) +{ + decomposed_parts pa = float64_unpack_canonical(a, s); + decomposed_parts pr = round_decomposed(pa, s->float_rounding_mode, s); + return float64_round_pack_canonical(pr, s); +} + +float64 float64_trunc_to_int(float64 a, float_status *s) +{ + decomposed_parts pa = float64_unpack_canonical(a, s); + decomposed_parts pr = round_decomposed(pa, float_round_to_zero, s); + return float64_round_pack_canonical(pr, s); +} + /*---------------------------------------------------------------------------- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to the @@ -2913,88 +3042,6 @@ float128 float32_to_float128(float32 a, float_status *status) } -/*---------------------------------------------------------------------------- -| Rounds the single-precision floating-point value `a' to an integer, and -| returns the result as a single-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_round_to_int(float32 a, float_status *status) -{ - flag aSign; - int aExp; - uint32_t lastBitMask, roundBitsMask; - uint32_t z; - a = float32_squash_input_denormal(a, status); - - aExp = extractFloat32Exp( a ); - if ( 0x96 <= aExp ) { - if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { - return propagateFloat32NaN(a, a, status); - } - return a; - } - if ( aExp <= 0x7E ) { - if ( (uint32_t) ( float32_val(a)<<1 ) == 0 ) return a; - status->float_exception_flags |= float_flag_inexact; - aSign = extractFloat32Sign( a ); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { - return packFloat32( aSign, 0x7F, 0 ); - } - break; - case float_round_ties_away: - if (aExp == 0x7E) { - return packFloat32(aSign, 0x7F, 0); - } - break; - case float_round_down: - return make_float32(aSign ? 0xBF800000 : 0); - case float_round_up: - return make_float32(aSign ? 0x80000000 : 0x3F800000); - } - return packFloat32( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x96 - aExp; - roundBitsMask = lastBitMask - 1; - z = float32_val(a); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - z += lastBitMask>>1; - if ((z & roundBitsMask) == 0) { - z &= ~lastBitMask; - } - break; - case float_round_ties_away: - z += lastBitMask >> 1; - break; - case float_round_to_zero: - break; - case float_round_up: - if (!extractFloat32Sign(make_float32(z))) { - z += roundBitsMask; - } - break; - case float_round_down: - if (extractFloat32Sign(make_float32(z))) { - z += roundBitsMask; - } - break; - default: - abort(); - } - z &= ~ roundBitsMask; - if (z != float32_val(a)) { - status->float_exception_flags |= float_flag_inexact; - } - return make_float32(z); - -} - - /*---------------------------------------------------------------------------- @@ -4140,99 +4187,6 @@ float128 float64_to_float128(float64 a, float_status *status) } -/*---------------------------------------------------------------------------- -| Rounds the double-precision floating-point value `a' to an integer, and -| returns the result as a double-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_round_to_int(float64 a, float_status *status) -{ - flag aSign; - int aExp; - uint64_t lastBitMask, roundBitsMask; - uint64_t z; - a = float64_squash_input_denormal(a, status); - - aExp = extractFloat64Exp( a ); - if ( 0x433 <= aExp ) { - if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { - return propagateFloat64NaN(a, a, status); - } - return a; - } - if ( aExp < 0x3FF ) { - if ( (uint64_t) ( float64_val(a)<<1 ) == 0 ) return a; - status->float_exception_flags |= float_flag_inexact; - aSign = extractFloat64Sign( a ); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { - return packFloat64( aSign, 0x3FF, 0 ); - } - break; - case float_round_ties_away: - if (aExp == 0x3FE) { - return packFloat64(aSign, 0x3ff, 0); - } - break; - case float_round_down: - return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0); - case float_round_up: - return make_float64( - aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 )); - } - return packFloat64( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x433 - aExp; - roundBitsMask = lastBitMask - 1; - z = float64_val(a); - switch (status->float_rounding_mode) { - case float_round_nearest_even: - z += lastBitMask >> 1; - if ((z & roundBitsMask) == 0) { - z &= ~lastBitMask; - } - break; - case float_round_ties_away: - z += lastBitMask >> 1; - break; - case float_round_to_zero: - break; - case float_round_up: - if (!extractFloat64Sign(make_float64(z))) { - z += roundBitsMask; - } - break; - case float_round_down: - if (extractFloat64Sign(make_float64(z))) { - z += roundBitsMask; - } - break; - default: - abort(); - } - z &= ~ roundBitsMask; - if (z != float64_val(a)) { - status->float_exception_flags |= float_flag_inexact; - } - return make_float64(z); - -} - -float64 float64_trunc_to_int(float64 a, float_status *status) -{ - int oldmode; - float64 res; - oldmode = status->float_rounding_mode; - status->float_rounding_mode = float_round_to_zero; - res = float64_round_to_int(a, status); - status->float_rounding_mode = oldmode; - return res; -} - /*---------------------------------------------------------------------------- | Returns the remainder of the double-precision floating-point value `a' diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 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. *----------------------------------------------------------------------------*/ +float16 float16_round_to_int(float16, float_status *status); float16 float16_add(float16, float16, float_status *status); float16 float16_sub(float16, float16, float_status *status); float16 float16_mul(float16, float16, float_status *status); From patchwork Tue Jan 9 12:22:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123914 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3965043qgn; Tue, 9 Jan 2018 04:32:48 -0800 (PST) X-Google-Smtp-Source: ACJfBovOnwtUI1hPZt08b7CvJAKkaH/1vwtFdDfZ7juH/0UVM3irNZyz76noiQjS0ObAnhMzU5la X-Received: by 10.37.186.210 with SMTP id a18mr13827689ybk.183.1515501168790; Tue, 09 Jan 2018 04:32:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501168; cv=none; d=google.com; s=arc-20160816; b=jpavE/h5ggg1ApB0eCV5b/wbQT2OeS5sy0xeWSRD2iQaIdtUHXv4yJm7I9EPTE1n7W WMvflzJeekU8TaRMNOG+/o9YWKqhTqqYRInf/YqVoHSsCi65kx9L3fapPi8mR28vAXey uf7xPYv3pzqQTjIb+fWcOeBqWeKQqBdROMuTxsGSqMr8ESO5IRpJ79fZRkNAYhh7EcKe 45YSxFc3a+YvIv1sqUlVkg3/VyYjxNthmqeyXtqWhSS1mc/OM+TgjQgLM0ER+Qqg70vc 5tN92EHAn39KSRM2CgvQy5c7DhyLD7cLKhQvswKmoP+5aPmi1mi/7OJHdBEC9/K4ZTa7 RTug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=gFxawPFfcFKLqcrR8t9RlmB5BzbYkhcyH3KPgWXjRvs=; b=pOO+AhLNT6wgdDsmp38oN+pSe4+TeePXOqYhs/MYGu47FVKh4tQ0UUHkkjbB0K1F0b yxyzOXHi0vpRPjFxyzwQqRMQYU/q/RdLUZvtosHDz+bsRZHhAgR03w2HsUKW+um2kQ26 TyQ8tvDgqSnbkf+rIrlX2XoYM15hSN/6bNF9RQ8wETnN1efVILDBYb13KkXajPlFWUge lfw1cRKYZd1rhDMOUwixRNCJjHw044MZewe1eiyEcHVkCn12oJiyy6yZZcNrR9C+30fE RnL7RW2Ki3Swh8btzaBaRSYVaz6Jj7rwyDbYnUOGztozGwhFixdXqP1S+IEj5twKz+oo RD0A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=DPvpyoGR; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id c3si1185618ybk.772.2018.01.09.04.32.48 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:32:48 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=DPvpyoGR; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49542 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt5E-0005ka-47 for patch@linaro.org; Tue, 09 Jan 2018 07:32:48 -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) 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-Received: by 10.28.132.207 with SMTP id g198mr11412114wmd.118.1515500590112; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" We share the common int64/uint64_pack_decomposed function across all the helpers and simply limit the final result depending on the final size. Signed-off-by: Alex Bennée -- v2 - apply float_flg_invalid fixes next patch --- fpu/softfloat.c | 1011 +++++++++++------------------------------------ include/fpu/softfloat.h | 13 + 2 files changed, 235 insertions(+), 789 deletions(-) -- 2.15.1 Reviewed-by: Richard Henderson 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_status *s) return float64_round_pack_canonical(pr, s); } +/*---------------------------------------------------------------------------- +| Returns the result of converting the floating-point value +| `a' to the two's complement integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. Otherwise, if the conversion overflows, the +| largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +static int64_t int64_pack_decomposed(decomposed_parts p, float_status *s) +{ + uint64_t r; + + switch (p.cls) { + case float_class_snan: + case float_class_qnan: + return INT64_MAX; + case float_class_inf: + return p.sign ? INT64_MIN : INT64_MAX; + case float_class_zero: + return 0; + case float_class_normal: + if (p.exp < DECOMPOSED_BINARY_POINT) { + r = p.frac >> (DECOMPOSED_BINARY_POINT - p.exp); + } else if (p.exp < 64) { + r = p.frac << (p.exp - DECOMPOSED_BINARY_POINT); + } else { + s->float_exception_flags |= float_flag_invalid; + r = UINT64_MAX; + } + if (p.sign) { + return r < - (uint64_t) INT64_MIN ? -r : INT64_MIN; + } else { + return r < INT64_MAX ? r : INT64_MAX; + } + default: + g_assert_not_reached(); + } +} + +static int16_t int16_pack_decomposed(decomposed_parts p, float_status *s) +{ + int64_t r = int64_pack_decomposed(p, s); + if (r < INT16_MIN) { + s->float_exception_flags |= float_flag_invalid; + return INT16_MIN; + } else if (r > INT16_MAX) { + s->float_exception_flags |= float_flag_invalid; + return INT16_MAX; + } + return r; +} + +static int32_t int32_pack_decomposed(decomposed_parts p, float_status *s) +{ + int64_t r = int64_pack_decomposed(p, s); + if (r < INT32_MIN) { + s->float_exception_flags |= float_flag_invalid; + return INT32_MIN; + } else if (r > INT32_MAX) { + s->float_exception_flags |= float_flag_invalid; + return INT32_MAX; + } + return r; +} + +#define FLOAT_TO_INT(fsz, isz) \ +int ## isz ## _t float ## fsz ## _to_int ## isz(float ## fsz a, float_status *s) \ +{ \ + decomposed_parts pa = float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr = round_decomposed(pa, s->float_rounding_mode, s); \ + return int ## isz ## _pack_decomposed(pr, s); \ +} \ + \ +int ## isz ## _t float ## fsz ## _to_int ## isz ## _round_to_zero \ + (float ## fsz a, float_status *s) \ +{ \ + decomposed_parts pa = float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr = round_decomposed(pa, float_round_to_zero, s); \ + return int ## isz ## _pack_decomposed(pr, s); \ +} + +FLOAT_TO_INT(16, 16) +FLOAT_TO_INT(16, 32) +FLOAT_TO_INT(16, 64) + +FLOAT_TO_INT(32, 16) +FLOAT_TO_INT(32, 32) +FLOAT_TO_INT(32, 64) + +FLOAT_TO_INT(64, 16) +FLOAT_TO_INT(64, 32) +FLOAT_TO_INT(64, 64) + +#undef FLOAT_TO_INT + +/* + * Returns the result of converting the floating-point value `a' to + * the unsigned integer format. The conversion is performed according + * to the IEC/IEEE Standard for Binary Floating-Point + * Arithmetic---which means in particular that the conversion is + * rounded according to the current rounding mode. If `a' is a NaN, + * the largest unsigned integer is returned. Otherwise, if the + * conversion overflows, the largest unsigned integer is returned. If + * the 'a' is negative, the result is rounded and zero is returned; + * values that do not round to zero will raise the inexact exception + * flag. + */ + +static uint64_t uint64_pack_decomposed(decomposed_parts p, float_status *s) +{ + switch (p.cls) { + case float_class_snan: + case float_class_qnan: + return UINT64_MAX; + case float_class_inf: + return p.sign ? 0 : UINT64_MAX; + case float_class_zero: + return 0; + case float_class_normal: + if (p.sign) { + s->float_exception_flags |= 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 |= 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 = uint64_pack_decomposed(p, s); + if (r > UINT16_MAX) { + s->float_exception_flags |= float_flag_invalid; + r = UINT16_MAX; + } + return r; +} + +static uint32_t uint32_pack_decomposed(decomposed_parts p, float_status *s) +{ + uint64_t r = uint64_pack_decomposed(p, s); + if (r > UINT32_MAX) { + s->float_exception_flags |= float_flag_invalid; + r = UINT32_MAX; + } + return r; +} + +#define FLOAT_TO_UINT(fsz, isz) \ +uint ## isz ## _t float ## fsz ## _to_uint ## isz(float ## fsz a, float_status *s) \ +{ \ + decomposed_parts pa = float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr = round_decomposed(pa, s->float_rounding_mode, s); \ + return uint ## isz ## _pack_decomposed(pr, s); \ +} \ + \ +uint ## isz ## _t float ## fsz ## _to_uint ## isz ## _round_to_zero \ + (float ## fsz a, float_status *s) \ +{ \ + decomposed_parts pa = float ## fsz ## _unpack_canonical(a, s); \ + decomposed_parts pr = round_decomposed(pa, float_round_to_zero, s); \ + return uint ## isz ## _pack_decomposed(pr, s); \ +} + +FLOAT_TO_UINT(16, 16) +FLOAT_TO_UINT(16, 32) +FLOAT_TO_UINT(16, 64) + +FLOAT_TO_UINT(32, 16) +FLOAT_TO_UINT(32, 32) +FLOAT_TO_UINT(32, 64) + +FLOAT_TO_UINT(64, 16) +FLOAT_TO_UINT(64, 32) +FLOAT_TO_UINT(64, 64) + +#undef FLOAT_TO_UINT + /*---------------------------------------------------------------------------- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to the @@ -2663,288 +2851,8 @@ float128 uint64_to_float128(uint64_t a, float_status *status) return normalizeRoundAndPackFloat128(0, 0x406E, a, 0, status); } -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ -int32_t float32_to_int32(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64; - - a = float32_squash_input_denormal(a, status); - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( ( aExp == 0xFF ) && aSig ) aSign = 0; - if ( aExp ) aSig |= 0x00800000; - shiftCount = 0xAF - aExp; - aSig64 = aSig; - aSig64 <<= 32; - if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64 ); - return roundAndPackInt32(aSign, aSig64, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int32_t float32_to_int32_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - int32_t z; - a = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0x9E; - if ( 0 <= shiftCount ) { - if ( float32_val(a) != 0xCF000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; - } - return (int32_t) 0x80000000; - } - else if ( aExp <= 0x7E ) { - if (aExp | aSig) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - aSig = ( aSig | 0x00800000 )<<8; - z = aSig>>( - shiftCount ); - if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { - status->float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 16-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int16_t float32_to_int16_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - int32_t z; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0x8E; - if ( 0 <= shiftCount ) { - if ( float32_val(a) != 0xC7000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return 0x7FFF; - } - } - return (int32_t) 0xffff8000; - } - else if ( aExp <= 0x7E ) { - if ( aExp | aSig ) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - shiftCount -= 0x10; - aSig = ( aSig | 0x00800000 )<<8; - z = aSig>>( - shiftCount ); - if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { - status->float_exception_flags |= float_flag_inexact; - } - if ( aSign ) { - z = - z; - } - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int64_t float32_to_int64(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64, aSigExtra; - a = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = 0xBE - aExp; - if ( shiftCount < 0 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - if ( aExp ) aSig |= 0x00800000; - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); - return roundAndPackInt64(aSign, aSig64, aSigExtra, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| unsigned integer is returned. Otherwise, if the conversion overflows, the -| largest unsigned integer is returned. If the 'a' is negative, the result -| is rounded and zero is returned; values that do not round to zero will -| raise the inexact exception flag. -*----------------------------------------------------------------------------*/ - -uint64_t float32_to_uint64(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64, aSigExtra; - a = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - if ((aSign) && (aExp > 126)) { - float_raise(float_flag_invalid, status); - if (float32_is_any_nan(a)) { - return LIT64(0xFFFFFFFFFFFFFFFF); - } else { - return 0; - } - } - shiftCount = 0xBE - aExp; - if (aExp) { - aSig |= 0x00800000; - } - if (shiftCount < 0) { - float_raise(float_flag_invalid, status); - return LIT64(0xFFFFFFFFFFFFFFFF); - } - - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra); - return roundAndPackUint64(aSign, aSig64, aSigExtra, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest unsigned integer is returned. Otherwise, if the -| conversion overflows, the largest unsigned integer is returned. If the -| 'a' is negative, the result is rounded and zero is returned; values that do -| not round to zero will raise the inexact flag. -*----------------------------------------------------------------------------*/ - -uint64_t float32_to_uint64_round_to_zero(float32 a, float_status *status) -{ - signed char current_rounding_mode = status->float_rounding_mode; - set_float_rounding_mode(float_round_to_zero, status); - int64_t v = float32_to_uint64(a, status); - set_float_rounding_mode(current_rounding_mode, status); - return v; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest positive integer is returned. Otherwise, if the -| conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int64_t float32_to_int64_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64; - int64_t z; - a = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0xBE; - if ( 0 <= shiftCount ) { - if ( float32_val(a) != 0xDF000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - else if ( aExp <= 0x7E ) { - if (aExp | aSig) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - aSig64 = aSig | 0x00800000; - aSig64 <<= 40; - z = aSig64>>( - shiftCount ); - if ( (uint64_t) ( aSig64<<( shiftCount & 63 ) ) ) { - status->float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} /*---------------------------------------------------------------------------- | Returns the result of converting the single-precision floating-point value @@ -3500,289 +3408,59 @@ int float32_le_quiet(float32 a, float32 b, float_status *status) | Returns 1 if the single-precision floating-point value `a' is less than | the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an | exception. Otherwise, the comparison is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -int float32_lt_quiet(float32 a, float32 b, float_status *status) -{ - flag aSign, bSign; - uint32_t av, bv; - a = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if (float32_is_signaling_nan(a, status) - || float32_is_signaling_nan(b, status)) { - float_raise(float_flag_invalid, status); - } - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - av = float32_val(a); - bv = float32_val(b); - if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 ); - return ( av != bv ) && ( aSign ^ ( av < bv ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point values `a' and `b' cannot -| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The -| comparison is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -int float32_unordered_quiet(float32 a, float32 b, float_status *status) -{ - a = float32_squash_input_denormal(a, status); - b = float32_squash_input_denormal(b, status); - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if (float32_is_signaling_nan(a, status) - || float32_is_signaling_nan(b, status)) { - float_raise(float_flag_invalid, status); - } - return 1; - } - return 0; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32_t float64_to_int32(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig; - a = float64_squash_input_denormal(a, status); - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; - if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x42C - aExp; - if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32(aSign, aSig, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int32_t float64_to_int32_round_to_zero(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, savedASig; - int32_t z; - a = float64_squash_input_denormal(a, status); - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( 0x41E < aExp ) { - if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FF ) { - if (aExp || aSig) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x433 - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = aSig; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise(float_flag_invalid, status); - return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<float_exception_flags |= float_flag_inexact; - } - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 16-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int16_t float64_to_int16_round_to_zero(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, savedASig; - int32_t z; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( 0x40E < aExp ) { - if ( ( aExp == 0x7FF ) && aSig ) { - aSign = 0; - } - goto invalid; - } - else if ( aExp < 0x3FF ) { - if ( aExp || aSig ) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x433 - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = aSig; - if ( aSign ) { - z = - z; - } - if ( ( (int16_t)z < 0 ) ^ aSign ) { - invalid: - float_raise(float_flag_invalid, status); - return aSign ? (int32_t) 0xffff8000 : 0x7FFF; - } - if ( ( aSig<float_exception_flags |= float_flag_inexact; - } - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. +| Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -int64_t float64_to_int64(float64 a, float_status *status) +int float32_lt_quiet(float32 a, float32 b, float_status *status) { - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, aSigExtra; - a = float64_squash_input_denormal(a, status); + flag aSign, bSign; + uint32_t av, bv; + a = float32_squash_input_denormal(a, status); + b = float32_squash_input_denormal(b, status); - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x433 - aExp; - if ( shiftCount <= 0 ) { - if ( 0x43E < aExp ) { + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if (float32_is_signaling_nan(a, status) + || float32_is_signaling_nan(b, status)) { float_raise(float_flag_invalid, status); - if ( ! aSign - || ( ( aExp == 0x7FF ) - && ( aSig != LIT64( 0x0010000000000000 ) ) ) - ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (int64_t) LIT64( 0x8000000000000000 ); } - aSigExtra = 0; - aSig <<= - shiftCount; - } - else { - shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra ); + return 0; } - return roundAndPackInt64(aSign, aSig, aSigExtra, status); + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + av = float32_val(a); + bv = float32_val(b); + if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 ); + return ( av != bv ) && ( aSign ^ ( av < bv ) ); } /*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. +| Returns 1 if the single-precision floating-point values `a' and `b' cannot +| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The +| comparison is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -int64_t float64_to_int64_round_to_zero(float64 a, float_status *status) +int float32_unordered_quiet(float32 a, float32 b, float_status *status) { - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig; - int64_t z; - a = float64_squash_input_denormal(a, status); + a = float32_squash_input_denormal(a, status); + b = float32_squash_input_denormal(b, status); - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); - shiftCount = aExp - 0x433; - if ( 0 <= shiftCount ) { - if ( 0x43E <= aExp ) { - if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) { - float_raise(float_flag_invalid, status); - if ( ! aSign - || ( ( aExp == 0x7FF ) - && ( aSig != LIT64( 0x0010000000000000 ) ) ) - ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - z = aSig<float_exception_flags |= float_flag_inexact; - } - return 0; - } - z = aSig>>( - shiftCount ); - if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) { - status->float_exception_flags |= float_flag_inexact; + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if (float32_is_signaling_nan(a, status) + || float32_is_signaling_nan(b, status)) { + float_raise(float_flag_invalid, status); } + return 1; } - if ( aSign ) z = - z; - return z; - + return 0; } + /*---------------------------------------------------------------------------- | Returns the result of converting the double-precision floating-point value | `a' to the single-precision floating-point format. The conversion is @@ -7049,252 +6727,7 @@ float64 uint32_to_float64(uint32_t a, float_status *status) return int64_to_float64(a, status); } -uint32_t float32_to_uint32(float32 a, float_status *status) -{ - int64_t v; - uint32_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float32_to_int64(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffffffff) { - res = 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint32_t float32_to_uint32_round_to_zero(float32 a, float_status *status) -{ - int64_t v; - uint32_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float32_to_int64_round_to_zero(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffffffff) { - res = 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -int16_t float32_to_int16(float32 a, float_status *status) -{ - int32_t v; - int16_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float32_to_int32(a, status); - if (v < -0x8000) { - res = -0x8000; - } else if (v > 0x7fff) { - res = 0x7fff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float32_to_uint16(float32 a, float_status *status) -{ - int32_t v; - uint16_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float32_to_int32(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffff) { - res = 0xffff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float32_to_uint16_round_to_zero(float32 a, float_status *status) -{ - int64_t v; - uint16_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float32_to_int64_round_to_zero(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffff) { - res = 0xffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint32_t float64_to_uint32(float64 a, float_status *status) -{ - uint64_t v; - uint32_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float64_to_uint64(a, status); - if (v > 0xffffffff) { - res = 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint32_t float64_to_uint32_round_to_zero(float64 a, float_status *status) -{ - uint64_t v; - uint32_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float64_to_uint64_round_to_zero(a, status); - if (v > 0xffffffff) { - res = 0xffffffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -int16_t float64_to_int16(float64 a, float_status *status) -{ - int64_t v; - int16_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float64_to_int32(a, status); - if (v < -0x8000) { - res = -0x8000; - } else if (v > 0x7fff) { - res = 0x7fff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float64_to_uint16(float64 a, float_status *status) -{ - int64_t v; - uint16_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float64_to_int32(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffff) { - res = 0xffff; - } else { - return v; - } - - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -uint16_t float64_to_uint16_round_to_zero(float64 a, float_status *status) -{ - int64_t v; - uint16_t res; - int old_exc_flags = get_float_exception_flags(status); - - v = float64_to_int64_round_to_zero(a, status); - if (v < 0) { - res = 0; - } else if (v > 0xffff) { - res = 0xffff; - } else { - return v; - } - set_float_exception_flags(old_exc_flags, status); - float_raise(float_flag_invalid, status); - return res; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. If the conversion overflows, the -| largest unsigned integer is returned. If 'a' is negative, the value is -| rounded and zero is returned; negative values that do not round to zero -| will raise the inexact exception. -*----------------------------------------------------------------------------*/ - -uint64_t float64_to_uint64(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig, aSigExtra; - a = float64_squash_input_denormal(a, status); - - aSig = extractFloat64Frac(a); - aExp = extractFloat64Exp(a); - aSign = extractFloat64Sign(a); - if (aSign && (aExp > 1022)) { - float_raise(float_flag_invalid, status); - if (float64_is_any_nan(a)) { - return LIT64(0xFFFFFFFFFFFFFFFF); - } else { - return 0; - } - } - if (aExp) { - aSig |= LIT64(0x0010000000000000); - } - shiftCount = 0x433 - aExp; - if (shiftCount <= 0) { - if (0x43E < aExp) { - float_raise(float_flag_invalid, status); - return LIT64(0xFFFFFFFFFFFFFFFF); - } - aSigExtra = 0; - aSig <<= -shiftCount; - } else { - shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra); - } - return roundAndPackUint64(aSign, aSig, aSigExtra, status); -} -uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *status) -{ - signed char current_rounding_mode = status->float_rounding_mode; - set_float_rounding_mode(float_round_to_zero, status); - uint64_t v = float64_to_uint64(a, status); - set_float_rounding_mode(current_rounding_mode, status); - return v; -} #define COMPARE(s, nan_exp) \ static inline int float ## s ## _compare_internal(float ## s a, float ## s b,\ diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 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); /*---------------------------------------------------------------------------- | Software half-precision operations. From patchwork Tue Jan 9 12:22:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123924 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3973301qgn; Tue, 9 Jan 2018 04:41:22 -0800 (PST) X-Google-Smtp-Source: ACJfBosDVhPaVRZsaR23fxDVwIbTVZloZ1nqh4KCehvssWNi8vtFY6GTPxJNSBe047mPHARDhHap X-Received: by 10.37.41.4 with SMTP id p4mr14032132ybp.206.1515501682078; Tue, 09 Jan 2018 04:41:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501682; cv=none; d=google.com; s=arc-20160816; b=qXnWvCxUvFXGFUNZ89akdm7cJ8LwdmWFdgObJ7zEtkd1TyiMhmir2dMu+LAZvDrJK/ kNMWq3ESX2pwzmV6WDTEIwdsv7l7h9eIpNLMn/SCrDWh7LMvSfnftjBDKR8jllWaMZqL 6mroZWZ2C62IQruVGKnMS5enHKrQ1R3OhuRz2iqbZ5RUfEy6Yj215QTnkcDSVVyisrrn Dd7J9GrzRW6zKo0xDGSgqr1fmaURUStX1lS8Jk2kQrBFwjfmrZy7+ZMXVqxF5UdJ/ccP DHh+UEovPRq9NIKst5NujkTyelsO6oX+7O36VUg+DMcERnUu+TDjBnNMSfqUvtUnXBWb 9/pQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=Cd1mYU8XGNQ5/1cXy362zD56NfttIO5m6b+OmxTdnaI=; b=s0QlqSW3wPSRm2xlaFKHll6FA4f66IWuORvFBBVOuK/CmXHR2iah/xhCuU4fQC73oT fBjJVX+CXJfDOIYMir4Wp/mLDTd7E63zgIIfTw0b+EqnPVv3iHARIkBbrnWbLGwwuxO4 HCMSOAAgqvC++5cv3VabYnc8zUNqwCOldTGHOSWGZGdyzru2M8TkHo3jfU5oHgEvJPIW KWIcG2OqQcy3cuTw8ph7vKNGw8dsdsMIuOnKzAc/TLqFt12BRPyQLeU5TF5u0au5Ch2+ x5T6LokZn2L3ProSQ9Gu5SvRvSqjj82qOmd8q2WVZAcwIFgxPDVgpGlqFcw+ZOzrhRgi WuUw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ckvuvOay; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id c18si2963872ywk.234.2018.01.09.04.41.21 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:41:22 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ckvuvOay; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:50007 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYtDV-0004jM-I5 for patch@linaro.org; Tue, 09 Jan 2018 07:41:21 -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) 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-Received: by 10.28.45.83 with SMTP id t80mr11517460wmt.90.1515500908866; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" These are considerably simpler as the lower order integers can just use the higher order conversion function. As the decomposed fractional part is a full 64 bit rounding and inexact handling comes from the pack functions. Signed-off-by: Alex Bennée 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(-) -- 2.15.1 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) #undef FLOAT_TO_UINT +/* + * Integer to float conversions + * + * Returns the result of converting the two's complement integer `a' + * to the floating-point format. The conversion is performed according + * to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +static decomposed_parts int_to_float(int64_t a, float_status *status) +{ + decomposed_parts r; + if (a == 0) { + r.cls = float_class_zero; + r.sign = false; + } else if (a == (1ULL << 63)) { + r.cls = float_class_normal; + r.sign = true; + r.frac = DECOMPOSED_IMPLICIT_BIT; + r.exp = 63; + } else { + uint64_t f; + if (a < 0) { + f = -a; + r.sign = true; + } else { + f = a; + r.sign = false; + } + int shift = clz64(f) - 1; + r.cls = float_class_normal; + r.exp = (DECOMPOSED_BINARY_POINT - shift); + r.frac = f << shift; + } + + return r; +} + +float16 int64_to_float16(int64_t a, float_status *status) +{ + decomposed_parts pa = int_to_float(a, status); + return float16_round_pack_canonical(pa, status); +} + +float16 int32_to_float16(int32_t a, float_status *status) +{ + return int64_to_float16(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 = 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 = 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 = { .sign = false}; + + if (a == 0) { + r.cls = float_class_zero; + } else { + int spare_bits = clz64(a) - 1; + r.cls = float_class_normal; + r.exp = DECOMPOSED_BINARY_POINT - spare_bits; + if (spare_bits < 0) { + shift64RightJamming(a, -spare_bits, &a); + r.frac = a; + } else { + r.frac = a << spare_bits; + } + } + + return r; +} + +float16 uint64_to_float16(uint64_t a, float_status *status) +{ + decomposed_parts pa = uint_to_float(a, status); + return float16_round_pack_canonical(pa, status); +} + +float16 uint32_to_float16(uint32_t a, float_status *status) +{ + return uint64_to_float16(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 = 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 = 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 zSign, int32_t zExp, } -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the single-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 int32_to_float32(int32_t a, float_status *status) -{ - flag zSign; - - if ( a == 0 ) return float32_zero; - if ( a == (int32_t) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); - zSign = ( a < 0 ); - return normalizeRoundAndPackFloat32(zSign, 0x9C, zSign ? -a : a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the double-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 int32_to_float64(int32_t a, float_status *status) -{ - flag zSign; - uint32_t absA; - int8_t shiftCount; - uint64_t zSig; - - if ( a == 0 ) return float64_zero; - zSign = ( a < 0 ); - absA = zSign ? - a : a; - shiftCount = countLeadingZeros32( absA ) + 21; - zSig = absA; - return packFloat64( zSign, 0x432 - shiftCount, zSig<= 0) { - return packFloat32(0, 0x95 - shiftcount, a << shiftcount); - } - /* Otherwise we need to do a round-and-pack. roundAndPackFloat32() - * expects the binary point between bits 30 and 29, hence the + 7. - */ - shiftcount += 7; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<= shiftcount; - } - - return roundAndPackFloat32(0, 0x9c - shiftcount, a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 64-bit unsigned integer `a' -| to the double-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 uint64_to_float64(uint64_t a, float_status *status) -{ - int exp = 0x43C; - int shiftcount; - - if (a == 0) { - return float64_zero; - } - - shiftcount = countLeadingZeros64(a) - 1; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<= shiftcount; - } - return roundAndPackFloat64(0, exp - shiftcount, a, status); -} - /*---------------------------------------------------------------------------- | Returns the result of converting the 64-bit unsigned integer `a' | to the quadruple-precision floating-point format. The conversion is performed @@ -6716,19 +6733,6 @@ int float128_unordered_quiet(float128 a, float128 b, float_status *status) return 0; } -/* misc functions */ -float32 uint32_to_float32(uint32_t a, float_status *status) -{ - return int64_to_float32(a, status); -} - -float64 uint32_to_float64(uint32_t a, float_status *status) -{ - return int64_to_float64(a, status); -} - - - #define COMPARE(s, nan_exp) \ static inline int float ## s ## _compare_internal(float ## s a, float ## s b,\ int is_quiet, float_status *status) \ diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 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 *status); float64 uint64_to_float64(uint64_t, float_status *status); float128 uint64_to_float128(uint64_t, float_status *status); -/* We provide the int16 versions for symmetry of API with float-to-int */ -static inline float32 int16_to_float32(int16_t v, float_status *status) -{ - return int32_to_float32(v, status); -} - -static inline float32 uint16_to_float32(uint16_t v, float_status *status) -{ - return uint32_to_float32(v, status); -} - -static inline float64 int16_to_float64(int16_t v, float_status *status) -{ - return int32_to_float64(v, status); -} - -static inline float64 uint16_to_float64(uint16_t v, float_status *status) -{ - return uint32_to_float64(v, status); -} - /*---------------------------------------------------------------------------- | Software half-precision conversion routines. *----------------------------------------------------------------------------*/ @@ -327,6 +310,11 @@ uint64_t float16_to_uint64(float16 a, float_status *status); int64_t float16_to_int64_round_to_zero(float16, float_status *status); uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); float16 int16_to_float16(int16_t a, float_status *status); +float16 int32_to_float16(int32_t a, float_status *status); +float16 int64_to_float16(int64_t a, float_status *status); +float16 uint16_to_float16(uint16_t a, float_status *status); +float16 uint32_to_float16(uint32_t a, float_status *status); +float16 uint64_to_float16(uint64_t a, float_status *status); /*---------------------------------------------------------------------------- | Software half-precision operations. From patchwork Tue Jan 9 12:22:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123923 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3971737qgn; Tue, 9 Jan 2018 04:39:43 -0800 (PST) X-Google-Smtp-Source: ACJfBouEo9hN4U+JgLyHz6iSlBJ79XISMRXHlesUoSQJnKaGY3iRO1HYuUFOHTy6/umP5gZxRTyN X-Received: by 10.129.106.213 with SMTP id f204mr4415562ywc.198.1515501583289; Tue, 09 Jan 2018 04:39:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501583; cv=none; d=google.com; s=arc-20160816; b=bRqB5ZxicOrmXnkW+frWWfoGGQBY8pZuDX4eUo+iNStPRGdxgTBmGLaz3M0C7icz5z FKgEeZVwGrz1Ap3Hl5wym1PpQ/sQ7I4MVXohvaLwFAut2yL5Dhz2lgwK1emxxM6Mt3Of kqWeOcGbMhWqnjbnfQdD5qGmJJbOlWsUHWT2xvdyniuS7Bxt1GIQWknc18uBJogX3zsC Leud8hFPoEK7n0vUru8Hklv+e2cXkgkbA/p1mlOTBSWf0FHEY1WKMN1mExvEkrAWt1Gz p9bMd/pLCKxr853/BVx0jvW959/sIeOuZsDvNSqU83CnSw/AzvR5bOU004awrYmX3L+k LJsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=iqs4IKr51meQKEBEWobMjAnSDOK0/YUs1Bat82nJ60M=; b=t7lKy0uHze3Z9aJLmIBx0WmxNKUdsn62LHC2KKEUTB8P+Orl7K3HvGW4N0500Etddl h4hKYwEliMV2mNAoDdX7ytWmKmvSCGSfCd61bYsG6VvQO4gANCQ8l/h1Vma5sLmmI3A5 j76Lewu6S1ovMIXqyEzHj7E01bdNf01NAMx4BnW7GBfgxtFDMs+wlb8+TVjXUwIZ2ujq 5YiLAns7bUpMkl97exjaTxwSf0B/Ey9YeN4j3owVGN7MwznpisBHkVAoCAEjD9JIlAz8 iZPit3F+XVqihv41vI5Thqm5cUm2whBsyk9UlEDQ2q+M8Bi0UEkjRpSIFikKZpFX/OOq 5v1g== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Rd6bSRdm; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id x11si2938554ybj.154.2018.01.09.04.39.43 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:39:43 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Rd6bSRdm; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49814 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYtBu-0003J6-Oz for patch@linaro.org; Tue, 09 Jan 2018 07:39:42 -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) 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-Received: by 10.28.85.193 with SMTP id j184mr12462536wmb.56.1515500905527; Tue, 09 Jan 2018 04:28:25 -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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This is one of the simpler manipulations you could make to a floating point number. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- fpu/softfloat.c | 104 +++++++++++++++--------------------------------- include/fpu/softfloat.h | 1 + 2 files changed, 32 insertions(+), 73 deletions(-) -- 2.15.1 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); } +/* Multiply A by 2 raised to the power N. */ +static decomposed_parts scalbn_decomposed(decomposed_parts a, int n, + float_status *s) +{ + if (a.cls == float_class_normal) { + a.exp += n; + } + return a; +} + +float16 float16_scalbn(float16 a, int n, float_status *status) +{ + decomposed_parts pa = float16_unpack_canonical(a, status); + decomposed_parts pr = scalbn_decomposed(pa, n, status); + return float16_round_pack_canonical(pr, status); +} + +float32 float32_scalbn(float32 a, int n, float_status *status) +{ + decomposed_parts pa = float32_unpack_canonical(a, status); + decomposed_parts pr = scalbn_decomposed(pa, n, status); + return float32_round_pack_canonical(pr, status); +} + +float64 float64_scalbn(float64 a, int n, float_status *status) +{ + decomposed_parts pa = float64_unpack_canonical(a, status); + decomposed_parts pr = scalbn_decomposed(pa, n, status); + return float64_round_pack_canonical(pr, status); +} + /*---------------------------------------------------------------------------- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 | and 7, and returns the properly rounded 32-bit integer corresponding to the @@ -6992,79 +7023,6 @@ MINMAX(32) MINMAX(64) -/* Multiply A by 2 raised to the power N. */ -float32 float32_scalbn(float32 a, int n, float_status *status) -{ - flag aSign; - int16_t aExp; - uint32_t aSig; - - a = float32_squash_input_denormal(a, status); - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - - if ( aExp == 0xFF ) { - if ( aSig ) { - return propagateFloat32NaN(a, a, status); - } - return a; - } - if (aExp != 0) { - aSig |= 0x00800000; - } else if (aSig == 0) { - return a; - } else { - aExp++; - } - - if (n > 0x200) { - n = 0x200; - } else if (n < -0x200) { - n = -0x200; - } - - aExp += n - 1; - aSig <<= 7; - return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status); -} - -float64 float64_scalbn(float64 a, int n, float_status *status) -{ - flag aSign; - int16_t aExp; - uint64_t aSig; - - a = float64_squash_input_denormal(a, status); - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - - if ( aExp == 0x7FF ) { - if ( aSig ) { - return propagateFloat64NaN(a, a, status); - } - return a; - } - if (aExp != 0) { - aSig |= LIT64( 0x0010000000000000 ); - } else if (aSig == 0) { - return a; - } else { - aExp++; - } - - if (n > 0x1000) { - n = 0x1000; - } else if (n < -0x1000) { - n = -0x1000; - } - - aExp += n - 1; - aSig <<= 10; - return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status); -} - floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) { flag aSign; diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index aa9e30d254..41338184d5 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -326,6 +326,7 @@ float16 float16_sub(float16, float16, float_status *status); float16 float16_mul(float16, float16, float_status *status); float16 float16_muladd(float16, float16, float16, int, float_status *status); float16 float16_div(float16, float16, float_status *status); +float16 float16_scalbn(float16, int, float_status *status); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); From patchwork Tue Jan 9 12:22:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123912 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3963773qgn; Tue, 9 Jan 2018 04:31:37 -0800 (PST) X-Google-Smtp-Source: ACJfBou+f4n77zAca9P9jzEwFUya7lgvoBwZd+og7sXvKA+PdO4Y6gI35WNn34yYf9N1p3eNdyWe X-Received: by 10.13.207.68 with SMTP id r65mr13975792ywd.227.1515501097330; Tue, 09 Jan 2018 04:31:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501097; cv=none; d=google.com; s=arc-20160816; b=ki30lS6I2aHmwSqMpxm0j7ovqo0Cv7olR1Dg5bgJpeWIA676al5v/6V6EYqhG38cP1 fUb2HluLIlhSuIqSJSyT6KcB7GP+wKDPg6IDYtmql7MfQ4Ymkii7dWpn9/2Q+hoYOUxP LepVjv3UgmH9gWqlXO+yide8Pn5DX9S6jOjeSNhRHUYiRJ4h4CwPuHApcqJaKrgw3M+0 RhPxN/87hrF+WovSk33QFq77lT3BzEHDVyienEQIaMprmEnQOX71ZKKKPtdw26aq7trO Ebt5sMbGWdj29Cc2qiQm+UlA/Pp0kfURuC6R6iHCQ5kL6MXizO2tCXzvEMWh9hRumh8T PI3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=X4rnVqpYCQie3dztzQP9kk+QOx2KcVI9sLNxrrbidZk=; b=YL0VLcYTjxbh+3xrV6vwaCBoQQs9uXKQVx88KKVcJvnBmk9XvaLkO3wYaBCEBMfEfR EG//uRsQl4x8SmJVThaP7/vQxkiNiPvnMSu4GReBN1wmcyK3ne1DRovNajVTTJAn7ss0 LMKlO8Jutuk3w9ni6B1c10gFPwckl3dU+ji5vCXXrWxFwLWCXPebafBJQFyqIIksQHBO pwLTxoVgBGKgf2pjgforhuHdDUgrjoxaAVFmfBHy23Cu3caylBl86CespzO5C2c99kKk awDIcCro8Jnub85ZYpZ/FJ+4MfO9SBsbSYfs0zPc8ek5e8uQGDVK+eYr70fTgqeQ0Mvc ia5g== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=G2Jm8m7N; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id 130si3062539ybc.161.2018.01.09.04.31.37 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:31:37 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=G2Jm8m7N; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49526 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt44-0003xF-Ne for patch@linaro.org; Tue, 09 Jan 2018 07:31:36 -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) 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-Received: by 10.28.19.210 with SMTP id 201mr10762569wmt.4.1515500907923; 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 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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Let's do the same re-factor treatment for minmax functions. I still use the MACRO trick to expand but now all the checking code is common. Signed-off-by: Alex Bennée --- v2 - minor indentation fix --- fpu/softfloat.c | 239 ++++++++++++++++++++++++++---------------------- include/fpu/softfloat.h | 6 ++ 2 files changed, 134 insertions(+), 111 deletions(-) -- 2.15.1 Reviewed-by: Richard Henderson 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); } +/* Float Min/Max */ +/* min() and max() functions. These can't be implemented as + * 'compare and pick one input' because that would mishandle + * NaNs and +0 vs -0. + * + * minnum() and maxnum() functions. These are similar to the min() + * and max() functions but if one of the arguments is a QNaN and + * the other is numerical then the numerical argument is returned. + * SNaNs will get quietened before being returned. + * minnum() and maxnum correspond to the IEEE 754-2008 minNum() + * and maxNum() operations. min() and max() are the typical min/max + * semantics provided by many CPUs which predate that specification. + * + * minnummag() and maxnummag() functions correspond to minNumMag() + * and minNumMag() from the IEEE-754 2008. + */ +static decomposed_parts minmax_decomposed(decomposed_parts a, + decomposed_parts b, + bool ismin, bool ieee, bool ismag, + float_status *s) +{ + if (a.cls >= float_class_qnan + || + b.cls >= float_class_qnan) + { + if (ieee) { + /* Takes two floating-point values `a' and `b', one of + * which is a NaN, and returns the appropriate NaN + * result. If either `a' or `b' is a signaling NaN, + * the invalid exception is raised. + */ + if (a.cls == float_class_snan || b.cls == float_class_snan) { + return pick_nan_parts(a, b, s); + } else if (a.cls >= float_class_qnan + && + b.cls < float_class_qnan) { + return b; + } else if (b.cls >= float_class_qnan + && + a.cls < float_class_qnan) { + return a; + } + } + return pick_nan_parts(a, b, s); + } else { + int a_exp, b_exp; + bool a_sign, b_sign; + + switch (a.cls) { + case float_class_normal: + a_exp = a.exp; + break; + case float_class_inf: + a_exp = INT_MAX; + break; + case float_class_zero: + a_exp = INT_MIN; + break; + default: + g_assert_not_reached(); + break; + } + switch (b.cls) { + case float_class_normal: + b_exp = b.exp; + break; + case float_class_inf: + b_exp = INT_MAX; + break; + case float_class_zero: + b_exp = INT_MIN; + break; + default: + g_assert_not_reached(); + break; + } + + a_sign = a.sign; + b_sign = b.sign; + if (ismag) { + a_sign = b_sign = 0; + } + + if (a_sign == b_sign) { + bool a_less = a_exp < b_exp; + if (a_exp == b_exp) { + a_less = 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_status *s) \ +{ \ + decomposed_parts pa = float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb = float ## sz ## _unpack_canonical(b, s); \ + decomposed_parts pr = minmax_decomposed(pa, pb, ismin, isiee, ismag, s); \ + \ + return float ## sz ## _round_pack_canonical(pr, s); \ +} + +MINMAX(16, min, true, false, false) +MINMAX(16, minnum, true, true, false) +MINMAX(16, minnummag, true, true, true) +MINMAX(16, max, false, false, false) +MINMAX(16, maxnum, false, true, false) +MINMAX(16, maxnummag, false, true, true) + +MINMAX(32, min, true, false, false) +MINMAX(32, minnum, true, true, false) +MINMAX(32, minnummag, true, true, true) +MINMAX(32, max, false, false, false) +MINMAX(32, maxnum, false, true, false) +MINMAX(32, maxnummag, false, true, true) + +MINMAX(64, min, true, false, false) +MINMAX(64, minnum, true, true, false) +MINMAX(64, minnummag, true, true, true) +MINMAX(64, max, false, false, false) +MINMAX(64, maxnum, false, true, false) +MINMAX(64, maxnummag, false, true, true) + +#undef MINMAX + /* Multiply A by 2 raised to the power N. */ static decomposed_parts scalbn_decomposed(decomposed_parts a, int n, float_status *s) @@ -6912,117 +7040,6 @@ int float128_compare_quiet(float128 a, float128 b, float_status *status) return float128_compare_internal(a, b, 1, status); } -/* min() and max() functions. These can't be implemented as - * 'compare and pick one input' because that would mishandle - * NaNs and +0 vs -0. - * - * minnum() and maxnum() functions. These are similar to the min() - * and max() functions but if one of the arguments is a QNaN and - * the other is numerical then the numerical argument is returned. - * SNaNs will get quietened before being returned. - * minnum() and maxnum correspond to the IEEE 754-2008 minNum() - * and maxNum() operations. min() and max() are the typical min/max - * semantics provided by many CPUs which predate that specification. - * - * minnummag() and maxnummag() functions correspond to minNumMag() - * and minNumMag() from the IEEE-754 2008. - */ -#define MINMAX(s) \ -static inline float ## s float ## s ## _minmax(float ## s a, float ## s b, \ - int ismin, int isieee, \ - int ismag, \ - float_status *status) \ -{ \ - flag aSign, bSign; \ - uint ## s ## _t av, bv, aav, abv; \ - a = float ## s ## _squash_input_denormal(a, status); \ - b = float ## s ## _squash_input_denormal(b, status); \ - if (float ## s ## _is_any_nan(a) || \ - float ## s ## _is_any_nan(b)) { \ - if (isieee) { \ - if (float ## s ## _is_signaling_nan(a, status) || \ - float ## s ## _is_signaling_nan(b, status)) { \ - return propagateFloat ## s ## NaN(a, b, status); \ - } else if (float ## s ## _is_quiet_nan(a, status) && \ - !float ## s ##_is_any_nan(b)) { \ - return b; \ - } else if (float ## s ## _is_quiet_nan(b, status) && \ - !float ## s ## _is_any_nan(a)) { \ - return a; \ - } \ - } \ - return propagateFloat ## s ## NaN(a, b, status); \ - } \ - aSign = extractFloat ## s ## Sign(a); \ - bSign = extractFloat ## s ## Sign(b); \ - av = float ## s ## _val(a); \ - bv = float ## s ## _val(b); \ - if (ismag) { \ - aav = float ## s ## _abs(av); \ - abv = float ## s ## _abs(bv); \ - if (aav != abv) { \ - if (ismin) { \ - return (aav < abv) ? a : b; \ - } else { \ - return (aav < abv) ? b : a; \ - } \ - } \ - } \ - if (aSign != bSign) { \ - if (ismin) { \ - return aSign ? a : b; \ - } else { \ - return aSign ? b : a; \ - } \ - } else { \ - if (ismin) { \ - return (aSign ^ (av < bv)) ? a : b; \ - } else { \ - return (aSign ^ (av < bv)) ? b : a; \ - } \ - } \ -} \ - \ -float ## s float ## s ## _min(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 1, 0, 0, status); \ -} \ - \ -float ## s float ## s ## _max(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 0, 0, 0, status); \ -} \ - \ -float ## s float ## s ## _minnum(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 1, 1, 0, status); \ -} \ - \ -float ## s float ## s ## _maxnum(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 0, 1, 0, status); \ -} \ - \ -float ## s float ## s ## _minnummag(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 1, 1, 1, status); \ -} \ - \ -float ## s float ## s ## _maxnummag(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _minmax(a, b, 0, 1, 1, status); \ -} - -MINMAX(32) -MINMAX(64) - - floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status) { flag aSign; diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 41338184d5..c948727bbb 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -327,6 +327,12 @@ float16 float16_mul(float16, float16, float_status *status); float16 float16_muladd(float16, float16, float16, int, float_status *status); float16 float16_div(float16, float16, float_status *status); float16 float16_scalbn(float16, int, float_status *status); +float16 float16_min(float16, float16, float_status *status); +float16 float16_max(float16, float16, float_status *status); +float16 float16_minnum(float16, float16, float_status *status); +float16 float16_maxnum(float16, float16, float_status *status); +float16 float16_minnummag(float16, float16, float_status *status); +float16 float16_maxnummag(float16, float16, float_status *status); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status); From patchwork Tue Jan 9 12:22:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 123918 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3967826qgn; Tue, 9 Jan 2018 04:35:24 -0800 (PST) X-Google-Smtp-Source: ACJfBotxKTcgI6Ppk2uFWGQbWL+CUWDZdvdVs9FYWiMIGRlSQxnMa5dVfE78kq9AhSP2+oUONobo X-Received: by 10.129.173.71 with SMTP id l7mr3529198ywk.229.1515501324589; Tue, 09 Jan 2018 04:35:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515501324; cv=none; d=google.com; s=arc-20160816; b=BJLTob0iirt23RgBQl3SsZGB7xQdJtEoHsWmP1p9B4htaTAMNgZFOqiGAMuJIiK46/ OYNJ/12Dx/f+ZAwQcBwliBNBFELa5M0l/RPruHmgWKx3gq2zNxNcpLRV+4r0dIZmHAYH C65LMGRAHwF0Qn1jx2G8VJOU6Sx48nAO0ueQ+4YFsUKQqGxrZpn2Ddv6bVPbrMmuU4cR dD/9X6wFbLqBkbW5ZfyXtW1jYtiaHNIE4zWQD44WlxIToGpJpoFC91KWsJ1cu6TnDcJ/ x5XMw8+Y65wRg6CUfiUesK//WYIznd4yGr9UTq+z+wUs/v3asaYUze3jo9G+xc673HcR HRbA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=9EVuYq8Svz+r+ohBrFBZAJHxebiz/Vagrbylnmdb36U=; b=cG9KDcxQ6+0RBUNJzdEyCEn3fHxXu0rGfKLxooBKrEX+YBmGn1lFZV8gJsAFIED74K 945mUXstzOmkQTWMACD0/Gpdqs5QNQ2mDLBJ5/ZR1p9+uHDBNGYWGfE9qZY3YM8vEsQO F24JtM+QtO9fasoTNzaKD+Z4joMJwFXTPKWeK55oG70sNoqlYt4JAIahW+ymGRspQElN 2REJ1D/LilHNoSdv0wTXdUwTeXkU0xyW+O0AgGXL7nWJEt7dNJ/pVjMqUVUuSKvV/qa9 gosCd+EjahWU3LRO/g9q0/U/dKi6l1nkz6OavGEiq1N7cDgqmSXZVmkepx/fAHqB1Uoi h6Sw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=a7aH0Ox0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id 141si956977ybe.589.2018.01.09.04.35.24 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 09 Jan 2018 04:35:24 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=a7aH0Ox0; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:49554 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eYt7k-0007we-0f for patch@linaro.org; Tue, 09 Jan 2018 07:35:24 -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) 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-Received: by 10.28.212.72 with SMTP id l69mr11050418wmg.66.1515500909840; Tue, 09 Jan 2018 04:28:29 -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) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: richard.henderson@linaro.org, peter.maydell@linaro.org, laurent@vivier.eu, bharata@linux.vnet.ibm.com, andrew@andrewdutcher.com 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 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_Benn=C3=A9e?= , qemu-devel@nongnu.org, Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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ée --- v2 - minor re-factor for better inf handling --- fpu/softfloat.c | 134 +++++++++++++++++++++++++++++------------------- include/fpu/softfloat.h | 2 + 2 files changed, 82 insertions(+), 54 deletions(-) -- 2.15.1 Reviewed-by: Richard Henderson 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) #undef MINMAX +/* Floating point compare */ +static int compare_decomposed(decomposed_parts a, decomposed_parts b, + bool is_quiet, float_status *s) +{ + if (a.cls >= float_class_qnan + || + b.cls >= float_class_qnan) { + if (!is_quiet || + a.cls == float_class_snan || + b.cls == float_class_snan) { + s->float_exception_flags |= float_flag_invalid; + } + return float_relation_unordered; + } + + if (a.cls == float_class_zero) { + if (b.cls == float_class_zero) { + return float_relation_equal; + } + return b.sign ? float_relation_greater : float_relation_less; + } else if (b.cls == 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 == float_class_inf) { + if ((b.cls == float_class_inf) && (a.sign == b.sign)) { + return float_relation_equal; + } + return a.sign ? float_relation_less : float_relation_greater; + } else if (b.cls == float_class_inf) { + return b.sign ? float_relation_greater : float_relation_less; + } + + if (a.sign != b.sign) { + return a.sign ? float_relation_less : float_relation_greater; + } + + if (a.exp == b.exp) { + if (a.frac == b.frac) { + return float_relation_equal; + } + if (a.sign) { + return a.frac > b.frac ? + float_relation_less : float_relation_greater; + } else { + return a.frac > b.frac ? + float_relation_greater : float_relation_less; + } + } else { + if (a.sign) { + return a.exp > b.exp ? float_relation_less : float_relation_greater; + } else { + return a.exp > b.exp ? float_relation_greater : float_relation_less; + } + } +} + +#define COMPARE(sz) \ +int float ## sz ## _compare(float ## sz a, float ## sz b, float_status *s) \ +{ \ + decomposed_parts pa = float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb = float ## sz ## _unpack_canonical(b, s); \ + return compare_decomposed(pa, pb, false, s); \ +} \ +int float ## sz ## _compare_quiet(float ## sz a, float ## sz b, float_status *s) \ +{ \ + decomposed_parts pa = float ## sz ## _unpack_canonical(a, s); \ + decomposed_parts pb = float ## sz ## _unpack_canonical(b, s); \ + return compare_decomposed(pa, pb, true, s); \ +} + +COMPARE(16) +COMPARE(32) +COMPARE(64) + +#undef COMPARE + /* Multiply A by 2 raised to the power N. */ static decomposed_parts scalbn_decomposed(decomposed_parts a, int n, float_status *s) @@ -6892,60 +6972,6 @@ int float128_unordered_quiet(float128 a, float128 b, float_status *status) return 0; } -#define COMPARE(s, nan_exp) \ -static inline int float ## s ## _compare_internal(float ## s a, float ## s b,\ - int is_quiet, float_status *status) \ -{ \ - flag aSign, bSign; \ - uint ## s ## _t av, bv; \ - a = float ## s ## _squash_input_denormal(a, status); \ - b = float ## s ## _squash_input_denormal(b, status); \ - \ - if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) && \ - extractFloat ## s ## Frac( a ) ) || \ - ( ( extractFloat ## s ## Exp( b ) == nan_exp ) && \ - extractFloat ## s ## Frac( b ) )) { \ - if (!is_quiet || \ - float ## s ## _is_signaling_nan(a, status) || \ - float ## s ## _is_signaling_nan(b, status)) { \ - float_raise(float_flag_invalid, status); \ - } \ - return float_relation_unordered; \ - } \ - aSign = extractFloat ## s ## Sign( a ); \ - bSign = extractFloat ## s ## Sign( b ); \ - av = float ## s ## _val(a); \ - bv = float ## s ## _val(b); \ - if ( aSign != bSign ) { \ - if ( (uint ## s ## _t) ( ( av | bv )<<1 ) == 0 ) { \ - /* zero case */ \ - return float_relation_equal; \ - } else { \ - return 1 - (2 * aSign); \ - } \ - } else { \ - if (av == bv) { \ - return float_relation_equal; \ - } else { \ - return 1 - 2 * (aSign ^ ( av < bv )); \ - } \ - } \ -} \ - \ -int float ## s ## _compare(float ## s a, float ## s b, float_status *status) \ -{ \ - return float ## s ## _compare_internal(a, b, 0, status); \ -} \ - \ -int float ## s ## _compare_quiet(float ## s a, float ## s b, \ - float_status *status) \ -{ \ - return float ## s ## _compare_internal(a, b, 1, status); \ -} - -COMPARE(32, 0xff) -COMPARE(64, 0x7ff) - static inline int floatx80_compare_internal(floatx80 a, floatx80 b, int is_quiet, float_status *status) { diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 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); int float16_is_quiet_nan(float16, float_status *status); int float16_is_signaling_nan(float16, float_status *status);