From patchwork Tue Feb 6 16:47:54 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: 127024 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3087096ljc; Tue, 6 Feb 2018 08:48:53 -0800 (PST) X-Google-Smtp-Source: AH8x2260nHlyGt2mOaizZsszPa8IsTgNik3OYv1gEWpOR+nIQqczGiivs86u5NBpjQqakmAxJLX0 X-Received: by 10.37.132.5 with SMTP id u5mr2067862ybk.138.1517935733089; Tue, 06 Feb 2018 08:48:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517935733; cv=none; d=google.com; s=arc-20160816; b=n+SBYhFIw8hbhq8ZRvfLuqYtPaOXFqHOP8zzp/IpuKyVbSt7girgFZaaBVfRurMPfc +mNYAcOp0Ruy/kufKAWqDRxR/x+2If4eUvYR+13KOzTP5J0vM63+by1LeRE5Knv9/HcP 73hL3GLKotEP91uiVwZIJiaZlqq/t4Icj2GCwJe+PqM1FiUKvcuwDmeatI6v624jE8BO QD9SPuwmvXp4jiktKVuehUc412Ir0IR3cPZKTGkgUVyiYr3lVMwoknceBsqqTI302eD4 nhOTUsArhEtQx8nO2mZ9P0/7RvLTXQB6WQvWHeYA2iurn0zrl22Nq3n4mZSGRZvsPzjE aWNQ== 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=h31NeeUXL9yU7R2Yb4mynZARITWdaJeJqTMLzgQtKsM=; b=Q/zbpXbHrhj11IhbKrE7Tqt0iWPzpcmwApMgVVlYPApaXobXN1jXemw2raddjCo91v zsmlluKmkxE4o9uQTOGK+D/FWSZ/sV9a0oCR/TN0pdGhghIwEU5prStPCijRT+hKLeaN dfql8JMo/UIWN/k5vdliu7vPijXA432OGDBe4psMu2LG3ww08HhYJtFdW8vh0A9De+f4 rBDC+XrX6El55npXIPglwKJjXWCmLkpLCuGTsA5Dtg4jCFCGlv6C2qKbGQut7Cb9Fo3Y QSHR8tdExuK/SqJu6SYmYo8TBL0QAxfsESFxlmfdg7/HUReafEzMAAxy1biaVyfyZ0Tn jl9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=UBW3sjxX; 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 o17si1300654ybm.292.2018.02.06.08.48.52 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:48:53 -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=UBW3sjxX; 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]:37432 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6QO-0000Ty-EG for patch@linaro.org; Tue, 06 Feb 2018 11:48:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33392) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Pu-0000T7-5b for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Pq-0004fE-Ol for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:22 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:41050) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Pq-0004dQ-IY for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:18 -0500 Received: by mail-wr0-x242.google.com with SMTP id v15so2649510wrb.8 for ; Tue, 06 Feb 2018 08:48:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=h31NeeUXL9yU7R2Yb4mynZARITWdaJeJqTMLzgQtKsM=; b=UBW3sjxXiaaaSup07qEIjhv3D24YUUTp1qMVT6dWyOK8yMxuAvrRpPriPaPkN7/QIR F8c3ptyo9zA0G/Butz/BuTuUSlI7O9YvjGIZt8ZnsJlWrqgd+4+B7kdvNdxkFSEMC+IK mehiytcGxrYWr3DIq7RuE7SBRQ87dSN5gTdcI= 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=h31NeeUXL9yU7R2Yb4mynZARITWdaJeJqTMLzgQtKsM=; b=syKM9/LJm3qSrTPYdHikAJCRHHyJ2zbEM3B9/nLemCB7IezhwGCpJCMM5pdnQ1Ztbv XGtFbtW5+uIAd9wiIQF8gkY3NzqjqeO1k8Cn3KtOXZvOkChyZJ7ROmjjBVUvzCPTicxk aUcwwuMAW4tacjsNqA44T7PrlKvg/MBvsn7TXThS4YSwEat06NTvkuZw/tv6vTG7GHhB 7sFgTY8OO3VAkKcfh8m2zGqPsq0/ASMH2q3+LpNRIFJD3sEyhe5h1xvncCDAZn4p8NVM QQG9kZM+urGJH2Y2B9Am8CjOf8xoWs4kWvvroMFjqJmZAGpQBAY0msnQiHZqyaPdN6nA LZRA== X-Gm-Message-State: APf1xPCS7wbCeG73bhE3Ohf2IZ37+ortmu/zG7dKjn1+eyHEOg8XQnOP WRnGx4ISpN47v+AEvJanMglsXA== X-Received: by 10.223.163.207 with SMTP id m15mr2968527wrb.174.1517935697375; Tue, 06 Feb 2018 08:48:17 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id k3sm23125266wmk.3.2018.02.06.08.48.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:16 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 2DC043E025C; Tue, 6 Feb 2018 16:48:15 +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, 6 Feb 2018 16:47:54 +0000 Message-Id: <20180206164815.10084-2-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 01/22] 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 Reviewed-by: Peter Maydell --- fpu/softfloat.c | 15 +++++++++++++++ include/fpu/softfloat.h | 1 + 2 files changed, 16 insertions(+) -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 433c5dad2d..3a4ab1355f 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -3488,6 +3488,21 @@ static float16 roundAndPackFloat16(flag zSign, int zExp, return packFloat16(zSign, zExp, zSig >> 13); } +/*---------------------------------------------------------------------------- +| If `a' is denormal and we are in flush-to-zero mode then set the +| input-denormal exception and return zero. Otherwise just return the value. +*----------------------------------------------------------------------------*/ +float16 float16_squash_input_denormal(float16 a, float_status *status) +{ + if (status->flush_inputs_to_zero) { + if (extractFloat16Exp(a) == 0 && extractFloat16Frac(a) != 0) { + float_raise(float_flag_input_denormal, status); + return make_float16(float16_val(a) & 0x8000); + } + } + return a; +} + static void normalizeFloat16Subnormal(uint32_t aSig, int *zExpPtr, uint32_t *zSigPtr) { diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 0f96a0edd1..d5e99667b6 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -277,6 +277,7 @@ void float_raise(uint8_t flags, float_status *status); | If `a' is denormal and we are in flush-to-zero mode then set the | input-denormal exception and return zero. Otherwise just return the value. *----------------------------------------------------------------------------*/ +float16 float16_squash_input_denormal(float16 a, float_status *status); float32 float32_squash_input_denormal(float32 a, float_status *status); float64 float64_squash_input_denormal(float64 a, float_status *status); From patchwork Tue Feb 6 16:47:55 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: 127031 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3091853ljc; Tue, 6 Feb 2018 08:54:30 -0800 (PST) X-Google-Smtp-Source: AH8x225y5Yf9ixXVy4vta8cwcwvFQU9j8qHECv1915N5FDw6zcs5vSiite+xRApKs14fZ4kdEQJX X-Received: by 10.37.244.70 with SMTP id p6mr1883579ybe.279.1517936070735; Tue, 06 Feb 2018 08:54:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936070; cv=none; d=google.com; s=arc-20160816; b=YV62I5UXZsbreuKJoZqZJyS02xLjpFNlRWn6zSc7OsFY08CCd0wOWwKUORgzTwBS/9 rzMDKyDikxFHjeUzIPtyeTZPaf0qAx+187JdVUWUHHjEbGPJdW4pk59hwgemS2GctrR7 rE/a/1co/8jXDxX5iWOIo/A1bnDLgzcZH6tWDLK91W37KfShtU8bOPRFyZ3Y/RiapbLG eNrLXip8JMM/FhGBza9PGV3F73qbGdHOHLtseEW+7UvSwXhJY0xXGjui+QdYHmnk87Go 5QsM3BE5dxp45xbEI8PA0X8pn+o+MeQwn8KCKKvoSUFrpTDPJTrZ+v30GCaXYMk1h+Mx kIBQ== 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=BAFRdaYLrQzoTHM/D56Ivrx3doxZ9W9pIAbUfGIwFy4=; b=WWHKruFef+6HNJlvi/k3g7fPAIFvBQfBOcKnfIRDWmbFczI58wb9JL946FUFcw/AJF 1CqZS/6PPRAT4/T6gbvw7b8n9Ub9F665CfNrvpqb2YxFawtolODprpPb/khsH7qENq62 tB8tWT5QVG6baBwpxv4QK5FGAsKhJ9NPGphd4GmTsFnU3D/cUNZHZGxZzejlD+YBRq4y gdIaggr1wVHTplPuHUl9qy0HUy1mtbVHlCieTXNgCcO9c9LJ0mGO+1j2beh9rKqVNZUe IaZkRXDhus9ojNrXYRSlIAwHP6l4qV23n40uM/gE1OwiRSD/qmRWfFy5HpUkxhskOeU8 uUzg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=WQywmFVM; 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 e92si25981ybi.401.2018.02.06.08.54.30 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:54: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=WQywmFVM; 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]:37476 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Vq-0004sb-2i for patch@linaro.org; Tue, 06 Feb 2018 11:54:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33390) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Pu-0000T5-50 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Ps-0004hi-4i for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:22 -0500 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:55163) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Pr-0004g3-UG for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:20 -0500 Received: by mail-wm0-x244.google.com with SMTP id i186so4987193wmi.4 for ; Tue, 06 Feb 2018 08:48:19 -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=BAFRdaYLrQzoTHM/D56Ivrx3doxZ9W9pIAbUfGIwFy4=; b=WQywmFVMtMeYVZDpgBQ8fAyw1Ex0TGldi35YeCRUq491n0Mo6/tgY7dIMRykyvvWTj cgyK47YfI7SErenlw6zRs6qmGweLI7taNX1d57dmu28k+xkXeMcKlnSR3JcxJAg03VX3 qs3v7FrMm2TFfdBjz70lydjQyCN6QNvtwbgU0= 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=BAFRdaYLrQzoTHM/D56Ivrx3doxZ9W9pIAbUfGIwFy4=; b=PUsE/GgDzYK6fSpYXFVZZ7nNJ2vPuxOkLjzCS3VomjmOHzdIobFPM1zFA7tmv9xpvz NM29Aoh9LDvTkM0/8TrhyqstpT2de9m9DUnLQ+lqFoMw2ZwlgjpKKbPxV1jGaNqbr4n8 BcQkYNS9e50/zAj3ivZnq6o9pHvyB253RlSd8+YGRdLgoyC6CUqA52Nz1KuHaMJ6iDC8 aErmfuUgY3LNOvE7gNttB1390YlCP+gX32gJy2ciVpPshnmQQIMusc7gnFjhHC7886Nm k+dcjJ4sPN6a1FdxFZUt3/tP0hP3bUM2ufh7iklDLRpD67pgiOdzVKilO2FjXPRs6Qqj OR5w== X-Gm-Message-State: APf1xPCjkco8aflq+amBp3FycbMLv3WZE1sHWOGDegqQpN9TOq7cQuIS SiCzL3KX1pEuC9MykBpwwph13g== X-Received: by 10.28.88.129 with SMTP id m123mr2366811wmb.64.1517935698666; Tue, 06 Feb 2018 08:48:18 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id r188sm10454338wmb.40.2018.02.06.08.48.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:16 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 3F4833E027B; Tue, 6 Feb 2018 16:48:15 +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, 6 Feb 2018 16:47:55 +0000 Message-Id: <20180206164815.10084-3-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 02/22] 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 Reviewed-by: Richard Henderson --- 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 Feb 6 16:47:56 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: 127025 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3087147ljc; Tue, 6 Feb 2018 08:48:57 -0800 (PST) X-Google-Smtp-Source: AH8x226GUoO+LSqlbL1FOUocmFBkO9/EJihpRkWiJ5+IK8rP0Lcr9MRG6PSHXTY6BWhPPqH+lWoj X-Received: by 10.37.162.135 with SMTP id c7mr1960114ybi.247.1517935737777; Tue, 06 Feb 2018 08:48:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517935737; cv=none; d=google.com; s=arc-20160816; b=x03sYdqiyH4/TQPZXOMwmxoPDIXq4NwDqy0HMglcGunzmBcmTb/mN7e5/c1aYcXFUm jCMhd0zgays25bUO2g6ZhGiZkPuDxU8wghT70JAsbQw6HQnOCb31iAaPB00YrSdWODHf WuaRQ8B6Anmz33yzmS8gH9GrfUAT1UT3M5CF0S/gYLPFwr0cRNXIqMVHR7iS9+OAPJgE utX4ZIL4DVDaNYlJY4XC+me4rxzU2fVXfeJT75r00xW2AbCj4lZS3trPrayJt7jEeBUX dHjBNNviYqTbfiwxEIt4oUKy6GOOF4Z69nKRZ378UVcPwMPu6kT8mcuV3zCvnUE1/O18 b9sw== 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=b8BgNJT3hHBvrBVeYE+kzxGeZV6BI607e0AjKLb6He8=; b=OSap5uo8WuXryMiP1pHJKiopoBWdqV8SPfswLRr6Npsu9A47QS8jJCALQkCo2W/bcU 6Uce+2LVMkD4F5tWmh968zLdlIPbNjSCxBqG2CeHev/Q40pZAC3UaB9EG5XSRbHzOBfR 2EYQWhkj7Zn4jHtUsjx6u/VB8qNJjfEKXFzvsFQ29q//2sgeGUbpFfli4B3UpPK6SF9Y 5HGNJ2KiujMETqwOy4sbV3Z2WAsYqHF6VzwdnQuamzVXK/3ABtD8p+qKosbrnL/gGuBK 9Y9a61dSMgLZM5q5GNdPKL2+QA3SRKhBLlmw4/tCl6ksX+es6zV/Tg6tG9idA8V2ENDS 3s+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=TMXJ3f2e; 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 l8si30705ywk.149.2018.02.06.08.48.57 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:48:57 -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=TMXJ3f2e; 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]:37437 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6QT-0000Vv-3K for patch@linaro.org; Tue, 06 Feb 2018 11:48:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33406) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Pu-0000TQ-Oa for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Pt-0004jS-7d for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:22 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:39094) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Ps-0004hw-Tw for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:21 -0500 Received: by mail-wr0-x241.google.com with SMTP id f6so2648280wra.6 for ; Tue, 06 Feb 2018 08:48:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=b8BgNJT3hHBvrBVeYE+kzxGeZV6BI607e0AjKLb6He8=; b=TMXJ3f2eGVcgejbDQV8w87hcnALpeDrAGNjaaeOzlkNC7Jqf41IvfeOe63E6VkPxQ0 G++kFpZd2SAD+piUtpwUPS9u/UrKx8dj2TZrqZ5Z1c5Cm8bXsFZXqPk53pFuCEbijufy gSPLZHB0TTS83grvJtONERds7u/yNpbDHpHj4= 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=b8BgNJT3hHBvrBVeYE+kzxGeZV6BI607e0AjKLb6He8=; b=EjlA1KolqIgvzlJeq5vYgDWYajTshc+tqmibqVZk39rBeM/HsLAlkhUHHBrlXhUnJq OEzLRWNk/jugBC1/pRLvztZJ+kvhQu6Z/6V3DITKi1+9sRvr5V7B6nKraQAQ9d9Xocch 00RzqldDKY7FmlXNW+rKCjhT/a3qttzMb/X9mYIGXKUekZwEQs8t6SK8dITpjk7K1HdS BCVJsubjJzEmsZhzPVzzf/bxUQkj2sv30VTghi/idgZzqj6CDuBY9Og+zoZsIBdozaLO BisQeUtoulLU9HwWoWsVD5bJTObTJeXBvXGL2y98HYFr0i/FnWgWAHnxJbOriQvDcj8+ d5Uw== X-Gm-Message-State: APf1xPBd1ToWqV2EROTcwgvVCuuoxknuCAM1LC3XOHSUNKMjm+plOEbl +7vsK0e2PgM4CToEkkYNrIhCag== X-Received: by 10.223.152.130 with SMTP id w2mr2868978wrb.12.1517935699637; Tue, 06 Feb 2018 08:48:19 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id u79sm16532383wma.10.2018.02.06.08.48.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:16 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 5336F3E0576; Tue, 6 Feb 2018 16:48:15 +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, 6 Feb 2018 16:47:56 +0000 Message-Id: <20180206164815.10084-4-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 03/22] fpu/softfloat-types: new header to prevent excessive re-builds 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 main culprit here is bswap.h which pulled in softfloat.h so it could use the types in its CPU_Float* and ldfl/stfql functions. As bswap.h is very widely included this added a compile dependency every time we touch softfloat.h. Move the typedefs for each float type into their own file so we don't re-build the world every time we tweak the main softfloat.h header. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- v3 - new in v3 --- include/fpu/softfloat-types.h | 115 ++++++++++++++++++++++++++++++++++++++++++ include/fpu/softfloat.h | 31 +----------- include/qemu/bswap.h | 2 +- 3 files changed, 117 insertions(+), 31 deletions(-) create mode 100644 include/fpu/softfloat-types.h -- 2.15.1 diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h new file mode 100644 index 0000000000..8210a94ea1 --- /dev/null +++ b/include/fpu/softfloat-types.h @@ -0,0 +1,115 @@ +/* + * QEMU float support + * + * The code in this source file is derived from release 2a of the SoftFloat + * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and + * some later contributions) are provided under that license, as detailed below. + * It has subsequently been modified by contributors to the QEMU Project, + * so some portions are provided under: + * the SoftFloat-2a license + * the BSD license + * GPL-v2-or-later + * + * This header holds definitions for code that might be dealing with + * softfloat types but not need access to the actual library functions. + */ +/* +=============================================================================== +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* BSD licensing: + * Copyright (c) 2006, Fabrice Bellard + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Portions of this work are licensed under the terms of the GNU GPL, + * version 2 or later. See the COPYING file in the top-level directory. + */ + +#ifndef SOFTFLOAT_TYPES_H +#define SOFTFLOAT_TYPES_H + +/* + * Software IEC/IEEE floating-point types. + */ + +typedef uint16_t float16; +typedef uint32_t float32; +typedef uint64_t float64; +#define float16_val(x) (x) +#define float32_val(x) (x) +#define float64_val(x) (x) +#define make_float16(x) (x) +#define make_float32(x) (x) +#define make_float64(x) (x) +#define const_float16(x) (x) +#define const_float32(x) (x) +#define const_float64(x) (x) +typedef struct { + uint64_t low; + uint16_t high; +} floatx80; +#define make_floatx80(exp, mant) ((floatx80) { mant, exp }) +#define make_floatx80_init(exp, mant) { .low = mant, .high = exp } +typedef struct { +#ifdef HOST_WORDS_BIGENDIAN + uint64_t high, low; +#else + uint64_t low, high; +#endif +} float128; +#define make_float128(high_, low_) ((float128) { .high = high_, .low = low_ }) +#define make_float128_init(high_, low_) { .high = high_, .low = low_ } + +#endif /* SOFTFLOAT_TYPES_H */ diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 52af1412de..4e16e22e58 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -100,36 +100,7 @@ enum { float_relation_unordered = 2 }; -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point types. -*----------------------------------------------------------------------------*/ -typedef uint16_t float16; -typedef uint32_t float32; -typedef uint64_t float64; -#define float16_val(x) (x) -#define float32_val(x) (x) -#define float64_val(x) (x) -#define make_float16(x) (x) -#define make_float32(x) (x) -#define make_float64(x) (x) -#define const_float16(x) (x) -#define const_float32(x) (x) -#define const_float64(x) (x) -typedef struct { - uint64_t low; - uint16_t high; -} floatx80; -#define make_floatx80(exp, mant) ((floatx80) { mant, exp }) -#define make_floatx80_init(exp, mant) { .low = mant, .high = exp } -typedef struct { -#ifdef HOST_WORDS_BIGENDIAN - uint64_t high, low; -#else - uint64_t low, high; -#endif -} float128; -#define make_float128(high_, low_) ((float128) { .high = high_, .low = low_ }) -#define make_float128_init(high_, low_) { .high = high_, .low = low_ } +#include "fpu/softfloat-types.h" /*---------------------------------------------------------------------------- | Software IEC/IEEE floating-point underflow tininess-detection mode. diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h index 09c78fd28a..3f28f661b1 100644 --- a/include/qemu/bswap.h +++ b/include/qemu/bswap.h @@ -1,7 +1,7 @@ #ifndef BSWAP_H #define BSWAP_H -#include "fpu/softfloat.h" +#include "fpu/softfloat-types.h" #ifdef CONFIG_MACHINE_BSWAP_H # include From patchwork Tue Feb 6 16:47:57 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: 127032 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3092397ljc; Tue, 6 Feb 2018 08:55:10 -0800 (PST) X-Google-Smtp-Source: AH8x225H608mCkwQ7PCc0bza0YxmK4SfMRcQI6Jz06eT9pnDeqy3EN5dLVd21l7XqWIdWtxfyS1P X-Received: by 10.129.85.4 with SMTP id j4mr1777115ywb.459.1517936110820; Tue, 06 Feb 2018 08:55:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936110; cv=none; d=google.com; s=arc-20160816; b=0eSJpIMRF+EVzN7rl4cbymNTaQE+WtpR1Sj4vOtj5VHcaQVB32b+oGjhns66YK50/J /uXSOxlGa6/LoHmrNwn+Dh53LxSI2YvB3spumlLN0TQS1o70Q+40469GKqgDHZyagzYP 2agqCUw2Spvtnv1xQ1ZbCJFuKxeJyrYtCVSWNloXG2VfXjmadxEgPEteq6Oz9ifF0k+x CtsqvOWfLsalJg+nhlpa9LfMfERcVSvVM4su7Hrw8c1Q2+ufpiInRy1CDjtxYG2Pjyzh xMiqNqCa99ndO+6ehQhd5UIayMfBimXyEOuzG5/5hCxEa9WpWVmxMCETU3u7Ur+f+YO9 B7ng== 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=Gw4DnmmBoFPfPC9NmXjuIvca36/g1jwWjn8GdauPpwU=; b=RhzhSAgvFwY90TRKzrAEA36jMfX+3oqBWJmSbgbHV3aS2JTqAcx84r1oixettFZ+7c KMV8kvsLslFO2Eo0PDFJsJhhMpXYKFPYxGrTVj4WmgfLdYqfd2aQkhRNvTMsyRWx41kR N1KsMxJMMiNwblRK4K2YX3QF3TGzOnD/VcAYRLazKA+Qrq9pNd2C52t/4KmQuZBdR2/5 K/2S6na65ftPkdbVd5fVNpVbYQillaQEkNsTvzdUA4UB56aeVHHd/4KZovetAh4+dNHG IXwToveC4FQWHsQQfGQ4LcJHEMglLMLk/DY3YE146YXYd1DgQHytAm1DJJXbfUgZ0zTK klbQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=DkRm1VmB; 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 b12si1856048ywb.388.2018.02.06.08.55.10 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:55:10 -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=DkRm1VmB; 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]:37492 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6WT-0006L7-W7 for patch@linaro.org; Tue, 06 Feb 2018 11:55:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33485) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Py-0000Wg-Er for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Pu-0004mU-Tn for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:26 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:37179) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Pu-0004k7-IO for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:22 -0500 Received: by mail-wr0-x242.google.com with SMTP id a43so2654024wrc.4 for ; Tue, 06 Feb 2018 08:48:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Gw4DnmmBoFPfPC9NmXjuIvca36/g1jwWjn8GdauPpwU=; b=DkRm1VmB2yYQz09eDdhyOid4i5lnxbsalTZr5vxMMy8f50I6Y1X3CGeX50BwA1/Xw1 16JbCM7BttVwnfWJhqjFDN33fiHX2rFAMzJh/R8VZaVT9C0RrxbK0+gRyKh9/CylBDmI auwZEHDl5eMt4KOSmoY4J4ONo6tzQ/8M30qR0= 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=Gw4DnmmBoFPfPC9NmXjuIvca36/g1jwWjn8GdauPpwU=; b=cyRwcesGx0n2XnA2z2J4nbCMUJinc35xIK+VzYssY9RsyEN1MG634hTbFHUjjSzN2i 8+XcyPb37vW3kSOKHGZ0XDdAjdUqKHo3BJZ9X/nE8fObuxszWPdPaCkmGwjSoefMlcyC 5uorUt9LhHayv1ZywWuit0HyWpOOoJH8l85h7e3hpIeT44xp0lOfkz+fEUM7i4hWU7GE GjlimnSLfqorSG+/j/nYwUWJD+m7fA5RriM9ctPw66h1dXrmBQZwUTGENFFcDHnqYLOt F/6eDVouJ7/m5p4s59gIU4Y8n+slCddMTyx680Oe/WMPuzq0+JXmYTc9Y099BB2cx0J7 UxdQ== X-Gm-Message-State: APf1xPASmqSMA3MK9VrdfQrdLSk1YSp5nWG2vuOrQFJDQy0YgPBq5b2j PjdWJhxLUn9Hx1ycrDobc53EsQ== X-Received: by 10.223.158.201 with SMTP id b9mr2714059wrf.192.1517935701092; Tue, 06 Feb 2018 08:48:21 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id d73sm14847749wma.16.2018.02.06.08.48.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:16 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 956703E059E; Tue, 6 Feb 2018 16:48:15 +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, 6 Feb 2018 16:47:57 +0000 Message-Id: <20180206164815.10084-5-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 04/22] target/*/cpu.h: remove softfloat.h 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: Marek Vasut , Guan Xuetao , Eduardo Habkost , Bastian Koppelmann , Anthony Green , Chris Wulff , Mark Cave-Ayland , qemu-devel@nongnu.org, Alexander Graf , Max Filippov , "open list:S390" , "open list:ARM" , "open list:PowerPC" , Artyom Tarasenko , "Edgar E. Iglesias" , Paolo Bonzini , Stafford Horne , David Gibson , =?utf-8?q?Alex_Benn=C3=A9e?= , Aurelien Jarno , Richard Henderson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" As cpu.h is another typically widely included file which doesn't need full access to the softfloat API we can remove the includes from here as well. Where they do need types it's typically for float_status and the rounding modes so we move that to softfloat-types.h as well. As a result of not having softfloat in every cpu.h call we now need to add it to various helpers that do need the full softfloat.h definitions. Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson [For PPC parts] Acked-by: David Gibson --- include/fpu/softfloat-types.h | 64 +++++++++++++++++++++++++++++++++++++++++ include/fpu/softfloat.h | 53 ---------------------------------- target/alpha/cpu.h | 2 -- target/arm/cpu.c | 1 + target/arm/cpu.h | 2 -- target/arm/helper-a64.c | 1 + target/arm/helper.c | 1 + target/arm/neon_helper.c | 1 + target/hppa/cpu.c | 1 + target/hppa/cpu.h | 1 - target/hppa/op_helper.c | 2 +- target/i386/cpu.h | 4 --- target/i386/fpu_helper.c | 1 + target/m68k/cpu.c | 2 +- target/m68k/cpu.h | 1 - target/m68k/fpu_helper.c | 1 + target/m68k/helper.c | 1 + target/m68k/translate.c | 2 ++ target/microblaze/cpu.c | 1 + target/microblaze/cpu.h | 2 +- target/microblaze/op_helper.c | 1 + target/moxie/cpu.h | 1 - target/nios2/cpu.h | 1 - target/openrisc/cpu.h | 1 - target/openrisc/fpu_helper.c | 1 + target/ppc/cpu.h | 1 - target/ppc/fpu_helper.c | 1 + target/ppc/int_helper.c | 1 + target/ppc/translate_init.c | 1 + target/s390x/cpu.c | 1 + target/s390x/cpu.h | 2 -- target/s390x/fpu_helper.c | 1 + target/sh4/cpu.c | 1 + target/sh4/cpu.h | 2 -- target/sh4/op_helper.c | 1 + target/sparc/cpu.h | 2 -- target/sparc/fop_helper.c | 1 + target/tricore/cpu.h | 1 - target/tricore/fpu_helper.c | 1 + target/tricore/helper.c | 1 + target/unicore32/cpu.c | 1 + target/unicore32/cpu.h | 1 - target/unicore32/ucf64_helper.c | 1 + target/xtensa/cpu.h | 1 - target/xtensa/op_helper.c | 1 + 45 files changed, 93 insertions(+), 79 deletions(-) -- 2.15.1 diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h index 8210a94ea1..4e378cb612 100644 --- a/include/fpu/softfloat-types.h +++ b/include/fpu/softfloat-types.h @@ -80,6 +80,12 @@ this code that are retained. #ifndef SOFTFLOAT_TYPES_H #define SOFTFLOAT_TYPES_H +/* This 'flag' type must be able to hold at least 0 and 1. It should + * probably be replaced with 'bool' but the uses would need to be audited + * to check that they weren't accidentally relying on it being a larger type. + */ +typedef uint8_t flag; + /* * Software IEC/IEEE floating-point types. */ @@ -112,4 +118,62 @@ typedef struct { #define make_float128(high_, low_) ((float128) { .high = high_, .low = low_ }) #define make_float128_init(high_, low_) { .high = high_, .low = low_ } +/* + * Software IEC/IEEE floating-point underflow tininess-detection mode. + */ + +enum { + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 +}; + +/* + *Software IEC/IEEE floating-point rounding mode. + */ + +enum { + float_round_nearest_even = 0, + float_round_down = 1, + float_round_up = 2, + float_round_to_zero = 3, + float_round_ties_away = 4, + /* Not an IEEE rounding mode: round to the closest odd mantissa value */ + float_round_to_odd = 5, +}; + +/* + * Software IEC/IEEE floating-point exception flags. + */ + +enum { + float_flag_invalid = 1, + float_flag_divbyzero = 4, + float_flag_overflow = 8, + float_flag_underflow = 16, + float_flag_inexact = 32, + float_flag_input_denormal = 64, + float_flag_output_denormal = 128 +}; + + +/* + * Floating Point Status. Individual architectures may maintain + * several versions of float_status for different functions. The + * correct status for the operation is then passed by reference to + * most of the softfloat functions. + */ + +typedef struct float_status { + signed char float_detect_tininess; + signed char float_rounding_mode; + uint8_t float_exception_flags; + signed char floatx80_rounding_precision; + /* should denormalised results go to zero and set the inexact flag? */ + flag flush_to_zero; + /* should denormalised inputs go to zero and set the input_denormal flag? */ + flag flush_inputs_to_zero; + flag default_nan_mode; + flag snan_bit_is_one; +} float_status; + #endif /* SOFTFLOAT_TYPES_H */ diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 4e16e22e58..f3b9008f78 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -82,12 +82,6 @@ this code that are retained. #ifndef SOFTFLOAT_H #define SOFTFLOAT_H -/* This 'flag' type must be able to hold at least 0 and 1. It should - * probably be replaced with 'bool' but the uses would need to be audited - * to check that they weren't accidentally relying on it being a larger type. - */ -typedef uint8_t flag; - #define LIT64( a ) a##LL /*---------------------------------------------------------------------------- @@ -102,53 +96,6 @@ enum { #include "fpu/softfloat-types.h" -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point underflow tininess-detection mode. -*----------------------------------------------------------------------------*/ -enum { - float_tininess_after_rounding = 0, - float_tininess_before_rounding = 1 -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point rounding mode. -*----------------------------------------------------------------------------*/ -enum { - float_round_nearest_even = 0, - float_round_down = 1, - float_round_up = 2, - float_round_to_zero = 3, - float_round_ties_away = 4, - /* Not an IEEE rounding mode: round to the closest odd mantissa value */ - float_round_to_odd = 5, -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point exception flags. -*----------------------------------------------------------------------------*/ -enum { - float_flag_invalid = 1, - float_flag_divbyzero = 4, - float_flag_overflow = 8, - float_flag_underflow = 16, - float_flag_inexact = 32, - float_flag_input_denormal = 64, - float_flag_output_denormal = 128 -}; - -typedef struct float_status { - signed char float_detect_tininess; - signed char float_rounding_mode; - uint8_t float_exception_flags; - signed char floatx80_rounding_precision; - /* should denormalised results go to zero and set the inexact flag? */ - flag flush_to_zero; - /* should denormalised inputs go to zero and set the input_denormal flag? */ - flag flush_inputs_to_zero; - flag default_nan_mode; - flag snan_bit_is_one; -} float_status; - static inline void set_float_detect_tininess(int val, float_status *status) { status->float_detect_tininess = val; diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h index 09720c2f3b..a79fc2e780 100644 --- a/target/alpha/cpu.h +++ b/target/alpha/cpu.h @@ -33,8 +33,6 @@ #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" - #define ICACHE_LINE_SIZE 32 #define DCACHE_LINE_SIZE 32 diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 9da6ea505c..2d6ac054bd 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -34,6 +34,7 @@ #include "sysemu/hw_accel.h" #include "kvm_arm.h" #include "disas/capstone.h" +#include "fpu/softfloat.h" static void arm_cpu_set_pc(CPUState *cs, vaddr value) { diff --git a/target/arm/cpu.h b/target/arm/cpu.h index d2bb59eded..c7c922d79b 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -39,8 +39,6 @@ #include "cpu-qom.h" #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" - #define EXCP_UDEF 1 /* undefined instruction */ #define EXCP_SWI 2 /* software interrupt */ #define EXCP_PREFETCH_ABORT 3 diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c index 06fd321fae..10e08bdc1f 100644 --- a/target/arm/helper-a64.c +++ b/target/arm/helper-a64.c @@ -31,6 +31,7 @@ #include "exec/cpu_ldst.h" #include "qemu/int128.h" #include "tcg.h" +#include "fpu/softfloat.h" #include /* For crc32 */ /* C2.4.7 Multiply and divide */ diff --git a/target/arm/helper.c b/target/arm/helper.c index bfce09643b..4ef99882c4 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -15,6 +15,7 @@ #include /* For crc32 */ #include "exec/semihost.h" #include "sysemu/kvm.h" +#include "fpu/softfloat.h" #define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */ diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c index 689491cad3..a1ec6537eb 100644 --- a/target/arm/neon_helper.c +++ b/target/arm/neon_helper.c @@ -11,6 +11,7 @@ #include "cpu.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" +#include "fpu/softfloat.h" #define SIGNBIT (uint32_t)0x80000000 #define SIGNBIT64 ((uint64_t)1 << 63) diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 5213347720..9224331165 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -23,6 +23,7 @@ #include "cpu.h" #include "qemu-common.h" #include "exec/exec-all.h" +#include "fpu/softfloat.h" static void hppa_cpu_set_pc(CPUState *cs, vaddr value) diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 7640c81221..c88d844938 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -51,7 +51,6 @@ #define CPUArchState struct CPUHPPAState #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" #define TARGET_PAGE_BITS 12 diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c index 4ee936bf86..a3af62daf7 100644 --- a/target/hppa/op_helper.c +++ b/target/hppa/op_helper.c @@ -24,7 +24,7 @@ #include "exec/cpu_ldst.h" #include "sysemu/sysemu.h" #include "qemu/timer.h" - +#include "fpu/softfloat.h" void QEMU_NORETURN HELPER(excp)(CPUHPPAState *env, int excp) { diff --git a/target/i386/cpu.h b/target/i386/cpu.h index f91e37d25d..faf39ec1ce 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -52,10 +52,6 @@ #define CPUArchState struct CPUX86State -#ifdef CONFIG_TCG -#include "fpu/softfloat.h" -#endif - enum { R_EAX = 0, R_ECX = 1, diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c index 9014b6f88a..ea5a0c4861 100644 --- a/target/i386/fpu_helper.c +++ b/target/i386/fpu_helper.c @@ -24,6 +24,7 @@ #include "qemu/host-utils.h" #include "exec/exec-all.h" #include "exec/cpu_ldst.h" +#include "fpu/softfloat.h" #define FPU_RC_MASK 0xc00 #define FPU_RC_NEAR 0x000 diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index 98919b358b..cbd5f08ce8 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -24,7 +24,7 @@ #include "qemu-common.h" #include "migration/vmstate.h" #include "exec/exec-all.h" - +#include "fpu/softfloat.h" static void m68k_cpu_set_pc(CPUState *cs, vaddr value) { diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 627fb787b6..e250dc5278 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -28,7 +28,6 @@ #include "qemu-common.h" #include "exec/cpu-defs.h" #include "cpu-qom.h" -#include "fpu/softfloat.h" #define OS_BYTE 0 #define OS_WORD 1 diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index 665e7609af..3c5a82aaa0 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -23,6 +23,7 @@ #include "exec/helper-proto.h" #include "exec/exec-all.h" #include "exec/cpu_ldst.h" +#include "fpu/softfloat.h" /* Undefined offsets may be different on various FPU. * On 68040 they return 0.0 (floatx80_zero) diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 20155c7801..917d46efcc 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -24,6 +24,7 @@ #include "exec/gdbstub.h" #include "exec/helper-proto.h" +#include "fpu/softfloat.h" #define SIGNBIT (1u << 31) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 34db97b8a0..bbbc3d8a0e 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -32,6 +32,8 @@ #include "trace-tcg.h" #include "exec/log.h" +#include "fpu/softfloat.h" + //#define DEBUG_DISPATCH 1 diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c index 5700652e06..393520f3ef 100644 --- a/target/microblaze/cpu.c +++ b/target/microblaze/cpu.c @@ -28,6 +28,7 @@ #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "exec/exec-all.h" +#include "fpu/softfloat.h" static const struct { const char *name; diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h index f3e7405a62..1fe21c8539 100644 --- a/target/microblaze/cpu.h +++ b/target/microblaze/cpu.h @@ -28,7 +28,7 @@ #define CPUArchState struct CPUMBState #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" +#include "fpu/softfloat-types.h" struct CPUMBState; typedef struct CPUMBState CPUMBState; #if !defined(CONFIG_USER_ONLY) diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c index 869072a2d1..1b4fe796e7 100644 --- a/target/microblaze/op_helper.c +++ b/target/microblaze/op_helper.c @@ -24,6 +24,7 @@ #include "qemu/host-utils.h" #include "exec/exec-all.h" #include "exec/cpu_ldst.h" +#include "fpu/softfloat.h" #define D(x) diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h index a01f480821..d85e1fc061 100644 --- a/target/moxie/cpu.h +++ b/target/moxie/cpu.h @@ -34,7 +34,6 @@ #define MOXIE_EX_BREAK 16 #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" #define TARGET_PAGE_BITS 12 /* 4k */ diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h index 204b39add7..cd4e40d1b4 100644 --- a/target/nios2/cpu.h +++ b/target/nios2/cpu.h @@ -27,7 +27,6 @@ #define CPUArchState struct CPUNios2State #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" #include "qom/cpu.h" struct CPUNios2State; typedef struct CPUNios2State CPUNios2State; diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index fb46cc9986..5050b1135c 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -29,7 +29,6 @@ struct OpenRISCCPU; #include "qemu-common.h" #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" #include "qom/cpu.h" #define TYPE_OPENRISC_CPU "or1k-cpu" diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c index 1375cea948..977a1e8e55 100644 --- a/target/openrisc/fpu_helper.c +++ b/target/openrisc/fpu_helper.c @@ -22,6 +22,7 @@ #include "cpu.h" #include "exec/helper-proto.h" #include "exception.h" +#include "fpu/softfloat.h" static inline uint32_t ieee_ex_to_openrisc(OpenRISCCPU *cpu, int fexcp) { diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 9f8cbbe7aa..7bde1884a1 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -79,7 +79,6 @@ #include "exec/cpu-defs.h" #include "cpu-qom.h" -#include "fpu/softfloat.h" #if defined (TARGET_PPC64) #define PPC_ELF_MACHINE EM_PPC64 diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index c4dab159e4..9ae418a577 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -21,6 +21,7 @@ #include "exec/helper-proto.h" #include "exec/exec-all.h" #include "internal.h" +#include "fpu/softfloat.h" static inline float128 float128_snan_to_qnan(float128 x) { diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 3a50f1e1b7..35bdf09773 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -23,6 +23,7 @@ #include "qemu/host-utils.h" #include "exec/helper-proto.h" #include "crypto/aes.h" +#include "fpu/softfloat.h" #include "helper_regs.h" /*****************************************************************************/ diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c index 55c99c97e3..54ec2e122a 100644 --- a/target/ppc/translate_init.c +++ b/target/ppc/translate_init.c @@ -36,6 +36,7 @@ #include "sysemu/qtest.h" #include "qemu/cutils.h" #include "disas/capstone.h" +#include "fpu/softfloat.h" //#define PPC_DUMP_CPU //#define PPC_DEBUG_SPR diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index d2e6b9f5c7..7acb827f1b 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -42,6 +42,7 @@ #include "sysemu/arch_init.h" #include "sysemu/sysemu.h" #endif +#include "fpu/softfloat.h" #define CR0_RESET 0xE0UL #define CR14_RESET 0xC2000000UL; diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index a1123ad621..96264ad4cb 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -41,8 +41,6 @@ #include "exec/cpu-all.h" -#include "fpu/softfloat.h" - #define NB_MMU_MODES 4 #define TARGET_INSN_START_EXTRA_WORDS 1 diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c index 334159119f..43f8bf1c94 100644 --- a/target/s390x/fpu_helper.c +++ b/target/s390x/fpu_helper.c @@ -24,6 +24,7 @@ #include "exec/exec-all.h" #include "exec/cpu_ldst.h" #include "exec/helper-proto.h" +#include "fpu/softfloat.h" /* #define DEBUG_HELPER */ #ifdef DEBUG_HELPER diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c index e0b99fbc89..4f8c830fe3 100644 --- a/target/sh4/cpu.c +++ b/target/sh4/cpu.c @@ -25,6 +25,7 @@ #include "qemu-common.h" #include "migration/vmstate.h" #include "exec/exec-all.h" +#include "fpu/softfloat.h" static void superh_cpu_set_pc(CPUState *cs, vaddr value) diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h index 52a4568dd5..a649b68d78 100644 --- a/target/sh4/cpu.h +++ b/target/sh4/cpu.h @@ -40,8 +40,6 @@ #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" - #define TARGET_PAGE_BITS 12 /* 4k XXXXX */ #define TARGET_PHYS_ADDR_SPACE_BITS 32 diff --git a/target/sh4/op_helper.c b/target/sh4/op_helper.c index 4b8bbf63b4..4f825bae5a 100644 --- a/target/sh4/op_helper.c +++ b/target/sh4/op_helper.c @@ -21,6 +21,7 @@ #include "exec/helper-proto.h" #include "exec/exec-all.h" #include "exec/cpu_ldst.h" +#include "fpu/softfloat.h" #ifndef CONFIG_USER_ONLY diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index 3eaffb354e..9724134a5b 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -29,8 +29,6 @@ #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" - /*#define EXCP_INTERRUPT 0x100*/ /* trap definitions */ diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c index c7fb176e4c..b6642fd1d7 100644 --- a/target/sparc/fop_helper.c +++ b/target/sparc/fop_helper.c @@ -21,6 +21,7 @@ #include "cpu.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" +#include "fpu/softfloat.h" #define QT0 (env->qt0) #define QT1 (env->qt1) diff --git a/target/tricore/cpu.h b/target/tricore/cpu.h index f41d2ceb69..e7dfe4bcc6 100644 --- a/target/tricore/cpu.h +++ b/target/tricore/cpu.h @@ -24,7 +24,6 @@ #include "qemu-common.h" #include "cpu-qom.h" #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" #define CPUArchState struct CPUTriCoreState diff --git a/target/tricore/fpu_helper.c b/target/tricore/fpu_helper.c index 7979bb6692..df162902d6 100644 --- a/target/tricore/fpu_helper.c +++ b/target/tricore/fpu_helper.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" +#include "fpu/softfloat.h" #define QUIET_NAN 0x7fc00000 #define ADD_NAN 0x7fc00001 diff --git a/target/tricore/helper.c b/target/tricore/helper.c index 378c2a4a76..45276d3782 100644 --- a/target/tricore/helper.c +++ b/target/tricore/helper.c @@ -19,6 +19,7 @@ #include "cpu.h" #include "exec/exec-all.h" +#include "fpu/softfloat.h" enum { TLBRET_DIRTY = -4, diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c index 17dc1504d7..93cbae39d9 100644 --- a/target/unicore32/cpu.c +++ b/target/unicore32/cpu.c @@ -18,6 +18,7 @@ #include "qemu-common.h" #include "migration/vmstate.h" #include "exec/exec-all.h" +#include "fpu/softfloat.h" static void uc32_cpu_set_pc(CPUState *cs, vaddr value) { diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h index a3cc71416d..42e1d52478 100644 --- a/target/unicore32/cpu.h +++ b/target/unicore32/cpu.h @@ -23,7 +23,6 @@ #include "qemu-common.h" #include "cpu-qom.h" #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" #define NB_MMU_MODES 2 diff --git a/target/unicore32/ucf64_helper.c b/target/unicore32/ucf64_helper.c index 6c919010c3..fad3fa6618 100644 --- a/target/unicore32/ucf64_helper.c +++ b/target/unicore32/ucf64_helper.c @@ -11,6 +11,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" +#include "fpu/softfloat.h" /* * The convention used for UniCore-F64 instructions: diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index f300c02c07..49c2e3cf9a 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -36,7 +36,6 @@ #include "qemu-common.h" #include "cpu-qom.h" #include "exec/cpu-defs.h" -#include "fpu/softfloat.h" #include "xtensa-isa.h" #define NB_MMU_MODES 4 diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c index 43182b113e..7486b99799 100644 --- a/target/xtensa/op_helper.c +++ b/target/xtensa/op_helper.c @@ -34,6 +34,7 @@ #include "exec/cpu_ldst.h" #include "exec/address-spaces.h" #include "qemu/timer.h" +#include "fpu/softfloat.h" void xtensa_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, From patchwork Tue Feb 6 16:47:58 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: 127029 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3089996ljc; Tue, 6 Feb 2018 08:52:06 -0800 (PST) X-Google-Smtp-Source: AH8x226XJtS9LeLG9s1PioYXMeefTHTctOpME5cb2dDL0BB3CuYGcyNsW1+Y5Vpt73iyJnvHjkMo X-Received: by 10.129.75.8 with SMTP id y8mr1860046ywa.245.1517935926212; Tue, 06 Feb 2018 08:52:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517935926; cv=none; d=google.com; s=arc-20160816; b=lGNrWTb6wOWFpcYbCetpvkMqLTXJWPphTcTS72a6BMbfsWmT3dcaC7lnbSP79AMIT9 dbHBans0obsJUb2BK3TFdRHOoHVeDHpsgkAFqyaxyR0Yxsjo8hm8rM9zPJLUwaXiuyad u3m/ypg7A9sDoqEaS0QxmymgLPxIc5VaVGxYpi5pHB+hgOu8tLTYlcvEQERMWe18SOXY M/uACcR7z/Vxz+c0mFc+Izo7e0DiJSqt1Q5wSSobnpEFgLqnz1hkD0IK1dI9n+F61pzo rnTkP0JO3mhYcwPeyI8ZIWST+bhTSkr7cE3PhjB7oa5yBcb62cCHceNhy27UMn+1Cldf cBow== 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=6e42PntWcXp9kup69M+lCg5U5Wv68rh4rND0cf5yMTw=; b=i+SF2DfoxrFSy1haP9TRLYopw5m1dYNStHcwirkzQIcmixO7FKP7GlPXoSDS8WUhxa EUHbZ9Jx41B2J7PncrzJLl83gjOgbApqRpG5H34ai/rClBQOXAGs9OJPBqons9ec0xFx znH17OZEhtJno+EaT7yKMVNY53QCaJmRJQtRUXWCMV+DPc2PxHXN3IALsZQRvzahUfY4 lSecgRMLqFEcXhtXazvT3Rzx3F6CEbthBUlC1rxQgccBinTSNMWnfjGaN7ejOm0ucCWA b3wvtHjGhtZB3m89W1fJOqDJkqsdxvLTlZu5ceHIKGjkmBGQlpjcQh1x+KM1EuRUxlzw qdcw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ULpIVzMw; 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 w14si213674ybg.767.2018.02.06.08.52.06 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:52:06 -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=ULpIVzMw; 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]:37464 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6TV-0003VZ-HG for patch@linaro.org; Tue, 06 Feb 2018 11:52:05 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33484) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Py-0000We-Eh for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Px-0004ro-Gp for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:26 -0500 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:53519) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Px-0004pn-8O for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:25 -0500 Received: by mail-wm0-x242.google.com with SMTP id t74so5035259wme.3 for ; Tue, 06 Feb 2018 08:48:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6e42PntWcXp9kup69M+lCg5U5Wv68rh4rND0cf5yMTw=; b=ULpIVzMwtQAkCfSB1ba199cLVYHqMDNVZhmmQnTM/4+f0Evi+rV6PeTrsDycWctmUg y13kZ9OO9Rr291ag3YztAwVszmikYqHezq/oqQ3K5A4KN9qRv+A3O6jixYgINPRzozRz MBc/NyMX35xuiYA6cyGSgaxEuW/hNE8EyCA0I= 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=6e42PntWcXp9kup69M+lCg5U5Wv68rh4rND0cf5yMTw=; b=JAS+aiLps17kwGn14JGfapjwipQUcXs1v8+uUYdsvnw/hM14lfWo68cU1CI8oYoPI7 shcKh4UE9UMZUmQYRsDALvHL1Pf7KlAVqZJNRNv8xuFG4ypjJE3fh33OYjJ8DzFENbD+ foqVNg8EYyqLHTdaVvYQKC31FmSc/X2Txww1fY/UVF8CHeAU6WSptJbNkprEfgbHNfcS 2Wc4rRxtcw4XzkW6IuY7sozyUFA92MCyguogrchSA3Kq+cwM6PjCukJKg6Cb2gy/nd7l fzw32wr/fFfYwFi91xleMa38joaFdrqVTDghdjLhh9m2Mvf6ysdfPcl9NRp37ZqXLf9E QyCg== X-Gm-Message-State: APf1xPBBffG5dEbsaZxhZMniWaPgn6XtXEzHJcgGpeIBDYInCU83ZxT6 54/YVrIbhUzUHAIv/pdAzEA/NA== X-Received: by 10.28.23.14 with SMTP id 14mr2496718wmx.5.1517935703972; Tue, 06 Feb 2018 08:48:23 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id b35sm34971789wra.13.2018.02.06.08.48.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:21 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id A70AB3E060B; Tue, 6 Feb 2018 16:48:15 +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, 6 Feb 2018 16:47:58 +0000 Message-Id: <20180206164815.10084-6-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 05/22] 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é Reviewed-by: Peter Maydell --- include/fpu/softfloat.h | 7 +++++++ 1 file changed, 7 insertions(+) -- 2.15.1 diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index f3b9008f78..1d34f2c3eb 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -265,6 +265,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 Feb 6 16:47:59 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: 127026 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3087158ljc; Tue, 6 Feb 2018 08:48:58 -0800 (PST) X-Google-Smtp-Source: AH8x225PF9rCEC+V1NdQFnDk+e4NIGnt57fLkU3r2jw2owWrhvxvj9XoCoKBm3FJZYRYEhMpt5A/ X-Received: by 10.37.244.71 with SMTP id p7mr1818824ybe.264.1517935738305; Tue, 06 Feb 2018 08:48:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517935738; cv=none; d=google.com; s=arc-20160816; b=nbF0zEL7TMt1wqafZ420mSEmWmE6+tgpbG7MZR88JjY1AISWBcbrHd1T1pBMogycgU 9VXjzY+x08WzkFlcp0AwxFGUzO+j2FZgcWle41GAvILO3aR52BSKAUS/x/e/N6Xecnxi KpVNdvzMoJuMXupdMVAnJ92G97dKCpvXwmqWFnuy3FqGy99/GKFDmgFqOrobthTrfSFW U6zKuvPGGB4svGaeo7M5vzx/yub49En03IaOwEiBfYc+0JEhWwkRJaA0Rmxfsg1HdQ7t vp0MdppulZ/Q2lNzAExFVhT4pk5cAuvmRrz/aQOGoFuyUF9c4kVEbF7X1z+m6azgEepj cbrQ== 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=bPH2w3PfFpdRcohbDu83KT6KDKSPHYODix9ErvUA+Fg=; b=qHta3om8fcMAiRi/8wu5nG/XQ5tqyC5y03lUgSjZYZ9SwduD5UWDXp+ZDo9BtzHN7v AZerYZEx6l5DSySi0SNBnK4ulVnf9/Ys8iYpihKX1lnm828LaLgEj2b0Dt3ANTFf8Uwv 8NpGtTZNh22f1qVMT8SeLUFVPB7kFKTGQ06NLCewZbAprr8Koxx6QNkHBkjXsc5udQCI GAPt5GJtIzJxqZarpMAuZR+KubktyWQ0ijDRcduJgongXqmBgE5WIRKkDNkdKRQh3BHR xl9fWCyk8vrj/D+irpwkjHS2q24FFIDnxOrk0xgB/SQMczA1HV788oLl22mHd5TKix7y ZpUw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Zdnz3y/a; 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 u15si782416ybj.430.2018.02.06.08.48.58 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:48:58 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Zdnz3y/a; 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]:37440 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6QT-0000XI-MQ for patch@linaro.org; Tue, 06 Feb 2018 11:48:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33440) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Px-0000VM-8q for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Pw-0004pq-Gr for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:25 -0500 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:39879) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Pw-0004o2-A7 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:24 -0500 Received: by mail-wm0-x244.google.com with SMTP id b21so5127961wme.4 for ; Tue, 06 Feb 2018 08:48:24 -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=bPH2w3PfFpdRcohbDu83KT6KDKSPHYODix9ErvUA+Fg=; b=Zdnz3y/a0bEZz3T6ywMOO5g0Dhi1EHPXLH3f07z1XSr6hkcNn+56LDZ/hJAZzSR+Ml 408TRUQTbri/QYZIJ+EABFLV2iTiyY4jPcnYD6i8F1GemagWeccmVaXn9DXgVbTJm6cF 6K2S9Zsin2qLsva6q2AY9yT/Pnhni6mdB8ekU= 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=bPH2w3PfFpdRcohbDu83KT6KDKSPHYODix9ErvUA+Fg=; b=FbaLevVZawAMWPClX1yTFpLtyx6+WYi2xtcKWI6Uc0PJgAHk9H4wrf+AM4+GOgfbzS TJ0nqp2YkJvFp/mJ2U+wC913bxts246S/mPKglEHkCn5fgWcEkcOePQ0umVsE/KvtUnq waRA9krYz+DB3p0/QQaEiE5rePmm6H5637/mFjcrDxUYDrM6OJigyNkUcOik3G78dLh9 s4On4usimLDpHNtPu5CPdYzDj9NAe3sBwfFghiugmjH9Kq6yREDUellEDDYUr+eVm/a1 57OiMp0Xe83Hcerhwv3OmFbYF+ZRppe3o8D+VjJX43hSBdVpts8bwJuOywCgQr9jZ6K/ HPbQ== X-Gm-Message-State: APf1xPBKW1xGzy+hSLTT1GnbMFfqPqArQSOR+uhN/XrdbzIerYYLEFg9 tfFQ02wR83wFA7O0ozYY/uL7vw== X-Received: by 10.28.177.7 with SMTP id a7mr2305755wmf.143.1517935703182; Tue, 06 Feb 2018 08:48:23 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id g8sm23408356wra.18.2018.02.06.08.48.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:21 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id B8BA73E0633; Tue, 6 Feb 2018 16:48:15 +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, 6 Feb 2018 16:47:59 +0000 Message-Id: <20180206164815.10084-7-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 06/22] 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 Reviewed-by: Peter Maydell --- include/fpu/softfloat.h | 9 +++++++++ 1 file changed, 9 insertions(+) -- 2.15.1 diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 1d34f2c3eb..f75aa59100 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -272,6 +272,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 Feb 6 16:48:00 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: 127033 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3092774ljc; Tue, 6 Feb 2018 08:55:39 -0800 (PST) X-Google-Smtp-Source: AH8x225eUfi3up+9EleVD1YeXf0emd8mlYF/WNu3QGPbuNOzggnKywBL9l4jMT3ocL/veag9oafK X-Received: by 10.37.3.194 with SMTP id 185mr1867499ybd.379.1517936138954; Tue, 06 Feb 2018 08:55:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936138; cv=none; d=google.com; s=arc-20160816; b=D76L2jEQzsbtb7nybtQ3F81aw82DxlLvHJrJUV+HH3KHGiW189CVU1rYlWAsVjI2mB ENrL063kZ9GDysON1X4uKFNGQjYOgf39fb9Hp2H3bWtGJLTMwSRBa1zu5RB94xgeaM3i /9H/qje4CHo1C9Ly5yeKYonlAOEto6ny+xY6RD0aQea8zjAK7bAXu/snehhmh5NkJtYR jPPK/K3HtfL01JvuEbWSY7sqQId8DxphyDi0WBGkeIJAmowkXrcskmGhodNHAJ9hnG8k MZ55JhYqEo3n7AdChDZ8ng4R+IBvhmtrJJCZ7vMX70IjltGZM/HrB2OY3erLxLGJo1R2 +0fA== 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=SorheihcHtUCGiSTnTOTs5ctR1c+FNyyQ7fs42JPDKc=; b=I8i87jjfmBMv65taWUvWaeSdOiMQJVdamkqatC8K320xoHCNsHdJ1qLtylLLAookzv eAEtoNk1ZS6Y6q9WwuPBOhuH4r8yKL39cIfY7wxNefR5Tyu4a3A80Lj0EXtMZS0wpc9y xExxncvywUsmqyJtHIAk0KCRtr7YhqBepVaOywxZhHSKROgDrtAI1vbIRDTvGdqaJXlY V6fyCnACABFtC4rEIW/Vqxm5y0qOYHeBqHQF5/2znLWmRySI0cA2Md/LB5YjTPSatFPX 4l1yCrOi+KuXcUU5CwG8BZIM3GGYeyJumM+a3v9uOR+iAjRSwRwi0vePaXl5qzRqoyTy xejw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=V04n8Sfy; 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 t1si1659379ybk.651.2018.02.06.08.55.38 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:55:38 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=V04n8Sfy; 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]:37615 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Ww-0006r8-Ba for patch@linaro.org; Tue, 06 Feb 2018 11:55:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33569) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Q4-0000b0-4O for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Q0-0004yf-O7 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:32 -0500 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:51157) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Q0-0004xh-IR for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:28 -0500 Received: by mail-wm0-x242.google.com with SMTP id f71so5028608wmf.0 for ; Tue, 06 Feb 2018 08:48: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=SorheihcHtUCGiSTnTOTs5ctR1c+FNyyQ7fs42JPDKc=; b=V04n8Sfyil+UbO9ad5CGlkyyEpohdCgR/KCadYK0CwrK9EXSivWEbZPSRrQRzz62zB XLAXjfWCJEISbKJ9VQNtDrLSsllGsZLUmp8g0QyQBBS51q1yjdQDZACFxDwrdxzLQj7N nukaOrHWatZkfteowu709WFIT5thoYghqw4E0= 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=SorheihcHtUCGiSTnTOTs5ctR1c+FNyyQ7fs42JPDKc=; b=bOfUH1p8XC4GNbt7WMkkKEVMJRNa6GwyniXwIn778UUlqEY2Kc6dYh6W8MWWxzYkuJ Duua2TwvRc2rP3tH7LSxYrr6hkRidJ7pupN2RDzrF7Ci5JBc8baTB0dFVMKHC8f274Yl OssH7lgwbUxty40dGk/PIDlVjW9ra+0+NmosT5x2RMI39b4iMSHhebhMqLeNyw2ntSLv oMvkBB77j6FwlYmRbkAw4WL8mJrhFRKQ+MxEBjQx7Zv2suE+XiODiGVChhLz/89035yR 3wwVicmTV2eTK9ZSPysEOottqq9qT0YV1fzcN0G/CMGK8zmgvkx4F6K1FKYEhMyzG4T2 +QtA== X-Gm-Message-State: APf1xPAJwv9iJm2ef9m7ywZRTsGsgnPcMLWnRJINfdzceGSunMHzdvfl YkNfKZhsAv+hXxNzc6NOuzTGPQ== X-Received: by 10.28.184.82 with SMTP id i79mr2420635wmf.6.1517935707466; Tue, 06 Feb 2018 08:48:27 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id q14sm5779936wre.66.2018.02.06.08.48.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:22 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id C9C623E063E; Tue, 6 Feb 2018 16:48:15 +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, 6 Feb 2018 16:48:00 +0000 Message-Id: <20180206164815.10084-8-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 07/22] 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 Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson --- include/fpu/softfloat.h | 5 +++++ 1 file changed, 5 insertions(+) -- 2.15.1 diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index f75aa59100..59c06ef192 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -281,6 +281,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 Feb 6 16:48:01 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: 127027 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3089618ljc; Tue, 6 Feb 2018 08:51:41 -0800 (PST) X-Google-Smtp-Source: AH8x225HgbifWhLndsSeUnKwAW6TNXgbHaEp9rtxspZWq8nv4NE/gz/y2SEcgrmHpFDdJ+3uskNj X-Received: by 10.37.173.67 with SMTP id l3mr1900005ybe.6.1517935901135; Tue, 06 Feb 2018 08:51:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517935901; cv=none; d=google.com; s=arc-20160816; b=DucPZ4+ptAsd6kcsURDQ6n8zYM6Kz8Or/mDfwnmf2EmiFYSmBIuCXfSFx6il1hbz3k N0xSLQwoHlLQt0O8WlexpBym+zrXAV8Et74ypE7jdQQAFYYc4YHLUi9nzUcwIe8uYiL6 xFFtocBgUg9iszkMX6Hf4TzyF5vkwTBPAuqGobpi/ZwGQ3J/IPKDmFLJyp49A6yeI2+o 3A9P9X/jk6rdBOT4hmsBagn1tzT7tOCxAOQw0c7Tw3cwV9Qkl9R3scBtBnZNYjyd2KR2 5k7E5OYWyAbudOilqA3RP3xu7EuyAq1VOu+XKzK/MuWPCo5xin2x5AwcRQR7JL3SeQBI kCow== 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=q0LPRbmqeQMt8/7SVdLsOh0eSUUPit9todhKy0ZBmSc=; b=bxaIfLH+NaPd5nzaDwvZkNnMg2Z2zt9JjXiuA1CKkPr8METUBPNVFtZcvH86ceg8QH /TAF7fflB+kkkWQS3VQwRaaYHkDKd4I/X1b1F8aZ8XfQ6dtbQJWI/Rs+/t3XUdSnM5yd hkov23lC3YXjjmL0b/yhuzyxSRov7AovJ6PcAQC9oB4cs2e9C3TxTMvCYpB9ZwrlUZF7 dtX4xiZiSfhlSAfD1ou9rDXHh5nx52SBp+hYiVEjfYZI4D/Ir2f6Wl5eh1Zc24RtIDKr 7C9k9Q4OlNvuo80ltKB0swZamJc6ACDzmtN1Jr946hbvjWxgRPmYSpK1amYCuuDhM+Xo 3myw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=KY8qhvWC; 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 h184si1853156ywf.345.2018.02.06.08.51.40 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:51:41 -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=KY8qhvWC; 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]:37455 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6T6-0002Eh-Bn for patch@linaro.org; Tue, 06 Feb 2018 11:51:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33566) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Q4-0000az-3K for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Q0-0004xv-1g for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:32 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:34511) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Pz-0004vT-Qi for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:27 -0500 Received: by mail-wr0-x243.google.com with SMTP id z6so2666126wrb.1 for ; Tue, 06 Feb 2018 08:48: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=q0LPRbmqeQMt8/7SVdLsOh0eSUUPit9todhKy0ZBmSc=; b=KY8qhvWCTd0g2x8zlT0MynMwNyvykVLVHQ8xirGcinmRYB3IXvz63pn4vA2o1V1WIa 0QTmH/YVrvMjvWN7n7vFY7oXN353Fx3Z+mINAAku7R3uJgjcCKRNCyh55WyL1YdKp3vN psQVusnziwExwWc2WprD5ggRhNc5rFkoM51BU= 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=q0LPRbmqeQMt8/7SVdLsOh0eSUUPit9todhKy0ZBmSc=; b=F14Fm8tYqNgFvxIxXRrrxdDoD5DTkRUrj0OROz9w6UZuS2KwXSR0D57yfkoESIUpo0 fvNbsOeGGQQ3lCi+1wEanuI6KBm5oAlL2lfEkQHeosPejN5WKvZ9tLJkgQP4/0t2izoB w87zgWjqsqAaXAiijL8d+FUwQl7nWcWFlSpAGfQvbsCKBYdTvKGjxl4lJNhvS1R3dWOc orMDHAupvavoV9LP1FQjr+DZaG5NBQE9jeJhjxfVAEKRZGG7BcXUd5CbyEqKDllORQ7X fpvCcWMHt4AM6iH7np85ES04lnjKaAtwi/e5K9GA3a404QqONmWFN7mDA9ztW9XtDz/X kPew== X-Gm-Message-State: APf1xPCendgFkVVu7qtrNJhqFadWV5uIZhIwW69c8PB+cZXeSp06ipvd 7ic9JoBLnkMSnJ/18tq39AGUTA== X-Received: by 10.223.136.89 with SMTP id e25mr2669924wre.140.1517935706681; Tue, 06 Feb 2018 08:48:26 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 78sm9549219wmm.22.2018.02.06.08.48.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:22 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id DA8BC3E069A; Tue, 6 Feb 2018 16:48:15 +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, 6 Feb 2018 16:48:01 +0000 Message-Id: <20180206164815.10084-9-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 08/22] 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 Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson --- v2 - fixup constants, remove unused onces --- include/fpu/softfloat.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) -- 2.15.1 diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 59c06ef192..23824a3000 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -286,6 +286,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(0x3c00) +#define float16_half make_float16(0x3800) +#define float16_infinity make_float16(0x7c00) + /*---------------------------------------------------------------------------- | The pattern for a default generated half-precision NaN. *----------------------------------------------------------------------------*/ @@ -392,8 +397,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) @@ -506,7 +509,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 Feb 6 16:48:02 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: 127040 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3094943ljc; Tue, 6 Feb 2018 08:58:24 -0800 (PST) X-Google-Smtp-Source: AH8x225KOVO2otcg4e6o4gzgmNF+LN58zyC4gX147p2T1SYUiRXQytjknC/WyV08q1U5xK/y1RFy X-Received: by 10.129.90.84 with SMTP id o81mr1894679ywb.115.1517936304817; Tue, 06 Feb 2018 08:58:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936304; cv=none; d=google.com; s=arc-20160816; b=lX/4WRyMaYM5ydf0yeV2vTwo2x/9RIrnc6IThZ4vis+MDgwFj55Hgqiwca213hB85h KDejYXZtMXsM2LCrAGL7f6RSbSI+JeQN555svM74K7gbISmpAyv/odOhRiVsYfRz/Li3 WJfDGEELVE4+2GuVDRlTJkGhVdd7vnPLgjh+LcY+sdDrE4YiO8UtsnrMQ0u40YMES6AU xMVtZRNne1x7rVdvcdVAHXsOyXruE4roSBsO3fgHLLVZxPmbJicFo4AZsUGjazdlCOiL 5jP8fbkwa+P6fBhC0t7+mQA+R0JpcH73MeAl6PzniPgQ102QyeycUSYqDhKj2rx3Xetu aEbQ== 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=CbmvNTfC2Q0sl6dTe4aB9f4qRWG8djUkf97QFijCsF0=; b=UPquoARQv6LSEw07RLt66Hua+rGYWvJ9NKjvhveJLvY5aalI/tXGFgv5r0oT1EJC4/ s6ZU0lIdyXQ4r2UfEZCLM4qc08LZ44B4ZTbjezteU7ee05Xr5efrjAESBu6bbCv7ar0t 9DW1vVaQXi7iHwq985UMP29HffJ17YvZYdecGq1EUcwf5JPTbYLKTCm6339qvQFt0MZC ma2mpnB7dE3qBGKKRXgIm6uzQAKnd2u46t8bYJlWvP3xLKTPh7S089z8/4X8/b5G2WEb ZETcM9nWm3KlHcmJBdzB685cVby8iK+CDp+0of/cHCAtwHXtT+FNTHPTrEzOjVjDTv/l xhpA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=IuYob9bv; 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 l184si459049ywg.22.2018.02.06.08.58.24 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:58: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=IuYob9bv; 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]:37843 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Zc-0001Kp-4y for patch@linaro.org; Tue, 06 Feb 2018 11:58:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33592) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Q4-0000bn-R9 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Q3-00053H-V4 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:32 -0500 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:53521) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Q3-00052T-P1 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:31 -0500 Received: by mail-wm0-x243.google.com with SMTP id t74so5036016wme.3 for ; Tue, 06 Feb 2018 08:48:31 -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=CbmvNTfC2Q0sl6dTe4aB9f4qRWG8djUkf97QFijCsF0=; b=IuYob9bvUlH4b2zmmQGtyc8Nf5kMoVDgwIuH91l+gHMrvJp/pNZuVecI1hlcjctz33 EaHkk8AIH/kpqce5JZHecx2c+W21LAtxFXZgNHMgYX5PRf/3jlnOELwsx9P5FQ4hiGwX vzKd7nFV5ja3l1RwHE4wa20iNOAQHmqyVXiDA= 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=CbmvNTfC2Q0sl6dTe4aB9f4qRWG8djUkf97QFijCsF0=; b=HIuuy+v3D01iyfrReYjrxrFyVdAwDE9dWdIh13g8Wqf/JACB8DSat2JTCKEFoEOAvN 4CEjD69sXyQxznIW8FOcNJaeUhlD2De5mm/qo7setYWp23s6kpOn13j78PUDuNp9eIGA ZxPlz8i1ctjj5gXKxPnAnAOvff4blXXLcb6zaR2iRrunbVzJjeiI1dEvy91AMQ0ZDgau pK6BDbQ+HQ6rRU60EqZdWa0IP4faXZEMK25iSswymfYoq4aJvyG+Th0TFAHE46aQyGDF PH0+S5n3SotY6gvYCW+vtiPaVsdalehzoh6J9dZCrJVtVXQ59opLEnX277MG6W1Javj0 Nj9g== X-Gm-Message-State: APf1xPBlMt9PCQI/y1QkKYDVpxk7E78HR8/Kq9EKNV3X+1gGDAp8GcaA g8AOzfVSv0cAe6i6ycAaPmdQKQ== X-Received: by 10.28.120.19 with SMTP id t19mr2434534wmc.53.1517935710642; Tue, 06 Feb 2018 08:48:30 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id s206sm6619035wme.4.2018.02.06.08.48.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:22 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id EC0843E06B0; Tue, 6 Feb 2018 16:48:15 +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, 6 Feb 2018 16:48:02 +0000 Message-Id: <20180206164815.10084-10-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 09/22] 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. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- fpu/softfloat-specialize.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -- 2.15.1 diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index de2c5d5702..4be0fb21ba 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -445,9 +445,10 @@ 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: + /* ARM mandated NaN propagation rules (see FPProcessNaNs()), take + * the first of: * 1. A if it is signaling * 2. B if it is signaling * 3. A (quiet) From patchwork Tue Feb 6 16:48:03 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: 127045 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3096542ljc; Tue, 6 Feb 2018 09:00:23 -0800 (PST) X-Google-Smtp-Source: AH8x224hDCvbMi9Aces4FZZzOUltnO1QW6cIV26+a2oCvCIvxcmtjC/oVcvf1JEK/uV5WlLwOZly X-Received: by 10.37.147.144 with SMTP id a16mr1879857ybm.137.1517936423425; Tue, 06 Feb 2018 09:00:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936423; cv=none; d=google.com; s=arc-20160816; b=I9KDaDQprI2/ciELlKJ78r3euepu40EcVJjskfI46C0OibkBcenyzv4j8biUDvc9CF 6ozFb7Y0fobgkEcPyZ/VLF0c856tN6DeuhtZK9z1XnhiPg0eGNW6i/uCCveRkMwQlsq4 OyYYQK3GXVNlCDJXXjokdQlLYDR18Z0N/3KtlE1+mcy9RdpG9AtQcpBI2vzLEzfVKcZM UXI76zzvyH37ZhPdXiOv475YEdGGRSRCxaaG/zDvDJFSH4Yss87+qqCyxgOoj1aApfDO Fu5ZPrWOCb+rmmzeFzerymaL1h/Lfdy0w2t+At98dVMloZulzneXWYI0YTMO/AQChVLD bZkA== 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=mxxgOfnozx7cvpkKXjRfz6cqqxRGu0Az+qLPzYygsUA=; b=I45QKuf/POZyw2jtCSoLLQaRKYfaGkPns7xBDtdWWMf+cZKfMnatYymLV8wAd0V5xV fxZf91T5af/k9kMEPRahvd44y3b0qHh2ZyQwgWA3UEC8bxXOW5tXGH2ovARfTmfjQXro k0trFYkLKVHSRWceMGm/pm+kSe+bYSkfENcdTRVyr8AupgHyppZTn6nhc78K482qrs7o VnOkaVdO5+vOl9rHl2Ca1O2+gG6kcpuNQaop/C/IlNcKUZuV6PkY6zRZDGFAFIWdXpHQ vxDNYlzW65oLo9JDvn9FARdZniE6fSE1UxFOoHM9yT7GnSAwkuKlMNfPFUp8z9et1WdO 9Bqg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=HrQqfTSF; 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 x13si1332875ybm.27.2018.02.06.09.00.23 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 09:00:23 -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=HrQqfTSF; 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]:37968 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6bW-0002Ya-No for patch@linaro.org; Tue, 06 Feb 2018 12:00:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33573) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Q4-0000bF-BH for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Q3-00052X-8P for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:32 -0500 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:37927) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Q2-00052A-Tp for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:31 -0500 Received: by mail-wm0-x242.google.com with SMTP id 141so5103685wme.3 for ; Tue, 06 Feb 2018 08:48: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=mxxgOfnozx7cvpkKXjRfz6cqqxRGu0Az+qLPzYygsUA=; b=HrQqfTSF3Ql5uc89yvMQVpp9RfyRjZTpEYnxgRUacvhQosHB5exTvBB3l+6PnsZJra BiJYAVD/N70wXkQd/1EBGyfHDImDOjkU6tHxdnoRGcdEWICSBAc+yokAGgVJcwMHua72 rDB98ckiprQd/ChyXdyrnPhfjdKOnH66GaLl0= 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=mxxgOfnozx7cvpkKXjRfz6cqqxRGu0Az+qLPzYygsUA=; b=SAxwJU6UvNGiPnHxR/l1P5Zq6W9UHuudfMhUTtn7lmWJGMmCnEjWcOUMOTXyjosUWy bdx6/QQzBxZfpVQXX0ULxbs9IDGtgDNkGdpUzrwXLCJs09nVtUWhEWXpNsXIa2XwXPBA wfOOODxFRbi4Ibcluef1GAYtstf6+Re9ktXT47uJBK68nYj13bZ+sXJ5Rne59Xd/8MTM 66yx3G95SduGIWUkFB0p/9Z1k4OmDciI4UIYYZr4/Ly9LtxWSPjUk2BKWJAbpjmzQMJZ R0YR8zLFPpD4eJLnD9FffneE8m4SPg+h0S8j5E2zhn3w+lovZfeSkowC96s4tRhbGYoT NMnQ== X-Gm-Message-State: APf1xPCVUj5z3pyfcTt/VUsGf6gAVPaQrDLnfgMLKAnSNpnaFi5bqhlC c4ldQhJpwLLZtRC4R8CIiPv01Q== X-Received: by 10.28.118.13 with SMTP id r13mr2289703wmc.95.1517935709756; Tue, 06 Feb 2018 08:48:29 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id x65sm6372052wmg.29.2018.02.06.08.48.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:22 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 09CCB3E074C; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:03 +0000 Message-Id: <20180206164815.10084-11-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 10/22] 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 Reviewed-by: Peter Maydell --- v2 - fix minor white space nit --- fpu/softfloat.c | 120 +++++++++++++++++++++++++------------------------------- 1 file changed, 54 insertions(+), 66 deletions(-) -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3a4ab1355f..297e48f5c9 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 Feb 6 16:48:04 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: 127041 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3095281ljc; Tue, 6 Feb 2018 08:58:52 -0800 (PST) X-Google-Smtp-Source: AH8x225QMuVVNEvaPqzyYKrAf0Itx7WNBsfcV5rbluoAK9uWhVxJdrCmrqWUl8iE2s8Y/If/vYO6 X-Received: by 10.37.196.68 with SMTP id u65mr1948187ybf.487.1517936332245; Tue, 06 Feb 2018 08:58:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936332; cv=none; d=google.com; s=arc-20160816; b=TYokv7LrbSL6Jjv168PFczIJSK53OK7bcLkLcxAp+qUohXfdvAFxgrD6+jkaLJpwbs q3omQPt3in+yVbr0XSBA55EyubkRvo+LJt4r4smw+MoOeOJNDQMmA2Ja7r0eoBcaL2YN JnZL64taHA48oWvsKPMMvOnqB9eloPEEIXQaEaYWTf7DH5s/nOYZlWIel7PRgZUsOlA+ /xcbhc6QjujOOoLLxwNixBjdx+OpTO6e7Wree20Wxi0F1BNdtYYMgFm2QksrUs3snCZ1 0utbE1deirLFHprWZ95JDaiAE4jbBF2LnMPE/dhlY4DrQ4NoARCOdR9cU3D1E+jXR3Db HsXg== 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=QSk7rvTnRN7zVjOz/qnoI6MD7fqHW+3DEcMId0sEPMc=; b=iaJF+fbHg/9LN13cs/+4tlpYyaPM/CJolnX8fAeDt9XWzmzYORUJpa7T4WXbZkrzrS rLP+faGUkHVMJHS1lKEUnytuzyBC2FfSOQ2OjIVLh64dnWZNjW9j4lgsJoGYHq/RCDAH guriYPg2cSosINpVxZotuMCX+o3TsiyIqIiOTHWNuf+Eb2E7uTpA+R++3tms6zIEpn2F n+my7TWtmdHN/i7CA2aHC4nTfbN4hWL7hd/AnWdKRt4LJO/+OmfPIb6pk8nx1NPF7cgn 2P0BlIK9ogf0kmQWCq/L+T0SYbvxPHSpljm3JASS2Lp50OSzo/MxRQU3NsmES+SnUVYG Wo3g== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Krblsqv3; 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 o2si1896949ywo.450.2018.02.06.08.58.52 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:58: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=Krblsqv3; 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]:37851 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6a3-0001kY-H2 for patch@linaro.org; Tue, 06 Feb 2018 11:58:51 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35804) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Wc-0007DN-Ug for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6WY-0001Z1-5G for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:19 -0500 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:32773) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6WX-0001YK-Lp for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:14 -0500 Received: by mail-wm0-x243.google.com with SMTP id x4-v6so18722029wmc.0 for ; Tue, 06 Feb 2018 08:55:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QSk7rvTnRN7zVjOz/qnoI6MD7fqHW+3DEcMId0sEPMc=; b=Krblsqv3PsaxUhoAsATH1m8cxStu/2Izs99DyFqZAaTdd9zVBWlWOj/qaAu/u8W/L5 5yA8kRrkY1nC0lzHHyVPfUHRDXMtFTsfy8Z5/8eevjOETgF9lDItkTN5m0T5EXcexU1B qr37gc6SnjClA/zsejfPvhlDthsmL2MRJvi7I= 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=QSk7rvTnRN7zVjOz/qnoI6MD7fqHW+3DEcMId0sEPMc=; b=cjBsFD4lNTagZ1EanatKuwb7eZlEmJFGbc7bkLqcT1NuJ9asyvb1N62qJfvRWzlyBw xYdngUu8m1qJUPWFVkBI51utnZYM3UwQgUxm5UPWLUlqox9XKgF68uwocPb2JsYqTYfK V0HcydePakORszBFo+17SSWRfRxAB1sxAOMCQNs/E8xDrbe4qEDHLC4FYWvsNcVXnf0m InzhtJbS8NADfCumdA8HNGNXzodyCAk1d0Aoo2wRdWUTEu+BcldVTuyD/4W7yJ0TEUJO Ve+k88WeLqb2cq0lAZpEHSw8/MavGffKYoqiGlBSei+Du55XC476i6VBvMc1zpvSAbVd WwOQ== X-Gm-Message-State: APf1xPALVlThOmB5nLaYgN5ARQijJzMhPbtEXpoBusB6G9zIiPeDLvoA twWNaGRetjzk6EFL7Vji5yNTdg== X-Received: by 10.28.107.134 with SMTP id a6mr2424828wmi.136.1517936112496; Tue, 06 Feb 2018 08:55:12 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id y55sm17962590wry.87.2018.02.06.08.55.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:55:11 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 1BF5A3E079E; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:04 +0000 Message-Id: <20180206164815.10084-12-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 11/22] 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 Reviewed-by: Philippe Mathieu-Daudé --- v3 - comment box style - CamelCase structs - hide DECOMPOSED_BINARY_POINT - frac in macro - more comments - add exp_size, frac_size to FloatFmt - compute exp_bias and exp_max from FLOAT_PARAMS - remove include bitops (in next patch) --- fpu/softfloat.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 297e48f5c9..568d555595 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -83,7 +83,6 @@ this code that are retained. * target-dependent and needs the TARGET_* macros. */ #include "qemu/osdep.h" - #include "fpu/softfloat.h" /* We only need stdlib for abort() */ @@ -186,6 +185,91 @@ static inline flag extractFloat64Sign(float64 a) return float64_val(a) >> 63; } +/* + * Classify a floating point number. Everything above float_class_qnan + * is a NaN so cls >= float_class_qnan is any NaN. + */ + +typedef enum __attribute__ ((__packed__)) { + float_class_unclassified, + float_class_zero, + float_class_normal, + float_class_inf, + float_class_qnan, /* all NaNs from here */ + float_class_snan, + float_class_dnan, + float_class_msnan, /* maybe silenced */ +} FloatClass; + +/* + * Structure holding all of the decomposed parts of a float. The + * exponent is unbiased and the fraction is normalized. All + * calculations are done with a 64 bit fraction and then rounded as + * appropriate for the final format. + * + * Thanks to the packed FloatClass a decent compiler should be able to + * fit the whole structure into registers and avoid using the stack + * for parameter passing. + */ + +typedef struct { + uint64_t frac; + int32_t exp; + FloatClass cls; + bool sign; +} FloatParts; + +#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. + * exp_size: the size of the exponent field + * exp_bias: the offset applied to the exponent field + * exp_max: the maximum normalised exponent + * frac_size: the size of the fraction field + * frac_shift: shift to normalise the fraction with DECOMPOSED_BINARY_POINT + * The following are computed based the size of fraction + * frac_lsb: least significant bit of fraction + * fram_lsbm1: the bit bellow the least significant bit (for rounding) + * round_mask/roundeven_mask: masks used for rounding + */ +typedef struct { + int exp_size; + int exp_bias; + int exp_max; + int frac_size; + int frac_shift; + uint64_t frac_lsb; + uint64_t frac_lsbm1; + uint64_t round_mask; + uint64_t roundeven_mask; +} FloatFmt; + +/* Expand fields based on the size of exponent and fraction */ +#define FLOAT_PARAMS(E, F) \ + .exp_size = E, \ + .exp_bias = ((1 << E) - 1) >> 1, \ + .exp_max = (1 << E) - 1, \ + .frac_size = F, \ + .frac_shift = DECOMPOSED_BINARY_POINT - F, \ + .frac_lsb = 1ull << (DECOMPOSED_BINARY_POINT - F), \ + .frac_lsbm1 = 1ull << ((DECOMPOSED_BINARY_POINT - F) - 1), \ + .round_mask = (1ull << (DECOMPOSED_BINARY_POINT - F)) - 1, \ + .roundeven_mask = (2ull << (DECOMPOSED_BINARY_POINT - F)) - 1 + +static const FloatFmt float16_params = { + FLOAT_PARAMS(5, 10) +}; + +static const FloatFmt float32_params = { + FLOAT_PARAMS(8, 23) +}; + +static const FloatFmt float64_params = { + FLOAT_PARAMS(11, 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 Feb 6 16:48:05 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: 127053 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3104204ljc; Tue, 6 Feb 2018 09:07:31 -0800 (PST) X-Google-Smtp-Source: AH8x224LAX5dFjy6gR47YhoqvcMU1K2Z057cM0sGTXiYOS13W+oMWvmvyclQjV0Ig7j5GX1J+NJB X-Received: by 10.37.16.6 with SMTP id 6mr1971723ybq.119.1517936676751; Tue, 06 Feb 2018 09:04:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936672; cv=none; d=google.com; s=arc-20160816; b=CcMnpfRWFc+h++bxRj+tWSfStaUvuqtDtjD+2atLCh3kMTk2kF3J/SQ/MXsESFL1XA /xiTbbAo9Hsu2AQR50N/IJb2Ja01Q1cGgpm5MQRUuNDcJIFVcZQPbKria9PUHIf7RAPg NaZqAwUzJLaIy8xdSgEIi7mxMMxnOjotTaniw10UIDSS1IC1I/bNs2QUVQ4TcHEy8mI/ Oyn9uDKh+4D7TR3VEVGttbfNSCrDEg9y1LNvab+BdF9V6W32SiEmNl0SHwNNZTOM7Aw4 W7UQqRVk/wRoZw7i0UaMrlbTcwfQXRufegIuKd6sDN7Rk/eUdIoV6OljRPEW4OYAe/o+ oT2w== 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=k0J51Z7H2xOYCsaz0UTu7PvMPj/8W2G9ltsFzf17aEM=; b=LpZkq6ck+y4uj178IovNEs6wMBRu74NZgKzrITIHY2Z7PfLk/NrmljClDVr489lT9L 0+n81/U6gpS7uGHIgqAMzft2mmi0QzYnln5TQFp7S5t0fICrp24A/+DyMheVNkeJAahT 9ofSh9t/c79O4pQ40uO6sVMJn7sUeoXeZELWwYTbfbYC0ICzwhnQPRy5V2IZtl1cmq4v 4Kc1yi91Rx61QKrcBRyLiGCOi0sfR1QWKEP43GA/9JkXTG56+nhakaOKlY+v/J/sY95J AIc74dz+ijFFNftP/2OR6dQHYr4YwvjPW9atPX2jgpJVpYQASmLo5HqiagTzowKdSvSI 0rpw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=TOuv+N2i; 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 130si821648ybt.0.2018.02.06.09.04.32 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 09:04:32 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=TOuv+N2i; 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]:38136 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6fY-0005md-1p for patch@linaro.org; Tue, 06 Feb 2018 12:04:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35877) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Wg-0007K5-8F for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Wc-0001gV-T0 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:22 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:36686) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Wb-0001dZ-KG for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:18 -0500 Received: by mail-wr0-x241.google.com with SMTP id y3so2675743wrh.3 for ; Tue, 06 Feb 2018 08:55:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=k0J51Z7H2xOYCsaz0UTu7PvMPj/8W2G9ltsFzf17aEM=; b=TOuv+N2i98JHjZkoPuq+c+gZw47tqi468RorPASd/Fn8rzcVHfQLYKCnN1kbVZHoDS 5vzkYRjNML2vK3kWA7yBD3A7AHChB++9AP+Jve6jzB+uZUSC2wGV3kk7o0EixbYCOuCR +18CiLlklNuseQgPEoKi8bPsoLjF5xztkjBJ0= 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=k0J51Z7H2xOYCsaz0UTu7PvMPj/8W2G9ltsFzf17aEM=; b=eloJY4XVPNKxvO6R/VKFpqfhBQ07knUrVuxoB7WKbjXkzZyQbvJeyqdHf1UDT0eJR1 FdF1ckxeS8HDt32Ov9n2ItdzHuwZYC18s9ssSu/HWLGTRcgl8edopSo1jfrqxmln6B7q At0gtSJLPpNqIudCppCynKLNtwNntnH2+rNURMQ362l5WbRM4vy0MoinSqk22WQDG02r +5rIp7840Y5RjLEvvYelXeHp15KI1430X8lutqts9zMR2fPyK14EodLWhF3xh1kSo1Z/ 14KB4s3PfdhzD44GP3iOGVdL2pft+7OMhSds1Jhw1aXgVgZ6XeDEQUfBD6q3MmYO2HAj MrBw== X-Gm-Message-State: APf1xPA/CXDd/UPebCjPjz39hx9Gm3AvR5IWndhBZWmx+bmSMpS0XyNd s9Yt/mVPvIUY1Xa+1muadZCO9g== X-Received: by 10.223.171.67 with SMTP id r3mr2604527wrc.80.1517936115991; Tue, 06 Feb 2018 08:55:15 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id u43sm7237494wrf.63.2018.02.06.08.55.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:55:11 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 2FAD43E08E8; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:05 +0000 Message-Id: <20180206164815.10084-13-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 12/22] 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 Reviewed-by: Philippe Mathieu-Daudé --- v3 - renames for FloatParts - shorten internal names - fix comment style - use FloatFmt values for for extract/deposit in raw_pack/unpack - move #include bitops from previous patch - add is_nan helper - avoid temp variables where we can v4 - fewer lines for pack_raw - is_nan/is_snan/is_qnan with unlikey() annotation for is_nan - pick_nan_parts -> pick_nan - __attribute__((flatten)) for public facing functions --- fpu/softfloat.c | 892 +++++++++++++++++++++++++----------------------- include/fpu/softfloat.h | 4 + 2 files changed, 469 insertions(+), 427 deletions(-) -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 568d555595..2190e7de56 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -83,6 +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() */ @@ -270,6 +271,470 @@ static const FloatFmt float64_params = { FLOAT_PARAMS(11, 52) }; +/* Unpack a float to parts, but do not canonicalize. */ +static inline FloatParts unpack_raw(FloatFmt fmt, uint64_t raw) +{ + const int sign_pos = fmt.frac_size + fmt.exp_size; + + return (FloatParts) { + .cls = float_class_unclassified, + .sign = extract64(raw, sign_pos, 1), + .exp = extract64(raw, fmt.frac_size, fmt.exp_size), + .frac = extract64(raw, 0, fmt.frac_size), + }; +} + +static inline FloatParts float16_unpack_raw(float16 f) +{ + return unpack_raw(float16_params, f); +} + +static inline FloatParts float32_unpack_raw(float32 f) +{ + return unpack_raw(float32_params, f); +} + +static inline FloatParts float64_unpack_raw(float64 f) +{ + return unpack_raw(float64_params, f); +} + +/* Pack a float from parts, but do not canonicalize. */ +static inline uint64_t pack_raw(FloatFmt fmt, FloatParts p) +{ + const int sign_pos = fmt.frac_size + fmt.exp_size; + uint64_t ret = deposit64(p.frac, fmt.frac_size, fmt.exp_size, p.exp); + return deposit64(ret, sign_pos, 1, p.sign); +} + +static inline float16 float16_pack_raw(FloatParts p) +{ + return make_float16(pack_raw(float16_params, p)); +} + +static inline float32 float32_pack_raw(FloatParts p) +{ + return make_float32(pack_raw(float32_params, p)); +} + +static inline float64 float64_pack_raw(FloatParts p) +{ + return make_float64(pack_raw(float64_params, p)); +} + +/* Canonicalize EXP and FRAC, setting CLS. */ +static FloatParts canonicalize(FloatParts part, const FloatFmt *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 FloatParts round_canonical(FloatParts p, float_status *s, + const FloatFmt *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 FloatParts float16_unpack_canonical(float16 f, float_status *s) +{ + return canonicalize(float16_unpack_raw(f), &float16_params, s); +} + +static float16 float16_round_pack_canonical(FloatParts 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 = round_canonical(p, s, &float16_params); + return float16_pack_raw(p); + } +} + +static FloatParts float32_unpack_canonical(float32 f, float_status *s) +{ + return canonicalize(float32_unpack_raw(f), &float32_params, s); +} + +static float32 float32_round_pack_canonical(FloatParts 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 = round_canonical(p, s, &float32_params); + return float32_pack_raw(p); + } +} + +static FloatParts float64_unpack_canonical(float64 f, float_status *s) +{ + return canonicalize(float64_unpack_raw(f), &float64_params, s); +} + +static float64 float64_round_pack_canonical(FloatParts 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 = round_canonical(p, s, &float64_params); + return float64_pack_raw(p); + } +} + +/* Simple helpers for checking if what NaN we have */ +static bool is_nan(FloatClass c) +{ + return unlikely(c >= float_class_qnan); +} +static bool is_snan(FloatClass c) +{ + return c == float_class_snan; +} +static bool is_qnan(FloatClass c) +{ + return c == float_class_qnan; +} + +static FloatParts pick_nan(FloatParts a, FloatParts b, float_status *s) +{ + if (is_snan(a.cls) || is_snan(b.cls)) { + s->float_exception_flags |= float_flag_invalid; + } + + if (s->default_nan_mode) { + a.cls = float_class_dnan; + } else { + if (pickNaN(is_qnan(a.cls), is_snan(a.cls), + is_qnan(b.cls), is_snan(b.cls), + 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 or subtracting the values of the + * floating-point values `a' and `b'. The operation is performed + * according to the IEC/IEEE Standard for Binary Floating-Point + * Arithmetic. + */ + +static FloatParts addsub_floats(FloatParts a, FloatParts b, bool subtract, + float_status *s) +{ + bool a_sign = a.sign; + bool b_sign = b.sign ^ subtract; + + if (a_sign != b_sign) { + /* Subtraction */ + + if (a.cls == float_class_normal && b.cls == float_class_normal) { + if (a.exp > b.exp || (a.exp == b.exp && a.frac >= b.frac)) { + 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 (is_nan(a.cls) || is_nan(b.cls)) { + return pick_nan(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) { + 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; + } + return a; + } + if (is_nan(a.cls) || is_nan(b.cls)) { + return pick_nan(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 __attribute__((flatten)) float16_add(float16 a, float16 b, + float_status *status) +{ + FloatParts pa = float16_unpack_canonical(a, status); + FloatParts pb = float16_unpack_canonical(b, status); + FloatParts pr = addsub_floats(pa, pb, false, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 __attribute__((flatten)) float32_add(float32 a, float32 b, + float_status *status) +{ + FloatParts pa = float32_unpack_canonical(a, status); + FloatParts pb = float32_unpack_canonical(b, status); + FloatParts pr = addsub_floats(pa, pb, false, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 __attribute__((flatten)) float64_add(float64 a, float64 b, + float_status *status) +{ + FloatParts pa = float64_unpack_canonical(a, status); + FloatParts pb = float64_unpack_canonical(b, status); + FloatParts pr = addsub_floats(pa, pb, false, status); + + return float64_round_pack_canonical(pr, status); +} + +float16 __attribute__((flatten)) float16_sub(float16 a, float16 b, + float_status *status) +{ + FloatParts pa = float16_unpack_canonical(a, status); + FloatParts pb = float16_unpack_canonical(b, status); + FloatParts pr = addsub_floats(pa, pb, true, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 __attribute__((flatten)) float32_sub(float32 a, float32 b, + float_status *status) +{ + FloatParts pa = float32_unpack_canonical(a, status); + FloatParts pb = float32_unpack_canonical(b, status); + FloatParts pr = addsub_floats(pa, pb, true, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 __attribute__((flatten)) float64_sub(float64 a, float64 b, + float_status *status) +{ + FloatParts pa = float64_unpack_canonical(a, status); + FloatParts pb = float64_unpack_canonical(b, status); + FloatParts pr = addsub_floats(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 @@ -2081,220 +2546,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 | `a' and `b'. The operation is performed according to the IEC/IEEE Standard @@ -3891,219 +4142,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 23824a3000..693ece0974 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -236,6 +236,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 Feb 6 16:48:06 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: 127054 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3105270ljc; Tue, 6 Feb 2018 09:08:41 -0800 (PST) X-Google-Smtp-Source: AH8x225yuKWcYe8AeMqBXyExkVcBVjIpSRF6z4Tb9GHL1VnvGxDjuFyusLnjAlhxWZM8Lzs11itt X-Received: by 10.129.146.130 with SMTP id j124mr1810077ywg.256.1517936921395; Tue, 06 Feb 2018 09:08:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936921; cv=none; d=google.com; s=arc-20160816; b=KiFCm86Zcc41AV+gvT94k2C/g8J2cyTkVhkEiUfhuJxqwWokoynodyE3WDCCOL6MYF qsXuKGOCLEyW4AUR2MLF3E/1hgpl1w18UjwNjI9SPKfZu1Nn3uews658aWdHXxHGXxuT 5aU9zYQc1ZL/S+4/O2e1/ldgMHE77Ve7RJacgLxwXP57cP0FYh2IfhUtTlakOASlWXzK a9g1q6eUq2fqR7KYdNIYDtq2W+SLq6lW53mMinXFVbkBp+Db4zSj+KVJV3yHuX6AlSZq Fc0n/2WXEvspFqRxBOdQNw4OzG5AO7eBbvFNfiw2fUdIDaRbV4KT6uzi+xM6Dx2fWuYa 8/wg== 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=aTitF/vZy4JI1OnQKvYEhvf7JtMp6QhCJ32FMblYvC4=; b=F4DoGyYvRP2MP9nqEITcKj4riyAs6zgNYXRV+ILy+bT00X6zYnQfED8RSo3uhU9itY QeEwcWeAIBXW3XlawPFjcpIu00GvMjA+BL4Lk6LyXPDKFQfc2mMy9RLSGWH0l9F9MDmg mS6smtbooKE9/ZorVMuuZn8nNg2f9/Wod3GIwoFUPqHPGtn+I5llbSBA4g3F5kXy9HIt LcTw/DvOdhZwcIX8QfoDjiVRBvpJCpDn4tmGHaRtf8pPLl0Qub8aQqv5IlPz4we32YJ7 P1MsfTjHxav6TdtP3kiz+Vm8M9c+BobpiADtku0itB9lapSkIJh39eC6EeRBwnXI2yi9 NwVg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=E1FpL3MI; 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 e68si1914248ywa.793.2018.02.06.09.08.41 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 09:08:41 -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=E1FpL3MI; 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]:38385 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6jY-00012j-KN for patch@linaro.org; Tue, 06 Feb 2018 12:08:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35917) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Wi-0007Oo-9y for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Wd-0001hO-J2 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:24 -0500 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:36384) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Wd-0001fx-1V for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:19 -0500 Received: by mail-wm0-x243.google.com with SMTP id f3so5206776wmc.1 for ; Tue, 06 Feb 2018 08:55:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=aTitF/vZy4JI1OnQKvYEhvf7JtMp6QhCJ32FMblYvC4=; b=E1FpL3MIkayk2q+PhF/kiz7RqhwmqBuQw7akDkz1lvuIENed8DXD//mD8nT26OWUrP lP+cAqRgleWldMrmxXrvweA6FtPc0ZfXG0cX348sE86mbF2uGnj5ZOs3/gMaPcG9eKTt 6LHVSiYiioOEDmgawSe5F4R1Z4b+6ZAz2tjG0= 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=aTitF/vZy4JI1OnQKvYEhvf7JtMp6QhCJ32FMblYvC4=; b=FDvgsa422NpXx7g/EeHL1IA6WBRPJDYE9+OyW91juCW+s1DahpgB3pLrSLB5Vm4HIM SwF8WM23FQ7iyaN6JrvPZiZWDs9vwI1+eJ873tW3QNgvF+NafTCNoVCpLVAnb80yV0QY FCrkd4l3G4JoqpB/Gk3E0WJMD6slJzyWBOHJN6uXfx9EOQsvewWy5TMbHtJdszYJ3z1S VwiUOxklY85qAnLDtBcDXbUxVtfx+/IsMBTJsR4Z0UkAyVgW421ospTFFMmNlu7jYhbi ClKFwRxX309ZdrgXBiTgIet+9zfqaOkSc5eNt/Ajz6kTTahIfWCXkyAmbE7MGblreLVg vjpw== X-Gm-Message-State: APf1xPDqsV0iIgInwQ3nInCkaYVOiO/3ZHizVpPWjVmL69+aMsUkI1Yr AVuvaHUD5M8+zuReFKjcFnebbw== X-Received: by 10.28.170.195 with SMTP id t186mr2538701wme.93.1517936117673; Tue, 06 Feb 2018 08:55:17 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id e15sm6552374wmh.39.2018.02.06.08.55.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:55:16 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 433A73E08F9; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:06 +0000 Message-Id: <20180206164815.10084-14-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 13/22] 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 --- v3 - mul compile fixes for new names - remove duplicate s-o-b - more explicit inf * zero check v4 - use is_nan - pick_nan_parts/pick_nan --- fpu/softfloat.c | 209 +++++++++++++++++++----------------------------- include/fpu/softfloat.h | 1 + 2 files changed, 82 insertions(+), 128 deletions(-) -- 2.15.1 Reviewed-by: Peter Maydell diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 2190e7de56..6d29e1a103 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -735,6 +735,87 @@ float64 __attribute__((flatten)) float64_sub(float64 a, float64 b, 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 FloatParts mul_floats(FloatParts a, FloatParts 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 (is_nan(a.cls) || is_nan(b.cls)) { + return pick_nan(a, b, s); + } + /* Inf * Zero == NaN */ + if ((a.cls == float_class_inf && b.cls == float_class_zero) || + (a.cls == float_class_zero && b.cls == float_class_inf)) { + 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 __attribute__((flatten)) float16_mul(float16 a, float16 b, + float_status *status) +{ + FloatParts pa = float16_unpack_canonical(a, status); + FloatParts pb = float16_unpack_canonical(b, status); + FloatParts pr = mul_floats(pa, pb, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 __attribute__((flatten)) float32_mul(float32 a, float32 b, + float_status *status) +{ + FloatParts pa = float32_unpack_canonical(a, status); + FloatParts pb = float32_unpack_canonical(b, status); + FloatParts pr = mul_floats(pa, pb, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 __attribute__((flatten)) float64_mul(float64 a, float64 b, + float_status *status) +{ + FloatParts pa = float64_unpack_canonical(a, status); + FloatParts pb = float64_unpack_canonical(b, status); + FloatParts pr = mul_floats(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 @@ -2546,70 +2627,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' @@ -4142,70 +4159,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 693ece0974..7fc63dd60f 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -239,6 +239,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 Feb 6 16:48:07 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: 127050 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3097831ljc; Tue, 6 Feb 2018 09:01:25 -0800 (PST) X-Google-Smtp-Source: AH8x224wgKZYUFhhZXO+uqhUAMLmm+QdU5JRqkncKq3xlfNhf0RXNahimP9cjFjU5gsKiBUMjPo2 X-Received: by 10.129.85.74 with SMTP id j71mr1846644ywb.328.1517936484806; Tue, 06 Feb 2018 09:01:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936484; cv=none; d=google.com; s=arc-20160816; b=RYRZnEMvomJoq+w5TQntatIdR/vJaRghvJb5PtkHd8wZ2pFcVOTsNKGlsQR8pBvtRG Rjz+nnmaHyjcTj1Gm3/nbm3I+zLAJ2kSzZ6PIurb7K4j8LvDtcXgg4OBOxE2Cipo4MPr T7+pwC8wpcbPdo/lLBSLPsCl+OZNLrFc6r+Ynq0oFqFgDwcfRvyDocwC6nNldXx65oAw 2wXz7BFjrtr7+gfSy55T7WlywBu0QBo1HIHlE5VZxq7YQ9ugjz6kVPmqa9X0nGXiC/ke 9RYjUsYWnMKGn2mOILEGz63x3ZyTAGOZYF1GT84OtEaObPrCG28885LRdKGjXAun+PRc h9Dw== 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=8HsFvyiGvdyq9W8Io7SzbAjMdYcYQbYTsxX5ab8g1rQ=; b=fgNS9CZ4QBOSb7vCTNz9SuWXMYZNfWlS/uKUzSc7SBKBKaOW4c9Bd1TB4hsFMvonWF j/yMzb9ENw1wBfTO71QmbNKOmSY4mT/Ybhva3vau4WGv14OopZX7SpxsGfCYgcsEkkSn aQJFyj3+y+63sLSXDcqWF7kigv0KjHfQyTKe7I2eI7g4a2DV0in0/wp5F+7OuVPoHgEE u91jM4U99s7HBTrbaX7G+L4nnHO4D8W6KHI8s6n6vsn0oiWhXC68eBYEsAm//C/xC54Q PsUVOiIH0CshIYqfd6IJgabsy9JBFsMjGL/k17tyYWez/Pk4KmCEJIXFdVY/r1eAEzoX CIjQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=NnzIp3xN; 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 n84si1260528ybb.833.2018.02.06.09.01.24 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 09:01: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=NnzIp3xN; 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]:38022 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6cW-0003yp-1p for patch@linaro.org; Tue, 06 Feb 2018 12:01:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33611) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Q7-0000ex-Ds for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Q5-00056Y-9N for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:35 -0500 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:55164) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Q4-00054U-VF for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:33 -0500 Received: by mail-wm0-x242.google.com with SMTP id i186so4988468wmi.4 for ; Tue, 06 Feb 2018 08:48:32 -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=8HsFvyiGvdyq9W8Io7SzbAjMdYcYQbYTsxX5ab8g1rQ=; b=NnzIp3xNWhyKPHRnhVmTYEHIOcsxRlys5TMAxGEYgH9boU5vJuPaweN90scQDuAUbT iStz5oVJ3dfOW7fbzcxxuc1qzC+ejCukNlnBcuQ9hk5zol2qmXw7MQqRElIvMYJPVwG0 aXay6hfpmRj19qBfeeool/83bAUrv7/M5jyOQ= 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=8HsFvyiGvdyq9W8Io7SzbAjMdYcYQbYTsxX5ab8g1rQ=; b=PQmP1Dx++qG4iqsUW/0SA6+31S4p9i6oJDCIjAv/FpdLxuv1wr6KEywE0fHTGn4Rwg XUIIwE3VxLKniYiXmfKl+d/Gkl8kZlYuDFnc3AmTTv93wx8rm6AXmxWK2q+C9zmHhxn1 PWZPRwYoORJyLyy45Y2bHHBkjk5wKtk2bavFbzPMJ1rsni3/CBML/HKpm/wxJriW1byO sdCVlAAIZm5W6xr20AoyVjJ0fv4w1BwOfZuTUt23sJ2ChUfIV3i4EL4BkJro1oQUs8I9 xA/pnl29y1Diaoj1BbeyFSLnzVqakpd/fD51Rho+8hFTTOvdKp01OZW3dWZkbxmv6Fgs YaEA== X-Gm-Message-State: APf1xPCapMDB5SG0Ezq0TKAA7nGYhLwY8w4X6MiEOPx+ITgT790dN1TJ Wb0LjGLmoc4lsotkzSBRgzm2ZA== X-Received: by 10.28.168.8 with SMTP id r8mr2558009wme.157.1517935711683; Tue, 06 Feb 2018 08:48:31 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id m11sm22541416wrf.75.2018.02.06.08.48.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:23 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 57D4B3E0946; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:07 +0000 Message-Id: <20180206164815.10084-15-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 14/22] 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 --- v3 - rename functions and structures v4 - use is_nan - better attribution for div128To64 - pick_nan_parts->pick_nan --- fpu/softfloat-macros.h | 48 ++++++++++ fpu/softfloat.c | 236 ++++++++++++++++++------------------------------ include/fpu/softfloat.h | 1 + 3 files changed, 137 insertions(+), 148 deletions(-) -- 2.15.1 Reviewed-by: Peter Maydell diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h index 9cc6158cb4..c45a23193e 100644 --- a/fpu/softfloat-macros.h +++ b/fpu/softfloat-macros.h @@ -625,6 +625,54 @@ static uint64_t estimateDiv128To64( uint64_t a0, uint64_t a1, uint64_t b ) } +/* From the GNU Multi Precision Library - longlong.h __udiv_qrnnd + * (https://gmplib.org/repo/gmp/file/tip/longlong.h) + * + * Licensed under the GPLv2/LGPLv3 + */ +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 6d29e1a103..4a859b2721 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -816,6 +816,94 @@ float64 __attribute__((flatten)) float64_mul(float64 a, float64 b, 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 FloatParts div_floats(FloatParts a, FloatParts 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 (is_nan(a.cls) || is_nan(b.cls)) { + return pick_nan(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) +{ + FloatParts pa = float16_unpack_canonical(a, status); + FloatParts pb = float16_unpack_canonical(b, status); + FloatParts pr = div_floats(pa, pb, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 float32_div(float32 a, float32 b, float_status *status) +{ + FloatParts pa = float32_unpack_canonical(a, status); + FloatParts pb = float32_unpack_canonical(b, status); + FloatParts pr = div_floats(pa, pb, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 float64_div(float64 a, float64 b, float_status *status) +{ + FloatParts pa = float64_unpack_canonical(a, status); + FloatParts pb = float64_unpack_canonical(b, status); + FloatParts pr = div_floats(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 @@ -2627,77 +2715,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' | with respect to the corresponding value `b'. The operation is performed @@ -4159,83 +4176,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 7fc63dd60f..85e4a74f1b 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -240,6 +240,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 Feb 6 16:48:08 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: 127055 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3107069ljc; Tue, 6 Feb 2018 09:10:41 -0800 (PST) X-Google-Smtp-Source: AH8x225zHF8qOHamxA/taAxkj+1VLkyk8RsI+hj7++Wnlq0yLZ8cDGj/etKr6r6KVsXvOFiMJBSa X-Received: by 10.37.50.77 with SMTP id y74mr1931286yby.431.1517937041104; Tue, 06 Feb 2018 09:10:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517937041; cv=none; d=google.com; s=arc-20160816; b=l4wacrELsgkf68qkQ4RFrvTBSl3o2i+YevOvgFhiVtJKoZhjloSS08jW72fMQxWrcb fk4DUttFFhhJVPHquvIUvqb3bptEb+2/j7M71IE0J/mvSDNppMG1BFQyjls48xqn8X35 7pcnqXAH1+BROjyObfQUrBpIpfRIxN0TftrHiHooJaQmg7WLFB3wvUUSnYnF2TDKxDaO sl9kiy7oEs1f7hQ3gJ204iWeQiGP8S6zBgN28+UjDiCgygNSU2M/LBjrL01vH8CRVx07 miZ1vX5yaf3gDTK+YL/h6aQxbJ1zd3osBVnpvms8FYebtkAZ6q11LnllZ35XOLVjh8UE MN1w== 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=bmx5Lqqax4VwUQC+H+iGMbr/Gh/RqeFzKQUKhGQLWoE=; b=gIdeJwT4PDiXBDyBQ8yDzmqXYaNl6r82XLmBW4T+axN0kEDuGNmqZqiMEHy7s9SYpF urPBX/UFFZXYWBaAKdJ4kphr0WWTCnoCxBZIE+nOFNl9dTuufhBGAZADSVTiSnPXnARR aTKgaHgjBmqOWRR/sLSetx07RF3OP4DBzLw2gPbteELRe9dqsogswHIxJqsSxF1I75wF oI9INV3CnaOhCerOvX5efgrx5A3Tuuxvq9zgcIVQpp4d2KQxf+zAJlMEQhSF2g5UNa6V O2B1KmWZNXY4cFX1Rk7JLimGLOQwl0F/xG33qSlgaZ3xkm3lQoFxl/N5E7gidno1/E9S dNnw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=K96g3eSU; 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 j125si110762ywf.312.2018.02.06.09.10.40 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 09:10:41 -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=K96g3eSU; 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]:38563 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6lU-0002iq-6H for patch@linaro.org; Tue, 06 Feb 2018 12:10:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35939) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Wj-0007Pw-02 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Wf-0001j3-Ik for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:24 -0500 Received: from mail-wm0-x230.google.com ([2a00:1450:400c:c09::230]:34792) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Wf-0001iK-1E for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:21 -0500 Received: by mail-wm0-x230.google.com with SMTP id j21-v6so18787747wmh.1 for ; Tue, 06 Feb 2018 08:55:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bmx5Lqqax4VwUQC+H+iGMbr/Gh/RqeFzKQUKhGQLWoE=; b=K96g3eSUi6oQS4kNaZ0nuAeu4A06OEUEZmiBSa2MADBZ3hiUwBWRmy/nTxgkzs+dea 0VFLDVgce5eShv4Q9GfALTOhhfLbCf/qjo80mjlIxFx77MZuRAxZJCvXxkf4yNIYdFm1 Y2WcWmYvqULAQ8gfxjhLzSDm2UU3F4pePu1Cc= 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=bmx5Lqqax4VwUQC+H+iGMbr/Gh/RqeFzKQUKhGQLWoE=; b=qy3i3K2PgDgLPpMaWHWPAVZ3JKiKbajRoitgcGzErBZjtqJVIVBh5mim/liPQK2x8U pEGxpBIQC8XE1+x1pa1DWLDLWN5jf2aqn4DKWlmMXclEr3hiNxIwJtMP8RIatFWm9wAC 4WGssp3287OnOClIIJoJuBBiioejFJeN7zQzay8Dn7eqkAvigJSrKl+rIGmC916AiraC CftOogV4WV1Ii16ZagYY1QKb5gIM3sXaMQlC61evSakuPjsuVnwNbSjPoFzC65XCsLbL 4xhTzkO+/5GSZyZqGQKrjXNWIUFO71XO2wOvrCyADKrYGDhK01+RDeqdXitP1A6cX4A2 I4jw== X-Gm-Message-State: APf1xPBZLw39skotu0F8pXaSAwJJE9asKWOyA/3bhF4xeBaqit0wlpa2 27LkDwsF4/I3mAczb/LJbno69g== X-Received: by 10.28.126.138 with SMTP id z132mr2344020wmc.139.1517936119305; Tue, 06 Feb 2018 08:55:19 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id z74sm13465572wmz.21.2018.02.06.08.55.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:55:16 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 6D2CC3E0962; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:08 +0000 Message-Id: <20180206164815.10084-16-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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::230 Subject: [Qemu-devel] [PATCH v4 15/22] 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 --- v3 - rename functions and structures v4 - use is_nan - attribute(flatten) --- fpu/softfloat-specialize.h | 104 ------- fpu/softfloat.c | 742 +++++++++++++++++---------------------------- include/fpu/softfloat.h | 1 + 3 files changed, 272 insertions(+), 575 deletions(-) -- 2.15.1 diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 4be0fb21ba..e81ca001e1 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 4a859b2721..ae4ba6de51 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -580,6 +580,40 @@ static FloatParts pick_nan(FloatParts a, FloatParts b, float_status *s) return a; } +static FloatParts pick_nan_muladd(FloatParts a, FloatParts b, FloatParts c, + bool inf_zero, float_status *s) +{ + if (is_snan(a.cls) || is_snan(b.cls) || is_snan(c.cls)) { + s->float_exception_flags |= float_flag_invalid; + } + + if (s->default_nan_mode) { + a.cls = float_class_dnan; + } else { + switch (pickNaNMulAdd(is_qnan(a.cls), is_snan(a.cls), + is_qnan(b.cls), is_snan(b.cls), + is_qnan(c.cls), is_snan(c.cls), + 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 or subtracting the values of the * floating-point values `a' and `b'. The operation is performed @@ -816,6 +850,243 @@ float64 __attribute__((flatten)) float64_mul(float64 a, float64 b, 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 FloatParts muladd_floats(FloatParts a, FloatParts b, FloatParts c, + int flags, float_status *s) +{ + bool inf_zero = ((1 << a.cls) | (1 << b.cls)) == + ((1 << float_class_inf) | (1 << float_class_zero)); + bool p_sign; + bool sign_flip = flags & float_muladd_negate_result; + FloatClass 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 (is_nan(a.cls) || is_nan(b.cls) || is_nan(c.cls)) { + return pick_nan_muladd(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 __attribute__((flatten)) float16_muladd(float16 a, float16 b, float16 c, + int flags, float_status *status) +{ + FloatParts pa = float16_unpack_canonical(a, status); + FloatParts pb = float16_unpack_canonical(b, status); + FloatParts pc = float16_unpack_canonical(c, status); + FloatParts pr = muladd_floats(pa, pb, pc, flags, status); + + return float16_round_pack_canonical(pr, status); +} + +float32 __attribute__((flatten)) float32_muladd(float32 a, float32 b, float32 c, + int flags, float_status *status) +{ + FloatParts pa = float32_unpack_canonical(a, status); + FloatParts pb = float32_unpack_canonical(b, status); + FloatParts pc = float32_unpack_canonical(c, status); + FloatParts pr = muladd_floats(pa, pb, pc, flags, status); + + return float32_round_pack_canonical(pr, status); +} + +float64 __attribute__((flatten)) float64_muladd(float64 a, float64 b, float64 c, + int flags, float_status *status) +{ + FloatParts pa = float64_unpack_canonical(a, status); + FloatParts pb = float64_unpack_canonical(b, status); + FloatParts pc = float64_unpack_canonical(c, status); + FloatParts pr = muladd_floats(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 @@ -2817,231 +3088,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'. @@ -4265,252 +4311,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 85e4a74f1b..65bc7442d2 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -240,6 +240,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 Feb 6 16:48:09 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: 127049 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3097433ljc; Tue, 6 Feb 2018 09:01:06 -0800 (PST) X-Google-Smtp-Source: AH8x224DNLGYFtBdrCri5tzLBUqmpvDb+E3eflgVd8BFM6vGcS8VY+0JKbsMmXEqpM3DZvDsI3FG X-Received: by 10.129.37.14 with SMTP id l14mr1906064ywl.412.1517936466545; Tue, 06 Feb 2018 09:01:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936466; cv=none; d=google.com; s=arc-20160816; b=NsZ/o5uCUFID8F+UutuVM1YWkmENSt0kc/SO2JPLvjRqSqrf4xLVgKZ0imQLkBWbTe ARccn46SB8gb0hJGM17Dmmn6ypxpm29fNhD59pesqjU13UYw571dUJqt+8l04N2ZsxXr 85YzV5OCyGtJXZ8XT1mJs7o3tyme04N3btywdk+Sly6k/m6F1Qk5SZlyqP4mIabcMTsj l+DY96pbrWoxNC1RIhtzJ1GvXmP2dgnQrnT+YZQs+SeNFcdZcf0sRRXARoT8smvUv7Ua HTMNyXlz8KmYRUshDrY3kVuExISfQPkRqKPg0xpEVqEd7mW7i7MEvqm3Cko4QOLMLNht W2Aw== 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=D4pDJEnOgHOmstbqR+pmy5DTC8NVaaqrBRWWAk1Lzzc=; b=Y/x/HX3beiaEIip5xta3U+kwh7tyBeICQyhHA5VARdVpKn95kIIdOj/pBrK7lnPMh3 G+bdOnLMHygBI/+5qdik5j0AbcK5efY9vAJFFoZ9QOQnjSIBB7A7dNYUYRTV6Kt2yZum EX0Sa2hj6Kje8zBGBL3vTk0qvCRmuTBo7ghQeETyTMB1JZ7w4xhNA6FVdWvHR26JWEi7 uxcVi7BA/6CweffpVFpYaP09m/p3NJHySm0790wbf9EZB/AW/42Rti5DTl8jtjl/qX7q H1L1DV7MlRS6ceMAxv5OOekRLntsf0fhqnsV428qjFedohMlgDyVzC6vM3YyDSuVK1En FrHA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=i18maw7U; 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 e133si1959732ybf.204.2018.02.06.09.01.06 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 09:01:06 -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=i18maw7U; 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]:38010 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6cD-0003m3-KU for patch@linaro.org; Tue, 06 Feb 2018 12:01:05 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33618) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Q8-0000fT-26 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Q6-00056x-81 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:36 -0500 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:36275) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Q5-00056d-UR for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:34 -0500 Received: by mail-wm0-x242.google.com with SMTP id f3so5164904wmc.1 for ; Tue, 06 Feb 2018 08:48:33 -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=D4pDJEnOgHOmstbqR+pmy5DTC8NVaaqrBRWWAk1Lzzc=; b=i18maw7Ujt38NzALoRIG4DQkv35CIdUdh345R1sPj0WAygKQBIJ/4TqLB9WVWdt0Fi 44sufAPaybJBZC3IAz8zdQ6AslighMAzCiIFYCX6c4q8Sif4vG9D2Z9jSbL9b7KnGld2 fY/s7DZewEgmZCzBcnYdzlcXWBs+9NHSnMnHA= 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=D4pDJEnOgHOmstbqR+pmy5DTC8NVaaqrBRWWAk1Lzzc=; b=qd7TTeqFSvo3MIGy+WQRyE1kautIvqsL9tJ71aPBKP1hSY0qJX8wrqmezUYacjWqWF 22ePU3drcoxMcVhsugM6RorkyVVcUAe3I6iejnGN7LN2HU4DyqxW+Giat3lrL6BFsjl+ TLag9WxD0wJToacMDZOBgzjjGFJZc4X6LVhDpcSD3TILMSI6h6f75ZVcsfjkaSWkcQEm D206fx2CNw5P15JfM74H2/1NQVkB0ujjCJPPKN3XOQAo72Tudn2y1x4qC/UotvJASDip GQfWlGCJ9Yv6ak44C4ZRNgJaYwKKxQmxObyuQo1fZG29/BWku66EJv1Z3TJahyT6zQWT 2aIw== X-Gm-Message-State: APf1xPCtrmp5CzqFQkiKGrCMTj7XVb/nKUAAnnKfAnFH/tm8Lj0SctcH Dq3CF0jSrI8lBsOo9QkWHQ+tbQ== X-Received: by 10.28.173.130 with SMTP id w124mr2180434wme.18.1517935712547; Tue, 06 Feb 2018 08:48:32 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id e67sm22959860wmf.7.2018.02.06.08.48.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:24 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 80D233E0239; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:09 +0000 Message-Id: <20180206164815.10084-17-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 16/22] 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 --- v3 - rename structures and functions v4 - move NaN handling to return NaN --- fpu/softfloat.c | 322 ++++++++++++++++++++++-------------------------- include/fpu/softfloat.h | 1 + 2 files changed, 148 insertions(+), 175 deletions(-) -- 2.15.1 Reviewed-by: Peter Maydell diff --git a/fpu/softfloat.c b/fpu/softfloat.c index ae4ba6de51..5d04e65538 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -560,7 +560,26 @@ static bool is_qnan(FloatClass c) return c == float_class_qnan; } -static FloatParts pick_nan(FloatParts a, FloatParts b, float_status *s) +static inline FloatParts return_nan(FloatParts a, float_status *s) +{ + switch (a.cls) { + case float_class_snan: + s->float_exception_flags |= float_flag_invalid; + a.cls = float_class_msnan; + /* FALLTHRU */ + case float_class_qnan: + if (s->default_nan_mode) { + a.cls = float_class_dnan; + } + break; + + default: + g_assert_not_reached(); + } + return a; +} + +static inline FloatParts pick_nan(FloatParts a, FloatParts b, float_status *s) { if (is_snan(a.cls) || is_snan(b.cls)) { s->float_exception_flags |= float_flag_invalid; @@ -1175,6 +1194,133 @@ 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 FloatParts round_to_int(FloatParts a, int rounding_mode, float_status *s) +{ + if (is_nan(a.cls)) { + return return_nan(a, s); + } + + switch (a.cls) { + 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) +{ + FloatParts pa = float16_unpack_canonical(a, s); + FloatParts pr = round_to_int(pa, s->float_rounding_mode, s); + return float16_round_pack_canonical(pr, s); +} + +float32 float32_round_to_int(float32 a, float_status *s) +{ + FloatParts pa = float32_unpack_canonical(a, s); + FloatParts pr = round_to_int(pa, s->float_rounding_mode, s); + return float32_round_pack_canonical(pr, s); +} + +float64 float64_round_to_int(float64 a, float_status *s) +{ + FloatParts pa = float64_unpack_canonical(a, s); + FloatParts pr = round_to_int(pa, s->float_rounding_mode, s); + return float64_round_pack_canonical(pr, s); +} + +float64 float64_trunc_to_int(float64 a, float_status *s) +{ + FloatParts pa = float64_unpack_canonical(a, s); + FloatParts pr = round_to_int(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 @@ -2905,87 +3051,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); - -} - /*---------------------------------------------------------------------------- | Returns the remainder of the single-precision floating-point value `a' | with respect to the corresponding value `b'. The operation is performed @@ -4129,99 +4194,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 65bc7442d2..4650758c23 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -237,6 +237,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 Feb 6 16:48:10 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: 127056 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3107565ljc; Tue, 6 Feb 2018 09:11:16 -0800 (PST) X-Google-Smtp-Source: AH8x227ZrZ/cNEnIX+uNW2Pm8AT0r79yfQMFDM7ES9IDfjITqW3hfMAcgqsoGhVAfuwxmYnkyV0G X-Received: by 10.37.35.196 with SMTP id j187mr1960253ybj.286.1517937076301; Tue, 06 Feb 2018 09:11:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517937076; cv=none; d=google.com; s=arc-20160816; b=q9K1TjEbZE31Ltn6xCaB66GoehUnfQBgVfiuBXXLV4mSu+gtJyx9OevD0ZlJ0IezZc oDiGFoZeC0QAiFyOwqnwuGc1Kws0LI6aP0DMxZxgKKyP+YLQanf1a2k6vR6R8yDqTklZ GJo5B5jyps6csr2wferNVOkCQQFSSMS6liwW8d6lXUt5QGXLms09NeWbIG/ZBrX7fsDN foerQ+DLK0dTvFL6in+996b0Xjbww2loXd2Eg9FPQjUQEUrecprucxjpt8hJNwfPeU/t fRjuJRLMapVljGs8gB8FdKyykq3Uf1S8jna9sCz7NibHKJmdkAt61ds3N5qYDH8IJy+N nMJQ== 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=pmzJe6ljgsW7yCIonTNshSsBurK24kdO5usa2mH/WFQ=; b=i05PbDY0oZDDwZ3XuP/P2fATge+GV13dcLOnFrOsFkh49nOYPrDs+dQ4/Thxd9pl23 rv1FpM1dyCevl7Ml0HDRLA2uiXIHngcZGLXCFntVb6CW8lf7WLkjK4nlIfR0uzv+nbBw ZUyIh+wo8m42z00s2wpi8YWIVbfDAtIr/s9FX0ob9hJO8daMz0mpGNEbEWTiD5sESvVd QNJPTIEdNUB37hw4KcVO3zvyvtTMfwG8NziCDezKZGB6QYiq79h1kX64vo8/uIZK9ZbY Wso69wM8PjLTUpPql8HYwfHmK1qmEKJFXmc5QV/EeBPv0UxI73Hyoh3ST/aAakZVZsj8 h7NQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=gVhAJ0cB; 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 y129si1877483ybf.569.2018.02.06.09.11.16 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 09:11:16 -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=gVhAJ0cB; 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]:38847 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6m3-0004Uu-HW for patch@linaro.org; Tue, 06 Feb 2018 12:11:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35928) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Wi-0007Pg-R4 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6We-0001iZ-Qh for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:24 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:42639) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6We-0001hV-8n for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:20 -0500 Received: by mail-wr0-x243.google.com with SMTP id 41so2674352wrc.9 for ; Tue, 06 Feb 2018 08:55:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pmzJe6ljgsW7yCIonTNshSsBurK24kdO5usa2mH/WFQ=; b=gVhAJ0cB3hwaAAcT35cCEdDNHU0ugqaT8MCMzKkGpwNdwYRsFK7Jf+vjzA6gxecWv0 U4pe8GXaxnUlF6qPKuJdwk1Zn87ALzBbCKG7mr927u3sbo4id8RDUIcYpNZ35Tzwdswg wW2Fg8cNM855ofh6vDz+yvM+DTmfYh4hLstgs= 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=pmzJe6ljgsW7yCIonTNshSsBurK24kdO5usa2mH/WFQ=; b=M7KOJXbWy21kIFOypD9mZskiE6FyxHAyuegQCxOOpKcN2h7MEK1vKLW00K5ScKOZ+n CTSjPx9UyVu3aYETZH9Y/wXhHQckQZK3lS9CV4rP9s6/NRMZTBX3JJBUaM4W7u5lYoBO +l5xJ7BT28mmtar6kkt5u5vfopMYsFdzQOj+gydaxhx6lJH03jBdU9ORR6ouS5Xn7VXr 2vSXdlyEQXH7CV+RlsKPKScw1ygAqh+v3Pz/fzUn+aiGAUoY2qTIph5Zz7OGRUu1JOci V4SLb6cD9FXNO/sgux7Ja477JzZ7qVIYEuC4XzsHHm5HIO4wTrY49DwwGJLiIUnLIQBk IP+A== X-Gm-Message-State: APf1xPAlC0IfxFfcT6EzGc7f6Ix15pSxB0wB+PBhWwgCDuuaHKZIGRXY evMMHo5gRubQIUxRCJE7c9wvHQ== X-Received: by 10.223.145.65 with SMTP id j59mr2962096wrj.79.1517936118581; Tue, 06 Feb 2018 08:55:18 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id d5sm33272895wra.72.2018.02.06.08.55.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:55:16 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 94CB33E099E; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:10 +0000 Message-Id: <20180206164815.10084-18-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 17/22] 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 Reviewed-by: Richard Henderson --- v2 - apply float_flg_invalid fixes next patch v3 - re-factor to common round_to_int/uint_and_pack - save flag state so invalid can override inexact - float to int/uint naming fixes --- fpu/softfloat.c | 935 ++++++++++-------------------------------------- include/fpu/softfloat.h | 13 + 2 files changed, 193 insertions(+), 755 deletions(-) -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 5d04e65538..216d60df6e 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1321,6 +1321,186 @@ 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 round_to_int_and_pack(FloatParts in, int rmode, + int64_t min, int64_t max, + float_status *s) +{ + uint64_t r; + int orig_flags = get_float_exception_flags(s); + FloatParts p = round_to_int(in, rmode, s); + + switch (p.cls) { + case float_class_snan: + case float_class_qnan: + return max; + case float_class_inf: + return p.sign ? min : 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 - DECOMPOSED_BINARY_POINT < 2) { + r = p.frac << (p.exp - DECOMPOSED_BINARY_POINT); + } else { + r = UINT64_MAX; + } + if (p.sign) { + if (r < -(uint64_t) min) { + return -r; + } else { + s->float_exception_flags = orig_flags | float_flag_invalid; + return min; + } + } else { + if (r < max) { + return r; + } else { + s->float_exception_flags = orig_flags | float_flag_invalid; + return max; + } + } + default: + g_assert_not_reached(); + } +} + +#define FLOAT_TO_INT(fsz, isz) \ +int ## isz ## _t float ## fsz ## _to_int ## isz(float ## fsz a, \ + float_status *s) \ +{ \ + FloatParts p = float ## fsz ## _unpack_canonical(a, s); \ + return round_to_int_and_pack(p, s->float_rounding_mode, \ + INT ## isz ## _MIN, INT ## isz ## _MAX,\ + s); \ +} \ + \ +int ## isz ## _t float ## fsz ## _to_int ## isz ## _round_to_zero \ + (float ## fsz a, float_status *s) \ +{ \ + FloatParts p = float ## fsz ## _unpack_canonical(a, s); \ + return round_to_int_and_pack(p, float_round_to_zero, \ + INT ## isz ## _MIN, INT ## isz ## _MAX,\ + 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 round_to_uint_and_pack(FloatParts in, int rmode, uint64_t max, + float_status *s) +{ + int orig_flags = get_float_exception_flags(s); + FloatParts p = round_to_int(in, rmode, s); + + switch (p.cls) { + case float_class_snan: + case float_class_qnan: + s->float_exception_flags = orig_flags | float_flag_invalid; + return max; + case float_class_inf: + return p.sign ? 0 : max; + case float_class_zero: + return 0; + case float_class_normal: + { + uint64_t r; + if (p.sign) { + s->float_exception_flags = orig_flags | float_flag_invalid; + return 0; + } + + if (p.exp < DECOMPOSED_BINARY_POINT) { + r = p.frac >> (DECOMPOSED_BINARY_POINT - p.exp); + } else if (p.exp - DECOMPOSED_BINARY_POINT < 2) { + r = p.frac << (p.exp - DECOMPOSED_BINARY_POINT); + } else { + s->float_exception_flags = orig_flags | float_flag_invalid; + return max; + } + + /* For uint64 this will never trip, but if p.exp is too large + * to shift a decomposed fraction we shall have exited via the + * 3rd leg above. + */ + if (r > max) { + s->float_exception_flags = orig_flags | float_flag_invalid; + return max; + } else { + return r; + } + } + default: + g_assert_not_reached(); + } +} + +#define FLOAT_TO_UINT(fsz, isz) \ +uint ## isz ## _t float ## fsz ## _to_uint ## isz(float ## fsz a, \ + float_status *s) \ +{ \ + FloatParts p = float ## fsz ## _unpack_canonical(a, s); \ + return round_to_uint_and_pack(p, s->float_rounding_mode, \ + UINT ## isz ## _MAX, s); \ +} \ + \ +uint ## isz ## _t float ## fsz ## _to_uint ## isz ## _round_to_zero \ + (float ## fsz a, float_status *s) \ +{ \ + FloatParts p = float ## fsz ## _unpack_canonical(a, s); \ + return round_to_uint_and_pack(p, s->float_rounding_mode, \ + UINT ## isz ## _MAX, 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 @@ -2672,288 +2852,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 @@ -3559,236 +3459,6 @@ int float32_unordered_quiet(float32 a, float32 b, float_status *status) 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. -*----------------------------------------------------------------------------*/ - -int64_t float64_to_int64(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 ( aExp ) aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x433 - aExp; - if ( shiftCount <= 0 ) { - if ( 0x43E < aExp ) { - 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 roundAndPackInt64(aSign, aSig, aSigExtra, status); - -} - -/*---------------------------------------------------------------------------- -| 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. -*----------------------------------------------------------------------------*/ - -int64_t float64_to_int64_round_to_zero(float64 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint64_t aSig; - int64_t z; - a = float64_squash_input_denormal(a, 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 ( aSign ) z = - z; - return z; - -} /*---------------------------------------------------------------------------- | Returns the result of converting the double-precision floating-point value @@ -7056,252 +6726,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 4650758c23..ec1e701c26 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -232,6 +232,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 Feb 6 16:48:11 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: 127051 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3101697ljc; Tue, 6 Feb 2018 09:04:49 -0800 (PST) X-Google-Smtp-Source: AH8x226QiRZvvoobeS8wKd1X4NLUuFZfoQPgjn0V4znwg4FO3XUIa7lVJ6ex8WOH60XKtUmx+/Iy X-Received: by 10.37.45.36 with SMTP id t36mr1948122ybt.354.1517936689135; Tue, 06 Feb 2018 09:04:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936689; cv=none; d=google.com; s=arc-20160816; b=xC1UsfGY7IMziBQf/o++rMX9WXpN4gbQfNCR9gBfGJiUcRAxJwFwtIZTjFb4nUqX7f hSeuBcf77KAETNVzAgxwy4twbbiykYp4qANGk1kNRyShU9gC4ALIsHBsCBmulFNc80Pk wnNhvIUDNhpPFSUdQ7tYZRG5M85YFliS9YUgp1IBceIcl2m4AFVrhbSuPsbu4DKFmsMt UWaxXv05skbAhtHh5Jm7/M6P51v2r9DL6cnivO8j+4WiHtanAkT6/Ys4EpjtGJClNuTT elvZio10Q1H94Uf2GqsxepV3cFeMC9ZxMBjmPZOrg5GKjwBRi/Df4ADJaO32MNDfK2VF +fvQ== 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=b0IkdpcAgRl85q52/A7+s4B+Iac43WylBcIZIlbjvYk=; b=USUTwTwKBzu243K9jG3k0MlgGya2FtokpBhtPUAVVkyuENnfkvL+dgy5llltS14eWF mK4QeKgsawy7iJRNsaiCPqs6uL8nBIfKCDVAjxHGwSwURePjWz/zk+ropSR8/RzcX76A HABJ5GzaMXY1NxFZrXcqo2FkqECEPnHf36d+jud9pn/i9+F0NAaeYB8K8yeTOR7kC6zL IQn6Qq7WSBqMnSTtEGRp/pnIXeVSiSBTfi6zCiU3JRxMAEY29pl5U7xh1ixw4IvNQTMK NEVHuC/FSLwJcJQ3zyd4eJIs7G3geVtkuZQklusq4eY7n4V/+I2nzGFknzStGDimagM9 1oiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=jvYPxP22; 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 t9si25292ywt.381.2018.02.06.09.04.48 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 09:04: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=jvYPxP22; 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]:38333 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6fo-00075X-8n for patch@linaro.org; Tue, 06 Feb 2018 12:04:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35812) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Wd-0007Dk-7p for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Wa-0001dS-UZ for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:19 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:34556) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Wa-0001bD-EH for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:16 -0500 Received: by mail-wr0-x243.google.com with SMTP id z6so2690787wrb.1 for ; Tue, 06 Feb 2018 08:55:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=b0IkdpcAgRl85q52/A7+s4B+Iac43WylBcIZIlbjvYk=; b=jvYPxP22clC5d8NpvfnQNnqa5kxwDc8qeKCGIBxNGp96m8bXVM3qBj/04h9I3VpE0I pDP7BEdvq0ZJn/rRhWBG6jLa9Cg8lUuQN7ssbmNHHkTdzLZt+BDa1WMZ8vX1MP+OBSpk NPArnWxpRBcVff5zA91iEFXi81ydRMjbbblvo= 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=b0IkdpcAgRl85q52/A7+s4B+Iac43WylBcIZIlbjvYk=; b=WICA72HbYBHlKJww19vHKnjfr5ZPz349+SlAgfmxWZYCqpSMKJL/0As0XoFxjmKmLo eue2m6r+h3dnnTBdgWgg73PESFFYNm7nR83+S6uXPA9ux23sJK7KtnGmKSI+tMYRYO0J PjD2lSkIvaxsvnp+exUqMFH4VFhsA7B9cOsi2+8XWVNkIqUU5xeyV6YLgx9PFavVVq/a iIgOyV1IniZjBVSMJuL0A/2XMtpp2EAz4SP1rPMrL2F6U8cWyvltCMqECTBxnNG3ete9 XCwdtL2o607TvxKtWgunErgGb44t+imV96OlzbNgKy7pVa3hWkE3CZlqcTpd24aVRco3 HtYQ== X-Gm-Message-State: APf1xPBU66Yi9y+vRMeQLK/6MrtT38u5JQm/Vvo7fT7KK0YIUHJ2AXc7 fl2JNz1tfmh1qVoTVvWKa5P5JQ== X-Received: by 10.223.167.3 with SMTP id c3mr2882791wrd.197.1517936115044; Tue, 06 Feb 2018 08:55:15 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id j144sm6867782wmj.45.2018.02.06.08.55.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:55:11 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id A7BE83E09A8; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:11 +0000 Message-Id: <20180206164815.10084-19-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 18/22] 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 v3 - renaming of functions/structs --- 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 216d60df6e..9f9f101d35 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1501,6 +1501,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 FloatParts int_to_float(int64_t a, float_status *status) +{ + FloatParts 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) +{ + FloatParts 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) +{ + FloatParts 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) +{ + FloatParts 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 FloatParts uint_to_float(uint64_t a, float_status *status) +{ + FloatParts 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) +{ + FloatParts 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) +{ + FloatParts 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) +{ + FloatParts 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 @@ -2592,43 +2755,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 @@ -6715,19 +6732,6 @@ int float128_unordered_quiet(float128 a, float128 b, float_status *status) return 0; } -/* misc functions */ -float32 uint32_to_float32(uint32_t a, float_status *status) -{ - return int64_to_float32(a, status); -} - -float64 uint32_to_float64(uint32_t a, float_status *status) -{ - return int64_to_float64(a, status); -} - - - #define COMPARE(s, nan_exp) \ static inline int float ## s ## _compare_internal(float ## s a, float ## s b,\ int is_quiet, float_status *status) \ diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index ec1e701c26..3e6fdd756a 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -190,9 +190,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); @@ -204,27 +208,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. *----------------------------------------------------------------------------*/ @@ -245,6 +228,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 Feb 6 16:48:12 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: 127034 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3093055ljc; Tue, 6 Feb 2018 08:55:57 -0800 (PST) X-Google-Smtp-Source: AH8x227zXfigHF+ZvFt5Nl55oeQqQxDow4Cf+XwFITNcUu1KnqfBUxx8LFKyxr9XbSKhDnWrzXmG X-Received: by 10.37.186.11 with SMTP id t11mr1869557ybg.450.1517936157500; Tue, 06 Feb 2018 08:55:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936157; cv=none; d=google.com; s=arc-20160816; b=CBiGz3oq8Nd4sVQG4LqEih4SWZyWG7FOj3kFwrQWwi0M9pmHTWR7BJa13uFuYZdOWl leXcSdQylAmbvLdRu4SsD48OTnmtN1AjTHg7qV3X12062KWcZIFLsKzK6m0jpKk98ZrZ DuVinDkpxpU2j/ObzGS43WrNC9X2PSGOMpxMjxFvahWBtNOZll2tGP92+TokPEVCR1xz TfHottFTp6r7E5yehRs3yHzGWePHOzb1AFcDzRXDxHYVh15wH3E4vTLQw6Y0Pxgq1vyq 8vLA+7WNs4pdTDOGjLHYVZPRiwMX65qIJVnNTDV0SfrQVKDnxHx/3Vgvz/W1lAY9DkYB r62g== 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=dIOCFTqn7NVlbHqtKqtMbIfU0aME3Jg60nM4GNu5gRg=; b=u50UBdHY1IVA/1dp/W0KIjcTokA603wODV8J4Qf3OyeTfiUqPm6BwAyiaLp2DFK30c ESWL2pQ7qlE+t2vdCm5KQE0Oz0d1G7anihRg8tiGM4NuKM0oI+geF3aJjyJ9eqcuI1fm 5U8Y5szAEJAW0X+ck/Hfv87TONBjwd7jaqV8QR69wmeoCIhqsRstu1HVHmnLi6sTs85/ Q9T7Tp/p7Y16rtW2avKmIRkMBln1kcAULdfVczGnLzJo35qsgWnKC1pVixQyBC/t4G7J LmRPVdpVIYZSANU/SF2+rBegkm0IXPow/Oc74704lxImlhrvEsWAcM50KZPhuzPU6ODL oJcA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=KdmWjpAn; 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 w186si1854357ywc.779.2018.02.06.08.55.56 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:55:57 -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=KdmWjpAn; 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]:37830 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6XE-0007Ty-D8 for patch@linaro.org; Tue, 06 Feb 2018 11:55:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35772) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Wb-0007BH-EC for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6WZ-0001bL-Sk for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:17 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:43982) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6WZ-0001aB-8U for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:15 -0500 Received: by mail-wr0-x242.google.com with SMTP id b52so2663349wrd.10 for ; Tue, 06 Feb 2018 08:55:15 -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=dIOCFTqn7NVlbHqtKqtMbIfU0aME3Jg60nM4GNu5gRg=; b=KdmWjpAn2BmcdfMJZ9k6PhRlgQU7ZsL90AExR0277Qj/ojPG9MTCUQVaNOuIFCxw41 CPF/ZFnDO7wfIj+p5Ck6PwBIEZFJoyGEtW9EVyzHQ/wYUPiA2fljd8U3pvsuDcfEy8CK VhsfkcaUNau5SRaoLFp2bQ8PiBLPP8tRpUkso= 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=dIOCFTqn7NVlbHqtKqtMbIfU0aME3Jg60nM4GNu5gRg=; b=l1GhfdwirYDryYGetLbqc+SuN8dBsfT41vQSHR1yFRTKiVIVo6XvEchUMCFGMjR7Tv aOpXOp2QfSiMFJ6Rh3eVxLOGpX5KRGsG/iOOU8L7Eh6a4iDnXBVkG++fjvcvXm+mo547 d7yfQ69nfpIPAT+Y3JCIKTdaIrR8F8B4ZNsVR7CmGS5haRXJN4emEtAl0jjWWiRbgDuo qa7C44EPjEeBsYHbYCrG/R9ASf/9fGU1FQd+MfJwDSb+GCsPVH6n5qI5gR6+MlfZF1sl Nh3tH5RLNy63rz3/KrMOqxn6Qdwzcjr5FU7BO0uY3HsOyvGCOemUqRLyILVc0tksHaOy +lFg== X-Gm-Message-State: APf1xPCgZLDFTnGVGa2gBCcKfvEU2ctYKuKmeRe6RCPhLUrTEhxCP7Wb XM95fnCBDU11htaN5h9ruTkaTw== X-Received: by 10.223.184.213 with SMTP id c21mr2936984wrg.57.1517936114073; Tue, 06 Feb 2018 08:55:14 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id m191sm8896068wma.42.2018.02.06.08.55.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:55:11 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id BAE413E09C4; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:12 +0000 Message-Id: <20180206164815.10084-20-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 19/22] 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 --- v3 - fix renames v4 - handle NaNs with return_nan - use unlikely(is_nan) --- fpu/softfloat.c | 106 +++++++++++++++--------------------------------- include/fpu/softfloat.h | 1 + 2 files changed, 34 insertions(+), 73 deletions(-) -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 9f9f101d35..558d37ecf9 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1664,6 +1664,39 @@ 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 FloatParts scalbn_decomposed(FloatParts a, int n, float_status *s) +{ + if (unlikely(is_nan(a.cls))) { + return return_nan(a, s); + } + if (a.cls == float_class_normal) { + a.exp += n; + } + return a; +} + +float16 float16_scalbn(float16 a, int n, float_status *status) +{ + FloatParts pa = float16_unpack_canonical(a, status); + FloatParts pr = scalbn_decomposed(pa, n, status); + return float16_round_pack_canonical(pr, status); +} + +float32 float32_scalbn(float32 a, int n, float_status *status) +{ + FloatParts pa = float32_unpack_canonical(a, status); + FloatParts pr = scalbn_decomposed(pa, n, status); + return float32_round_pack_canonical(pr, status); +} + +float64 float64_scalbn(float64 a, int n, float_status *status) +{ + FloatParts pa = float64_unpack_canonical(a, status); + FloatParts 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 @@ -6987,79 +7020,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 3e6fdd756a..52621e0b79 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -244,6 +244,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 Feb 6 16:48:13 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: 127052 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3102437ljc; Tue, 6 Feb 2018 09:05:36 -0800 (PST) X-Google-Smtp-Source: AH8x227N43NsQaoKhr4EQ1BG4Op1mlbEQOZaQ+oJZOFJMZ1kPFa740EGAkRFIHHKe1/di2C0Jbbc X-Received: by 10.37.76.193 with SMTP id z184mr1937463yba.196.1517936736222; Tue, 06 Feb 2018 09:05:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936736; cv=none; d=google.com; s=arc-20160816; b=fABLbh8FZ9wJBdpe8d3tv+6Ws4sJkBT1Xpqj2C7ZdG/sh9cI2jlqW6ZOcoRjvJ2NMR AqwbcN5c72W+LCPSdwUs7A5H7kZ+BTC8dt+TSwFVJVNMVRaT46XtIBUxZ2Zv4+gOcWOt sdEd+rkU1V0nNSxLFiRiClEA/s2Mk1pl+j1ynCvThrL0e11cALuQVnSI6Ld5NiSPBGql 8QNsbWHlyhKC65OECVXMUh89rMQfKSZqDT0LjoCKLF66D2zwhuSdEyAsq/t5v35vx0BZ 3rWVEHG0w8u2tE8bhGR7GTWO898YkBSh812W0rOvMCGH37XbprLhInt/zMalXdo3+NHH jqvg== 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=XgJ7Yi7AZt76clbkE8q69eGVUGgUmDO9N7D7HhRZ+68=; b=hFva1x0q3pdWjJ+rLfE/p82gKXmtJ86TPfyafkK3NqxAO5A+TidyAZvRq9vqAiD8rH Hj/NJi17M7Dsl8UNhrInhnmJEx/Z+hgwHXDLSVQ6E2FDjE/PaxvAKuXhpSr6RId7rJVe 94h8nL5gXYTAvZDJd17oLzczxOCq716SOTk7UWaidukUlwDQBtEHdbShVMcZJtF1cfZm UmUfMAvaDNftJeH3gTiE+STZkcT2t+V7ABNcxFTv0LTYnPzO3i23k7Vb0FZwW6GAUTRJ Q2ampHzc6P7LevtyrKhmaLBDFQcnHUnYF73RyVMZOlM4BS7/bvwBOsCXTOqVc64fJSQI 0z+g== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=THBGBiaV; 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 p17si1892502ybk.557.2018.02.06.09.05.35 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 09:05:36 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=THBGBiaV; 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]:38358 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6gZ-0007pT-J9 for patch@linaro.org; Tue, 06 Feb 2018 12:05:35 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33669) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6QD-0000iu-RT for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Q8-0005CE-G6 for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:41 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:37184) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Q8-00059Q-5N for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:36 -0500 Received: by mail-wr0-x242.google.com with SMTP id a43so2654782wrc.4 for ; Tue, 06 Feb 2018 08:48:35 -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=XgJ7Yi7AZt76clbkE8q69eGVUGgUmDO9N7D7HhRZ+68=; b=THBGBiaV1zBramPS5DV6nzD2ySvRNPpR4K4NZOix5zPSq03ORZyjLN4R6OaGiQ9uIn WHqJpz0Mp1PTPBFxqhswPEn9ZI+GfYv4Wksf0YB3VcAk9p2ZC7SQsxvx1o5OIwHOzp7V uhTK3QhqyHBGUTO1t51zTRSqKXfAHZ0YSs3bg= 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=XgJ7Yi7AZt76clbkE8q69eGVUGgUmDO9N7D7HhRZ+68=; b=FSvCrOk+xYurVq0hsXUaTXZAUVLe3dBMyO1CoO9iMlbq1d4orE+0OnOTLOahN8/riH u9Q+muoFisaBFZKRi3+y94afqGugxFpTGwqjTmJ6ISk4aBmdmlTBpnskGNtkj95IQWmH Bdk1AkFuevhxDz325AE8wFfhnLGBU2YgI+QJJC2mO3Sq9bOdSEAjoEZ9X/TVXGDbQXQu rZpA9ccsAkLOXwtgBXKQxCppRtIoEUAOJcAlABmBgXEtRQYyDG5d+rErgPN1H6Sa4e/I UN6J7PgMiOYFGOBz8fi8cTF51IrEJk+nZlgqavLCMUPJ+wCJ1D8le5Jpd1Nu2NyTko52 ol8A== X-Gm-Message-State: APf1xPAinybcWysY5ZsxoDCt3h50G8F1Cg8CTdYBTTIxCMkIG8+q5HQk cK1L0gQm52a9bFQAdXyvDl9s2Q== X-Received: by 10.223.134.237 with SMTP id 42mr3059064wry.283.1517935714946; Tue, 06 Feb 2018 08:48:34 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id z12sm11573038wrz.20.2018.02.06.08.48.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:32 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id CD48F3E0A1A; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:13 +0000 Message-Id: <20180206164815.10084-21-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 20/22] 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 Reviewed-by: Richard Henderson --- v2 - minor indentation fix v3 - fix merge conflicts from dropping MINMAX patch - fix naming of structs v4 - use is_nan/is_snan - pick_nan_parts->pick_nan - minmax_decomposed->minmax_floats --- fpu/softfloat.c | 227 +++++++++++++++++++++++++----------------------- include/fpu/softfloat.h | 6 ++ 2 files changed, 126 insertions(+), 107 deletions(-) -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 558d37ecf9..cb889a7a84 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1664,6 +1664,126 @@ 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 FloatParts minmax_floats(FloatParts a, FloatParts b, bool ismin, + bool ieee, bool ismag, float_status *s) +{ + if (unlikely(is_nan(a.cls) || is_nan(b.cls))) { + 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 (is_snan(a.cls) || is_snan(b.cls)) { + return pick_nan(a, b, s); + } else if (is_nan(a.cls) && !is_nan(b.cls)) { + return b; + } else if (is_nan(b.cls) && !is_nan(a.cls)) { + return a; + } + } + return pick_nan(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) \ +{ \ + FloatParts pa = float ## sz ## _unpack_canonical(a, s); \ + FloatParts pb = float ## sz ## _unpack_canonical(b, s); \ + FloatParts pr = minmax_floats(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 FloatParts scalbn_decomposed(FloatParts a, int n, float_status *s) { @@ -6913,113 +7033,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. - * 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_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 52621e0b79..35df225a55 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -245,6 +245,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 Feb 6 16:48:14 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: 127039 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3094856ljc; Tue, 6 Feb 2018 08:58:18 -0800 (PST) X-Google-Smtp-Source: AH8x227x8xJv4Pj2ciE6f0lBmkHHaTbNZo4TrJRMeJEyH/U07n1mGTZqehRwtQBg3TegkOHpaJM4 X-Received: by 10.129.90.84 with SMTP id o81mr1894478ywb.115.1517936298341; Tue, 06 Feb 2018 08:58:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517936298; cv=none; d=google.com; s=arc-20160816; b=VEdUeONpUBxnPQLDASzvdKX5rAUOdxzZVThV/+jrcly7OjnNK6w/8mtZo7NPLUolWf 0vYq+xDuiIpXpczRWBAs0sLXnogHUCH+2QTAUbGwbH2x3HFL1RXHrzhZh10iNweydm5g NPECcNDCSgHr7qsxy066e5fhOHXMYo7tRLAL2/AIN0IydqLbrHZBRjnqd98MahC+dix2 kKz+/jLAs5j0uD9Wn0M98lQcNhdRljgRtsxqhyXbPr1mxom33vBmn5EY1QIRZ3ZtfnL+ 0viCnFmB0bSZNfyMbCdBdnnrQDOkdJ7EcJhmLiYPZmVWStkjbtU2LwcW7KFRRbziXB0c r9wg== 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=j6JRJv9abkypmJSjSZWtORm9e1BwOuplbpYUw5I4taw=; b=IkSXATCwt3tOQNLa5YL5Ur0CRmEIU6YgzUya/T6FrLEAxh0t0yp7EmXtZFWCGoRz2S rMZ+Mx/9qch//HufzC4YVcY1MAbV+gYUKB19M6Y9nO0ZVXo68UHyg0AAtNhru2xevHoQ KeCp5ScJxPlOCXeuTcRbf8XqvykYJPC3NUsHaC0CWuiDdXaDi+wVcOLNOhryaxXeETQ9 pOqOB3FTZDxc5wbB9UvxEfursj6YEQNO0Yds4oVAd/onx12k7265dpsn05R4ECloaQvl 0MnK9xHsYZZC63o31vzz39uFMTUBeTZaPnPKR6jQ3GcxkpvHOohfNjOTZlegemxNCFtX SJTw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=CuTLXcDN; 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 i127si1826636ywb.662.2018.02.06.08.58.18 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:58:18 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=CuTLXcDN; 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]:37837 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6ZV-0000NL-J2 for patch@linaro.org; Tue, 06 Feb 2018 11:58:17 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35770) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Wb-0007BG-Dz for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6WZ-0001ah-3I for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:17 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:41108) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6WY-0001Yl-EL for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:55:15 -0500 Received: by mail-wr0-x244.google.com with SMTP id v15so2673786wrb.8 for ; Tue, 06 Feb 2018 08:55:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=j6JRJv9abkypmJSjSZWtORm9e1BwOuplbpYUw5I4taw=; b=CuTLXcDN84grFYrKKY3Aam+ZFBLKSGXh+bcoZGVQrz3wfr7anWo5UUgYQhuLwij3tv BmVQgCfEfZkj0K3a6peEGwgBcE37LmGM5bp4Jw6j5FnQ2ZNiEjkNDxbMZShxvKapq10B /Bj0I0IrZdHJbYPlXE/vKM5b2RcKRPvxIK1vg= 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=j6JRJv9abkypmJSjSZWtORm9e1BwOuplbpYUw5I4taw=; b=GBor+DVVPNmRDzcHFWTHgErJspctV2uMotpwdR57FtCI5Zspm6OtLzQkKoIjHCkj4E 5Zccnct0GBfLtfOFTHM2By6IvBdX2KPQP9UnmlsHw2YcuStDmGe547VVhTyIiUkT6XpY fvEf200k9jcsnNrK/HyhFxvuzDjHP2I9kDoOL1JGHm53EeKnl91WckWwtxaGjHQDVvkp WeB4J2hdG5IXUB+spkU8yFQcepRNFZuJDF9UiRtIgJtLV9pSQdMezxaeoRBqIz2jG/oj R4GIXJ7X6DrJpG9sMwzomb37zwCiAq6Va7jnxJjxohxNaSnCCbFjSJS+RDYXEn3qyPbY o/Ug== X-Gm-Message-State: APf1xPC1qmqbPRJ3Q8038HTCoHu45fcIocaSee1lv6aEZzckj0ddTbJ9 h27M2yymYe5ji2iK0whHSZAJ3A== X-Received: by 10.223.136.89 with SMTP id e25mr2686611wre.140.1517936113230; Tue, 06 Feb 2018 08:55:13 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id v9sm6422744wre.8.2018.02.06.08.55.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:55:11 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id DFB603E0AA7; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:14 +0000 Message-Id: <20180206164815.10084-22-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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 v4 21/22] 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 Reviewed-by: Richard Henderson --- v2 - minor re-factor for better inf handling v3 - fix renaming of structs/functions v4 - use is_nan --- fpu/softfloat.c | 134 +++++++++++++++++++++++++++++------------------- include/fpu/softfloat.h | 2 + 2 files changed, 82 insertions(+), 54 deletions(-) -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index cb889a7a84..8fc1c2a8d9 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1784,6 +1784,86 @@ MINMAX(64, maxnummag, false, true, true) #undef MINMAX +/* Floating point compare */ +static int compare_floats(FloatParts a, FloatParts b, bool is_quiet, + float_status *s) +{ + if (is_nan(a.cls) || is_nan(b.cls)) { + 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) \ +{ \ + FloatParts pa = float ## sz ## _unpack_canonical(a, s); \ + FloatParts pb = float ## sz ## _unpack_canonical(b, s); \ + return compare_floats(pa, pb, false, s); \ +} \ +int float ## sz ## _compare_quiet(float ## sz a, float ## sz b, \ + float_status *s) \ +{ \ + FloatParts pa = float ## sz ## _unpack_canonical(a, s); \ + FloatParts pb = float ## sz ## _unpack_canonical(b, s); \ + return compare_floats(pa, pb, true, s); \ +} + +COMPARE(16) +COMPARE(32) +COMPARE(64) + +#undef COMPARE + /* Multiply A by 2 raised to the power N. */ static FloatParts scalbn_decomposed(FloatParts a, int n, float_status *s) { @@ -6885,60 +6965,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 35df225a55..cebe37b716 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -251,6 +251,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); From patchwork Tue Feb 6 16:48:15 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: 127030 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3090128ljc; Tue, 6 Feb 2018 08:52:14 -0800 (PST) X-Google-Smtp-Source: AH8x227LfvDWe8mOqu9+1cG+CuCZb/2xHZ9YaSu2IPSPWLis4M2oZdWIJAMwTTWGrHjgscat2eey X-Received: by 10.37.173.37 with SMTP id y37mr1928744ybi.241.1517935934838; Tue, 06 Feb 2018 08:52:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517935934; cv=none; d=google.com; s=arc-20160816; b=AWiPf71eZb0UBeP78VU0YKQc3QRZ7w/rR1UQ7/TAbo8Jnm2+8Ztzn8XnjLrq7zlUTq UQrXcxFekav1UZ9+glRhj/S1oRsAo5hzW991gS3m+mkigOMn5w3R2RiOCtx/Iry18rcr HgXf/YFgp/Nro6q1oYH0ze8/pEuAEtM1WLVdOKG8R8W6woyNxHmzSIrbYbw08m2myNA9 tdFu+yUNdpC0PbpHgKSU4iTJjmhttdWEjGyf1kZNe4mIhdPtWik8CfyQOE0ITzq73BOC icm3MW8ugmk8Bz/inzPVOC/rXXNND0S2v+wDcmzjSmlNzG3BgmL6VGm6svi/SgSbCgIG qcPg== 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=oivlM7WqPF46OBB5Stbu+Ctx0JqERlmdrSYiEYQFZpQ=; b=TKWP/lhfkeIml8ZSGq2wYOcA1qsnBHvwFG1ZQgAl8msOZU+VVlxsPZsh4DaJV/Im+3 R85Lhfqz/s18qT3K4gy9RQ+nzqz2jh3oBmut/vVINvqAFCRg/YxkJ97h4I4XeCikwrbQ b3fpSDM5EFSnnyW6XBFUrYG1gQOAzIqfOmIPMBodbumrV+deqVVqMxj1fXJEcuY2Zcna gzihOxxZdPQp7Smp4jIRzqhZAvVbQfVbYVjY7+ljeBV7q2JOfzLpAZ1rCOUmcu03rPjb M3mi8oJrNXNKLbGVYe3ZVibiAbWZohj4lvG3q2G96fSBOqaRcWhcAciRf3ljrGvtK2Dx uDvw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Cw1N9hU5; 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 i203si1867948ywg.284.2018.02.06.08.52.14 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 06 Feb 2018 08:52: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=Cw1N9hU5; 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]:37473 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6Te-0003eh-6I for patch@linaro.org; Tue, 06 Feb 2018 11:52:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33658) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej6QD-0000hv-0R for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej6Q7-00059X-JV for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:41 -0500 Received: from mail-wr0-x230.google.com ([2a00:1450:400c:c0c::230]:41897) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ej6Q7-00057T-AP for qemu-devel@nongnu.org; Tue, 06 Feb 2018 11:48:35 -0500 Received: by mail-wr0-x230.google.com with SMTP id v15so2650497wrb.8 for ; Tue, 06 Feb 2018 08:48:35 -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=oivlM7WqPF46OBB5Stbu+Ctx0JqERlmdrSYiEYQFZpQ=; b=Cw1N9hU5Gb8Ywd60UtEp7s/kTmGYwDLqkk5ukveXsNJJixOMiuLSjh7wIRDNtOb1v1 DxR1Iy+XZ86x5B/Q/xK7goH+5rOGDYXCZ9S+CNMvmMmzrUeOgAbnhM7QGmCY1UXlSq+X hNBYzU6VlYE5tPxPGg3ROEJgxvXiJS8yWWHKc= 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=oivlM7WqPF46OBB5Stbu+Ctx0JqERlmdrSYiEYQFZpQ=; b=f7NRSEAP2ZAi+C+0BtF0S2sg3wPQk4yLNyo8mpOZq9QyOhy9mN9OiwXM5cFILSeEUp fRiZzl4u7lqmeXnEtN+8I0OhV63MRH5USV10vZC/hTT0dlnp2theTytv5zbH6miVxmXP LcsYzcd+Unq52DxCqtGxulWN977DODjSh3OY0p+Wpum9iV2Vk1lNJ0GAP2w6oErWXHB5 7c4EIWGOmDi+lgCLRpr7Tfwu8UhHhmlUmCm2dy6izWWQXNFdSqPkB1sdEeoPFZuC8UCA VZ4RlA+6t12DeBfeX7Vu2MHuaw7QPOzZdCyi6SXjLGphgNBdbcn+EorFe2tGPixbjIbA cnkA== X-Gm-Message-State: APf1xPA9dkCSJxSOLeXCGn7BFh1pCt613MsUYdUE9b7K6NK+A3xdcUUQ hYmxxwLd35HJ6cxXx02ldpurMQ== X-Received: by 10.223.152.130 with SMTP id w2mr2869619wrb.12.1517935714073; Tue, 06 Feb 2018 08:48:34 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id f8sm6015801wmc.3.2018.02.06.08.48.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 08:48:32 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id F222F3E0AC0; Tue, 6 Feb 2018 16:48:16 +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, 6 Feb 2018 16:48:15 +0000 Message-Id: <20180206164815.10084-23-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180206164815.10084-1-alex.bennee@linaro.org> References: <20180206164815.10084-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::230 Subject: [Qemu-devel] [PATCH v4 22/22] fpu/softfloat: re-factor sqrt 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 a little bit of a departure from softfloat's original approach as we skip the estimate step in favour of a straight iteration. Suggested-by: Richard Henderson Signed-off-by: Alex Bennée --- v3 - added to series - fixed renames of structs v4 - fix up comments - use is_nan - use return_nan instead of pick_nan(a,a) --- fpu/softfloat.c | 201 ++++++++++++++++++++++-------------------------- include/fpu/softfloat.h | 1 + 2 files changed, 91 insertions(+), 111 deletions(-) -- 2.15.1 Reviewed-by: Peter Maydell Reviewed-by: Richard Henderson diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 8fc1c2a8d9..80301d8e04 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1897,6 +1897,96 @@ float64 float64_scalbn(float64 a, int n, float_status *status) return float64_round_pack_canonical(pr, status); } +/* + * Square Root + * + * The old softfloat code did an approximation step before zeroing in + * on the final result. However for simpleness we just compute the + * square root by iterating down from the implicit bit to enough extra + * bits to ensure we get a correctly rounded result. + */ + +static FloatParts sqrt_float(FloatParts a, float_status *s, const FloatFmt *p) +{ + uint64_t a_frac, r_frac, s_frac; + int bit, last_bit; + + if (is_nan(a.cls)) { + return return_nan(a, s); + } + if (a.cls == float_class_zero) { + return a; /* sqrt(+-0) = +-0 */ + } + if (a.sign) { + s->float_exception_flags |= float_flag_invalid; + a.cls = float_class_dnan; + return a; + } + if (a.cls == float_class_inf) { + return a; /* sqrt(+inf) = +inf */ + } + + assert(a.cls == float_class_normal); + + /* We need two overflow bits at the top. Adding room for that is + a right shift. If the exponent is odd, we can discard the low + bit by multiplying the fraction by 2; that's a left shift. + Combine those and we shift right if the exponent is even. */ + a_frac = a.frac; + if (!(a.exp & 1)) { + a_frac >>= 1; + } + a.exp >>= 1; + + /* Bit-by-bit computation of sqrt. */ + r_frac = 0; + s_frac = 0; + + /* Iterate from implicit bit down to the 3 extra bits to compute a + * properly rounded result. Remember we've inserted one more bit + * at the top, so these positions are one less. */ + bit = DECOMPOSED_BINARY_POINT - 1; + last_bit = MAX(p->frac_shift - 4, 0); + do { + uint64_t q = 1ULL << bit; + uint64_t t_frac = s_frac + q; + if (t_frac <= a_frac) { + s_frac = t_frac + q; + a_frac -= t_frac; + r_frac += q; + } + a_frac <<= 1; + } while (--bit >= last_bit); + + /* Undo the right shift done above. If there is any remaining + fraction, the result is inexact. Set the sticky bit. */ + a.frac = (r_frac << 1) + (a_frac != 0); + + return a; +} + +float16 float16_sqrt(float16 a, float_status *status) +{ + FloatParts pa = float16_unpack_canonical(a, status); + FloatParts pr = sqrt_float(pa, status, &float16_params); + return float16_round_pack_canonical(pr, status); +} + +float32 float32_sqrt(float32 a, float_status *status) +{ + FloatParts pa = float32_unpack_canonical(a, status); + FloatParts pr = sqrt_float(pa, status, &float32_params); + return float32_round_pack_canonical(pr, status); +} + +float64 float64_sqrt(float64 a, float_status *status) +{ + FloatParts pa = float64_unpack_canonical(a, status); + FloatParts pr = sqrt_float(pa, status, &float64_params); + 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 @@ -3304,62 +3394,6 @@ float32 float32_rem(float32 a, float32 b, float_status *status) } -/*---------------------------------------------------------------------------- -| Returns the square root of the single-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_sqrt(float32 a, float_status *status) -{ - flag aSign; - int aExp, zExp; - uint32_t aSig, zSig; - uint64_t rem, term; - a = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if (aSig) { - return propagateFloat32NaN(a, float32_zero, status); - } - if ( ! aSign ) return a; - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - if ( aSign ) { - if ( ( aExp | aSig ) == 0 ) return a; - float_raise(float_flag_invalid, status); - return float32_default_nan(status); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return float32_zero; - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; - aSig = ( aSig | 0x00800000 )<<8; - zSig = estimateSqrt32( aExp, aSig ) + 2; - if ( ( zSig & 0x7F ) <= 5 ) { - if ( zSig < 2 ) { - zSig = 0x7FFFFFFF; - goto roundAndPack; - } - aSig >>= aExp & 1; - term = ( (uint64_t) zSig ) * zSig; - rem = ( ( (uint64_t) aSig )<<32 ) - term; - while ( (int64_t) rem < 0 ) { - --zSig; - rem += ( ( (uint64_t) zSig )<<1 ) | 1; - } - zSig |= ( rem != 0 ); - } - shift32RightJamming( zSig, 1, &zSig ); - roundAndPack: - return roundAndPackFloat32(0, zExp, zSig, status); - -} /*---------------------------------------------------------------------------- | Returns the binary exponential of the single-precision floating-point value @@ -4203,61 +4237,6 @@ float64 float64_rem(float64 a, float64 b, float_status *status) } - -/*---------------------------------------------------------------------------- -| Returns the square root of the double-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_sqrt(float64 a, float_status *status) -{ - flag aSign; - int aExp, zExp; - uint64_t aSig, zSig, doubleZSig; - uint64_t rem0, rem1, term0, term1; - 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); - } - if ( ! aSign ) return a; - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - if ( aSign ) { - if ( ( aExp | aSig ) == 0 ) return a; - float_raise(float_flag_invalid, status); - return float64_default_nan(status); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return float64_zero; - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; - aSig |= LIT64( 0x0010000000000000 ); - zSig = estimateSqrt32( aExp, aSig>>21 ); - aSig <<= 9 - ( aExp & 1 ); - zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 ); - if ( ( zSig & 0x1FF ) <= 5 ) { - doubleZSig = zSig<<1; - mul64To128( zSig, zSig, &term0, &term1 ); - sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (int64_t) rem0 < 0 ) { - --zSig; - doubleZSig -= 2; - add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 ); - } - zSig |= ( ( rem0 | rem1 ) != 0 ); - } - return roundAndPackFloat64(0, zExp, zSig, status); - -} - /*---------------------------------------------------------------------------- | Returns the binary log of the double-precision floating-point value `a'. | The operation is performed according to the IEC/IEEE Standard for Binary diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index cebe37b716..9b7b5e34e2 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -251,6 +251,7 @@ 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); +float16 float16_sqrt(float16, float_status *status); int float16_compare(float16, float16, float_status *status); int float16_compare_quiet(float16, float16, float_status *status);