From patchwork Wed Feb 21 11:05: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: 129017 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp490381ljc; Wed, 21 Feb 2018 03:05:53 -0800 (PST) X-Google-Smtp-Source: AH8x2267LTTmNqstj4b0jDrHd7xM8bmJRtMTjX+b3rWEUUdAXnbKOqtji/abYAqiKch2xxQxrZYo X-Received: by 10.129.141.73 with SMTP id w9mr1893698ywj.211.1519211153815; Wed, 21 Feb 2018 03:05:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211153; cv=none; d=google.com; s=arc-20160816; b=Qib6L/csn/cXUfhT1lXHgE9wtdskrvlch9hABfj0VWUtw7V1NtGgJBWt/YOJOl11eJ lNVWv2DRTlf3eHg81dmfK1tEU2VbtYnBC6NMRd+Ys4Y4UJSgWw5Ookc65Xis4VWCUNcQ uxPzcalN41+Mw1J88UeT314F6x3ObUVsiJId9p3Vv5JSRxFB6gLqd+71i3lgb7HxSyqB 5rgFxTAk1Nv8JMLNKkRATNxjBY3ZeMANymtFTfy5T41QCDkFGOX6mVUZUVAOulAFOM9H AmHir631om3J6XrApymYw7Wk/mghdOWcC6nGP/555D0crEH0dilIQvUvsmHJP7vwUo9V japA== 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=6fRZYTkBwQgN0XXVmqeZavsg0TW6RgcOAWFA1Pfoyk8=; b=wCq1hPkNtHkYhGrn/54cyv5p+q0oTe2c241h5PmV2vPd7sBrCqhatT/uUoPHHTSfTT yMQCYFnLMHTfuOM7s3rsdVKIx0YJYraTJToQGJf33A2QtC+Omc37ln1zlZEwCLBMTRl/ hsH+BekRB2opeAQ9Axijvq0sf5VuUcGIqhepf9iAw8z1l/z/HfYx3HfmDekKFl5bK24O bwRgktQsNjm+OLzwqlyDwMbZfwwit26Yi/f1+LWQQnx03FDLVVtYIay1vcHgdDWsikSu Gf5zQIMbfrGRXjAD0qFqgOXkMkGqGXNws7H8qdYv/aTfcsBYft4PlHW+EyuS7kTQIqdv sNag== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=iiyQUOU5; 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 j7si221611ywa.68.2018.02.21.03.05.53 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:05: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=iiyQUOU5; 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]:60035 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDh-0003rq-3N for patch@linaro.org; Wed, 21 Feb 2018 06:05:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35234) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDM-0003ra-5S for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDH-0006aj-IO for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:32 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:34340) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDH-0006aU-6g for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:27 -0500 Received: by mail-wr0-x241.google.com with SMTP id m5so3299274wrg.1 for ; Wed, 21 Feb 2018 03:05: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=6fRZYTkBwQgN0XXVmqeZavsg0TW6RgcOAWFA1Pfoyk8=; b=iiyQUOU56dsbC0rz9aUz26nCK+rSZu2kHunXXDHZH8mvlpMdGNygjI/LtUIE9OEYXc FgFT9SzhYJkUtOCXzyksSA7Uti4ozZQEvP/JzqP9JCg2fHOUXqImJHzOJaIkXr0ceoNx fxROpHPbBk+Yh3CMVYupPf+NfYYAD8USzbJ9w= 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=6fRZYTkBwQgN0XXVmqeZavsg0TW6RgcOAWFA1Pfoyk8=; b=TVaC3lzPhfusVj3uVQE7AJta7uTy0MmQ9zOAzhbuPKm8LsoRIlpqWWUbqoXVPN7u7L xeoZAQg5JwuUVu0SF/ioYOh4g3aNdwUq6WcTEB7oIU6ztyVxcz78QqMuaIcBJMt/kyGe BkITL7Ji3BiEMexN5LTiuC2ZbAzR61qSFaofJlMc4K/0Q5D+Fxyru0zVs4M1rM1Zt168 yN4VoIThLBO7w6dTk6TO/c9BDmYs4pJNOs3kwreWaglvuSd5DJYxk9e6PAoI75pDg1Lt /+3NFAVDotbNn4RFE4VJOqiZ78lav2N9vtQPEZhJy/aSVtnKte6SLgb0KsTVGvnR/qAB /vDQ== X-Gm-Message-State: APf1xPCSW0D9Y78KSma7FCh/vN1JJaTMTgro7TXyREexatY63DPPudVs /lF4HSu0Q6Uc4s/zZ8cXaUJqKw== X-Received: by 10.223.156.145 with SMTP id d17mr2662445wre.1.1519211125987; Wed, 21 Feb 2018 03:05:25 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id y1sm5858662wrh.80.2018.02.21.03.05.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:23 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 249143E01B5; Wed, 21 Feb 2018 11:05:23 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:01 +0000 Message-Id: <20180221110523.859-2-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 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 Wed Feb 21 11:05: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: 129018 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp490771ljc; Wed, 21 Feb 2018 03:06:13 -0800 (PST) X-Google-Smtp-Source: AH8x2279K+OyGgTIc0qPxOWM06xUk+ah+8AFXoyVP79Uz9x18yzbuh3U7uB1oNAqiJRGH78i8LPr X-Received: by 10.13.210.69 with SMTP id u66mr1791571ywd.271.1519211173732; Wed, 21 Feb 2018 03:06:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211173; cv=none; d=google.com; s=arc-20160816; b=T48/JcbCEjJfqBmusngAWMbhTKmbqWbLwe0JDGdH2zwFlmxB5XHjGOzTbh3kiHkWYT +SoY8QfrPVAlpBxx30DW/PySL6sW47/uUt5bZPL59cAOSWA85v+scLpZCy6dsOKqydhA OoxhnlP+gM2WKAD65t2mphyXcDddj5aFMa6WoEUY0WiDx+MouZkMUJvb6gqL6rUYYfAI kAtamFrfJITKaigdND7lFC0R+2ko5zP/EMU+IZEoA0IRRDxhLX3RXqp6kgF8DhSWeipD g2+QIaZkm0pWasAe0dZflldiBdqe7x53REttEO1kMNWjF8g22URd8QeBZXO3TQa+ilzK JuDQ== 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=CyGDq8tNesS2rDqF6Ds44vPw+vKj1nIBkuNu1XbVG40=; b=XPfZFW9wUIcJZ0DOAk6ZLmwNnY5ORPtnEhUChAE3EyTv8oH4nZpwyCxxftCOGQHz9V STk5/MzLUPZs1L5AF0LQtu1Xu+hrdNC4CiFD/x+NJ7X9WqQAUt8Em/rtqeTr5oCRAJ5I g28Gs8T+wVOaiQewZrKaDKa4VHQbssha6bM8/HsImzHUurK+UbzCG5tpm/rc79qXNT6k xMfPtPNUNkNn9kXKGC50bcVUfH8/2mkPNGaXubiY5Ih3e6f3acsNky4kj3TcRAvyAGsQ u1HmeAg0N+g9xdvKdXbzp0pUeZIWRusjEmGu3cQjC4i7YSJQjkI0qo8+k499IWI6KJuR xlaQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=VkTPdGtJ; 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 m4si412115ybk.434.2018.02.21.03.06.13 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:06:13 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=VkTPdGtJ; 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]:60036 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSE1-0003x6-3m for patch@linaro.org; Wed, 21 Feb 2018 06:06:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35260) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDP-0003sW-3c for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDJ-0006bI-06 for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:35 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:42327) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDI-0006ax-NU for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:28 -0500 Received: by mail-wr0-x242.google.com with SMTP id k9so3264670wre.9 for ; Wed, 21 Feb 2018 03:05: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=CyGDq8tNesS2rDqF6Ds44vPw+vKj1nIBkuNu1XbVG40=; b=VkTPdGtJe/1M9vIc7GJoC89idYA4hAowYN9ENn54H5xXt7U1Qo3N96ppDC1isPm2fH WEED3/wXsI3AGkMPPVPVj4f7hQyFzw+FE1xKzKdB8rfmEFBrUPlRwzR04to+jOhJfuK6 RK28zH0GoyFxQXjPbIeoNVXALRA/FJJDZovXQ= 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=CyGDq8tNesS2rDqF6Ds44vPw+vKj1nIBkuNu1XbVG40=; b=r1uVPthCtlsAiKapV1mdlrubX8XwnGZ36Qr+VE1zo300H2eDM/TeJ/lgODOYwCJyM1 f+Hrgece3eAbN20AqJ7MsoQltGn+KOx+YdizSnEiJjOBC6RtVkOZ2xftF46kcfr78mkZ aAn4y9mE8swjSjl51u9R6KcAJtKZPaEgVP0H54FLDmDDWh8jF23TRo/INqDCqMkRejaK i8IoKe3osbyR674dF+Y5YiIOOQ6G0/ak//iIqIYDM7CwuyyCEzpNqxepzpWcWli+nC0y WVOB+nwufkKEbg06ZbMNywECq4C+p3Zjv07W6W1qLKBWXkasfIvncAKRFrKeZ3b3mh3p dGyQ== X-Gm-Message-State: APf1xPBKZrRUSEFubXQtFqLY+furzWdrkU1mxjqpTPmfMEPGOU0d6Zyh u5f6mMbrNnwCfsQx6w5WTFIciA== X-Received: by 10.28.149.8 with SMTP id x8mr1866297wmd.24.1519211127558; Wed, 21 Feb 2018 03:05:27 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id t14sm28929630wmc.23.2018.02.21.03.05.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:24 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 3584D3E025C; Wed, 21 Feb 2018 11:05:23 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:02 +0000 Message-Id: <20180221110523.859-3-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 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 Wed Feb 21 11:05: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: 129020 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp493314ljc; Wed, 21 Feb 2018 03:09:02 -0800 (PST) X-Google-Smtp-Source: AH8x226VNPtM1MabHdnHW0whHs56aT9oZLc14WJwoF3tuzNjrJ5ry/Vm+THekBt4Vlk/661UdCDS X-Received: by 2002:a25:6903:: with SMTP id e3-v6mr1960595ybc.304.1519211342822; Wed, 21 Feb 2018 03:09:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211342; cv=none; d=google.com; s=arc-20160816; b=sjkp5dx4AgOOjByBgWQm7imNq/R178y5OdPawFELKyhUCpoIjIGv2LmX1a3FR3yIOi URSdG6mcCmbFcNVOjJnXArBmyaHh1RESo5y5eOkEvWHKosho/qQIOkwFrtGng/hi7YPK lvjUhSafzL0WNFi5/PXrEX5X0mYf4b5ckfYXKqI/fcMEF/ux8fzxc1z+ir6j0+4n3ypb PnZUkilYCSjhzUDiO+bO46CtmQzO7Jr1aH4JbPdKmRRANGcy12KHuRWfrKDSkBDxWdBo 8nMTttd9ToLknLXaI9jQzH5wkcscjfWEF8VbMzArgypKIMG5vdYOn4bTj1keQYhV0d5Z mQTQ== 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=+EQ+3TizRaKDBtFDJFNQ6IP628cXfYSPPEUh4ygb3Xs=; b=gmWLSg/lWe+GOigKa7vuQn7CT3skyyDK3x3knzT3RIV8mzR17H18UYw+MT0s/9VDyo FHVyL1hT+ZCaV89QiiHEQxtU0XQChQTEzvPpZ1jw/54mAncKjqtWcole+PYax6A7KKpX 8xKyeE0ab9pcXgePmst0Cx5TseEQVRJOuDvHKdiqxJ7FoAeQgT6lzXb+PHUyskaidgHe xQFILsJQfdaMXrZSqJFjc4l7ae8aHBNGcIC0zx4dVhiq93lT1UtywVoqmnorjmUKAx1N xB6QBGEov8Nk9y3nLbDESYNiLZoEXaT5BdfC+h19vlsdhQe5tgef9/uZLOk+knmAUBNJ CS+A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=h6FCaDJk; 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 d139si2268740ybc.273.2018.02.21.03.09.02 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:09:02 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=h6FCaDJk; 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]:60046 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSGk-0006FJ-5C for patch@linaro.org; Wed, 21 Feb 2018 06:09:02 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35250) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDN-0003rp-Tt for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDL-0006c6-TD for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:33 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:37636) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDL-0006bm-FQ for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:31 -0500 Received: by mail-wr0-x243.google.com with SMTP id z12so3285982wrg.4 for ; Wed, 21 Feb 2018 03:05: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=+EQ+3TizRaKDBtFDJFNQ6IP628cXfYSPPEUh4ygb3Xs=; b=h6FCaDJkM6OxuUsPNHA+UvsUa4elkV3jWeYiH0vOHencGXdXhb464Bshpd7vRY1wz8 Fnrrh4RkFaOo7TMRas2GcSwq9/Z21WqxAsSq82ELZBPwx9WXiVJUVhXqmDZI8FWdwU5G N+dJXywaucbbBnKpAllV7nxo6BosWq/WU3SiE= 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=+EQ+3TizRaKDBtFDJFNQ6IP628cXfYSPPEUh4ygb3Xs=; b=NCsGDCzVZmdkHJtTnUFFzZEv/ZJVr0G5YugHggn0aPKmXYJ36sEsFDQgEqa+pWxS1I Mq1LwyS64Xw1+Vq6NcemTqdKAxvYK27pN16SE9yezpddITrLsAIeE6+Ekgqx63iQnwAo fl+xloe4gwghRI/GnXkODp18IvW5adVxab927yuoBD3MLl32gFtI6tTtAitPAxoImLk0 tTNz3okebB/iZV712x4KPBH7XToeNPdRe8sZlTHTheWchwnhD4nLSv4C+sJ0FPYKhlw4 uWfT2MDII/MSJCkFeB2wRQlJ5bUgV39yRrI46GZVNE4LtUdh/DzdPrjADAZd97E3BzvE t08g== X-Gm-Message-State: APf1xPDnbahmgJRtTAvTP5rcXbADzcw2IEHjM4rAt/GS3S1LOeg0xRfI m4KvytfgiHnmxye1EzYn7vHPdg== X-Received: by 10.223.161.77 with SMTP id r13mr2735042wrr.230.1519211130099; Wed, 21 Feb 2018 03:05:30 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id r136sm807628wmf.18.2018.02.21.03.05.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:26 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 497903E03B5; Wed, 21 Feb 2018 11:05:23 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:03 +0000 Message-Id: <20180221110523.859-4-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 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 Wed Feb 21 11:05: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: 129025 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp496731ljc; Wed, 21 Feb 2018 03:12:48 -0800 (PST) X-Google-Smtp-Source: AH8x225ZLGvS+kszW3loqcQfdvLnHHPj4lC+NvkGcAEyMasPMgM3JvQaEJ8WBYhfr+8EQIJjXnVL X-Received: by 2002:a25:b687:: with SMTP id s7-v6mr1853504ybj.256.1519211568263; Wed, 21 Feb 2018 03:12:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211568; cv=none; d=google.com; s=arc-20160816; b=WDjQNMN2UT70/OhKEDupSx29LeqvpJwa/wE60WJ2igp00KJ+ohOfhQ4/L/g00YZddL Lse06FTqgJmshXm7FN6dHLD7bu//FqLcgJ5DTc0hV/UQl51PSdf5E2bKbcHCAS+9QzV3 DTqJCUiLy9DKQt2x0sIlr42r/8X6vqtqf/I/DzHehUmp2bNrWXKV2MUAY9/z71bBVM6r sfRxLLqERHUtZ2ilawF20F2nnNMmEblOo65t/fqgFpDA5yUh8+lADbz7/IJImSeYzXLY 3vbBFkhXLy18RGh9QOapnO2w9PEf6Cix2OzlA7z70DXOoToJo98x+lgyHGzYneHEFFyJ p2sw== 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=3Pje3qpnQkb9eIsMk56uuiWbY2Fsc/ZS14nZT5TCxsc=; b=wNyZFLVkVE7GJ9UFKXP02ECxYVuETanx+YF9rqvolKd4VAyjBUOsGQxRZYB2isNZVq LyK2EZti2zd5t6sDKjITz716GWj3z3uIvzdqYJDkp5S/NKJrlx7pKRprYWrfYF9MUZW9 tu9/qIMiRNb0sgBRiauwHVH01ih3tk1LFPVWfF89Hz3COt2bGMV0hLPR+RH566apI0Jq XVuei280Qikc+NMu0Q9NNQfjLRUzOm8zGnK+u0B8rNTtL6yW4vV+nn3voFFgFk3Uc82w J8iNcmpPvlxHVBC2EW9mN33aEFR2tbIaUkFgrnubmhm+QpAjORUGTLHlwbf8QEPcILcv C/nA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=OcKz/sYM; 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 y68si1574893ywy.327.2018.02.21.03.12.48 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:12:48 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=OcKz/sYM; 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]:60074 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSKN-0000xi-9U for patch@linaro.org; Wed, 21 Feb 2018 06:12:47 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35315) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDT-0003vv-WB for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDO-0006dH-8i for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:39 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:38134) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDN-0006cj-Sj for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:34 -0500 Received: by mail-wr0-x241.google.com with SMTP id n7so3285116wrn.5 for ; Wed, 21 Feb 2018 03:05: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=3Pje3qpnQkb9eIsMk56uuiWbY2Fsc/ZS14nZT5TCxsc=; b=OcKz/sYM5CfCrDKgMLLWAix7IO435gkWfdAhX+1j6kWBXBfG+qFPa2EBJjCdrsPlqL iAV1Q4aOfPkGrAwKL5ICKdHUM7A88cLtKQunipuE3ye3UuaCXBwZlMxplaJn/WrKfose I7XL2CKsItOnNeB/8s6Hfc3FqrQdPiLdfjtjQ= 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=3Pje3qpnQkb9eIsMk56uuiWbY2Fsc/ZS14nZT5TCxsc=; b=f9C1irm/eVXptkX9Wnj0IdXB8VvsJnccUkjgA8LlkoViTtjy3wwii0++VKnjBgW/PB JSr2CXevWRJ5ugvCtO+6Tvf++XA2vCRWJGqVX919QYkHKBKvt3g6EbH9z+37znB4aM3o FJ+EcyFHa+h6hlTzDj+c92fWfQHWEVxotM+a4nVm2ArM0QjEsy2AD1Im32PR6FnMMTgZ x6q4neAwGb+i93w2Ab7GeX45qF8hfWVeEsa+FvLrk9eQ1SBtFoqhlA6QRQvUcamT3NKK rajS7KwW4+9LoLeNjepxudYtfm7axqAoZaAmOoB4su9aoDlY/sG3Isq5QS1PQ/fyb+fQ NcGA== X-Gm-Message-State: APf1xPAhGPRPVlcFB4cBBikLGwKYZdZZ4j3vsZGf4yYG4bVRv9J61dgC qqma2leIcCPCjOs5WkObiJrH2A== X-Received: by 10.223.152.228 with SMTP id w91mr2513473wrb.74.1519211132505; Wed, 21 Feb 2018 03:05:32 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 62sm1596570wrf.24.2018.02.21.03.05.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:26 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 8CC573E0427; Wed, 21 Feb 2018 11:05:23 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:04 +0000 Message-Id: <20180221110523.859-5-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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: Chris Wulff , David Hildenbrand , Anthony Green , Mark Cave-Ayland , qemu-devel@nongnu.org, Max Filippov , "Edgar E. Iglesias" , Guan Xuetao , Marek Vasut , Alexander Graf , Richard Henderson , Artyom Tarasenko , Eduardo Habkost , "open list:S390" , "open list:ARM" , Stafford Horne , =?utf-8?q?Alex_Benn=C3=A9e?= , David Gibson , Bastian Koppelmann , Cornelia Huck , Laurent Vivier , "open list:PowerPC" , Paolo Bonzini , Aurelien Jarno 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 -- 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 d796085be9..1b3ae62db6 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 de62df091c..8c839faa8f 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 e7586fcf6c..32e4fd4732 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 7b635cc4ac..969f628f0a 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 3026714471..a4ed8770aa 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 1d79885222..65f4fb95cb 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 70c7583621..93cd38950e 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 d8df2fb07e..4dc1404800 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 cbaa343e04..17a87df654 100644 --- a/target/ppc/translate_init.c +++ b/target/ppc/translate_init.c @@ -38,6 +38,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 da7cb9c278..a665b9e60e 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 21ce40d5b6..96df2fe5c9 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 e37c187ca2..6302cfda3a 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 fb837aab4c..29d160a88d 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 Wed Feb 21 11:05: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: 129019 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp490779ljc; Wed, 21 Feb 2018 03:06:14 -0800 (PST) X-Google-Smtp-Source: AH8x227/2SooiAENLCR41XNYLKTVvEwJtEVygNbOOQGzxcErwfQ9FWxDTgnq8Hgd2MYQDYxfLD01 X-Received: by 2002:a25:b7cf:: with SMTP id u15-v6mr1946902ybj.416.1519211174452; Wed, 21 Feb 2018 03:06:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211174; cv=none; d=google.com; s=arc-20160816; b=oKU7m8tRLcgR8z97ci1+rEs+tC7R2W8Cp4Hd25LTcIa8+tdABT6+HhUqsVlQPyuaSk Ha8MjPt2FDW13tVHWmoYMoycxmwrJqLEEFZjkd12Zv4tB0iU28pCjHA8SdrPGDeZpNBV TtM2ww0ecFoPs+gd7RZhobjEh+lhOHTl1NFcvHe5r/opnhRINpdhvLhPxiZNrUrF9X/Z p+QHPfoXNuzZttt7TUzB6Ww5awwqrsPXSXF6DMgENIERH/u9/oMQOwns2Yj0cEfWcxzr 7P01gxVxsD8wBwPiv1OmwYYP+2emaFgoXDT4KujsylvLnnKx682Xka7Fup/B9evOx3po HbNg== 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=52FcgKh5qAB1ULhGmZ/lCIJkVC4Sw7rnuelKDz4ZKHQ=; b=Jf3AM8x8hmzW2Gh3a3X8zUiQDan+PfG7FYp14E4LsTi16CswNxOY38k+IJBOvjCve0 3Pq101b+5Yemg3XKzJ1uFlNlsFKH2J2QIJii8pmgA53GBJ/2qFtgPB5APB3N/m22L4Ds IYIejp8zYV6QsWUJG3KZ4OEcRHh8LXp05MXRbEUAS1CkqdWw5Hx+WbWW8SFdkxwAjHN+ Tvd8VwH4TbdRSzhMwUGTNKkYsvaiKLzMAUtawMhGMbn44Zd6znl0I64uP8iFyPKtfW/5 fg4cdTx3rAVL2nBA4yGrDoeRN1kaOyBjxyGt6VVvGYiLEHWpe1r0xWUPbnqIfWWPOckn xjMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=TdODNVUf; 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 b65si387099ybh.679.2018.02.21.03.06.14 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:06: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=TdODNVUf; 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]:60037 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSE1-0003xa-R6 for patch@linaro.org; Wed, 21 Feb 2018 06:06:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35270) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDQ-0003tA-0M for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDP-0006e1-7M for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:35 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:43966) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDP-0006da-0u for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:35 -0500 Received: by mail-wr0-x244.google.com with SMTP id u49so3259133wrc.10 for ; Wed, 21 Feb 2018 03:05:34 -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=52FcgKh5qAB1ULhGmZ/lCIJkVC4Sw7rnuelKDz4ZKHQ=; b=TdODNVUfNbIPl8SB1SIP6HyF6vY3EJ/etOzU6FC8C+cbHlk2ATihiUTs5gp5hb5K+z dTUbd6JgNStF319n0OodnBPydE0QeeTr8LosWeJyURFg2p1M6g+Q3cbraWJM9XFftNo5 ExrkN9Y2qOuNEfDl3QZInpYCBHW5IMJ0EStEM= 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=52FcgKh5qAB1ULhGmZ/lCIJkVC4Sw7rnuelKDz4ZKHQ=; b=ld6qe3imEIn268m/OfPI6KbA2VQeC5T9+Po4e02+JRQRk1fbDiUVWy/+CgseHrcJXv HSzBvsHdiEAh7kNwbdiqjlzd7azQGcEFSY2FS2jCVLDH7JU4oiBMGD5kBihQJiQkHTSP YCpNGkCpw17Owo8h8BI0kVJdTDHtslvQUumkGpyB5ALjT80sElO+u4kEpZEarjkGGluV kkoAHcTGjYr54E11xPd0rWw9GHcmVxuYHZDfl3b3J2e+q5h3rkSEG8GEBpvrwOqejh64 4BayOJ0YRtBJKaXn662W4THOppsyfBruQ2rD+Je513knmgp6O1E1YoM070oxJH7lD/Ie lmxw== X-Gm-Message-State: APf1xPCV3Gq1Txi/6UYuk4Q+7AQPCiC7MG1vZM9L/ImAbelZQ/+bwShU zQctNQPl/YGXVmyBt/np8X3H9w== X-Received: by 10.28.40.198 with SMTP id o189mr1678104wmo.141.1519211133951; Wed, 21 Feb 2018 03:05:33 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id k63sm19821228wrc.30.2018.02.21.03.05.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:27 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 9E9823E042D; Wed, 21 Feb 2018 11:05:23 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:05 +0000 Message-Id: <20180221110523.859-6-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 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 Wed Feb 21 11:05: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: 129023 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp495882ljc; Wed, 21 Feb 2018 03:11:47 -0800 (PST) X-Google-Smtp-Source: AH8x2263F+2Nr3JG2LlQlGWtVOKE44Gg0fwQ4HdNAQ8y021srQT/aYyAngoT5eVDzTyfQjmSdPFG X-Received: by 2002:a25:f40e:: with SMTP id q14-v6mr657317ybd.334.1519211507859; Wed, 21 Feb 2018 03:11:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211507; cv=none; d=google.com; s=arc-20160816; b=Ll7HLs4rlCxGVAv0GkhFY7QL0uNXuUDnOdHhvwG1iVqo3fk/AU8kkkeVgctdw+VZIj 6U43n4iLmVu2mxpe/myCzsqEIwARhhek56MUXurtRdLvzI4Au/6ZwrFZCWTksNjx/1mp 0K0hY0smZxfW0hCjlufTWiag+36BJu4ZguzY4Kb56TIvdBVkM6XIrrjXnDoVo9T8OSi1 mhvL2T7NvDF0BGleQg+bC6qEdLpvllc6+DMCloTWVgmFqzlsoiTpgp5CdjsbbH75OKmd nDkKrOwqmw+Ul+ESSWJvj9ITVmdAD4zxe9pWh9K0lTP5McPUe5ekand/yloIi/LM9TDP 4Khw== 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=V1rIefF1xH1GH1x1k7AGkSIkQ2sRzhLOIW7nEZh75ts=; b=qXldG/ZuZ3YSyJCqEyytPzPjpFcMyGOn92qGlYeM1l30m3St/WCO7ic2cEu0ef5rDc Dc2htxeIGRmI0O7p5JBAn84MR/xFst1//FoGYYZtRqFGAP8Kc2D8vstLONihJ2YIZu6f LyXEWZVFbBqkSj7RrjSUgmkzlE3fcAJf+KbpNDTkWOOMBrO0JlLxGlt8Zsqk0Ro91JO3 KMQwtdIzmB2URGdKK6jOzPIgpVEPk7vWW1d8M7mAErc2FI6Xt2KNtLOPNMMFj/K6j0Vi Nm/w4e8TPUBhqetV2XeIME8886Q4MCh79KGRUXV/HoNLQXodZBa67nTrn7xqUbCbrsNt 2wfg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=e0Tdg1FO; 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 w3si632127ybi.754.2018.02.21.03.11.47 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:11:47 -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=e0Tdg1FO; 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]:60061 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSJP-0007mv-5t for patch@linaro.org; Wed, 21 Feb 2018 06:11:47 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35318) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDU-0003vw-14 for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDR-0006fF-KV for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:40 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:43965) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDR-0006ei-EE for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:37 -0500 Received: by mail-wr0-x241.google.com with SMTP id u49so3259496wrc.10 for ; Wed, 21 Feb 2018 03:05:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=V1rIefF1xH1GH1x1k7AGkSIkQ2sRzhLOIW7nEZh75ts=; b=e0Tdg1FOj3DTBxDE7DIpFLAV5rNinLHxywdHw42ZNrDxljJttP1YREivz1L26S8Tuw YWYtPQGICRo45ggR8v9Hn9dy5n9gL7W/UUvdGwaqi/2tfl/JuKLS1XQBuYddf5zVtlMT 3hCFn4B3tkDbAI9RH2LqUyQ+qG9r9aULWHlG8= 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=V1rIefF1xH1GH1x1k7AGkSIkQ2sRzhLOIW7nEZh75ts=; b=Y2lW2FPQgo/T91bqbPS5kdpi5WZkfM1Piz2DjimE+5DwcjgKqQzT2EtT1qR1SSSBkj RMjGS0xHaisCfpIMd7N26MScHvzz3tlLdzfw8zl2aPZKrpnkz6shjVg7yanun6Bb0zZt B4e44JLFB04pbB6QvQXpAqTi/QkpIUeY62jNHxb3L/bi1cuJm0JbWqr/B4y3+/RvzeId qVISDUCcQWZ0RA0F7b7ZIUdsJ0rzhtqSD+BOk+JfYec4rLH/ukX/MYZobn84oAlSeEH6 zQTwtb0q0VJVXzEC/JdfUshazE1+uctJTXVzJiZJLk3u33PpqHHIWsZUtqiFxP8m61oA +mTQ== X-Gm-Message-State: APf1xPDzuWV/MEorbBuXcrhJZ6Qbqs1Jb/Z2JBLA6WMHwYluZTcY5y7N aRxo9Of+86b8MExROqYrXCvlBA== X-Received: by 10.28.109.10 with SMTP id i10mr1876586wmc.107.1519211136364; Wed, 21 Feb 2018 03:05:36 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id b136sm21711065wme.34.2018.02.21.03.05.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:27 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id AF8E23E043F; Wed, 21 Feb 2018 11:05:23 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:06 +0000 Message-Id: <20180221110523.859-7-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 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 Wed Feb 21 11:05: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: 129022 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp493673ljc; Wed, 21 Feb 2018 03:09:25 -0800 (PST) X-Google-Smtp-Source: AH8x227+AZSFf8Mn/NLMf6TMICd84kUiIy7X+8dKlwdWj5Hhx/OA//dGvVaDaFXOV/k8VkPlepHN X-Received: by 2002:a25:4986:: with SMTP id w128-v6mr1854548yba.131.1519211365672; Wed, 21 Feb 2018 03:09:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211365; cv=none; d=google.com; s=arc-20160816; b=eqcDaWPS762QnuoNfRUmtmEHRnTdamRrICrKnkn4MnbnZav2Qbc1JpCsZZbWuBKA+D GpPtlWoEtMjtxAuJaslIJRljpUvGRyWm1TrkHHTxAE0ET7vg1j9oXdPdzgnIwVfg5j1Z NnxfeqMCFrANHu/e4yfavqEDqcu8lUDt4y1ZNp+TL+G2V8LF4mRTvOuOZ5BPNKYfSB+5 SNaR7PuTkj3JXkAWvFIq5lUzp41NDQMHY0HOAVvC4ANgHdOZeZikUwoweQp9THQ2v6wg fa94bi5kEHCNjVV4ECSRX5woqaSnqJ2l6+lOC84TIrtU8PHgm7q06uSETSXxiDANGLaz dZpg== 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=vXkNsIDqo1oNimk5xnCFWIScB/6Sj4wc1llJWSRVUwE=; b=KE0guowaehOg/g8I/V3NrJsCsxEY9n2mwA5uRhM5Rz2MbyNp4F1kMfFlELAZqoGGBg +OvdJCWMpKAPKWsnhK714OjEoer6YCQytzkGTehvE6j73zSL35AfEycy8fPbWUfbeRRl O//KsQ7QlNybW2RDMfrtaMKZYzESkllj+jHoRySKaw2vCcKbUCpYaRxjddHcgmtXoHkZ GGq2sxJ01DPXK2tA1WACZj9PqK+Uw3uqGI/pMyNU8o1oLS8OMXkE91H82JSUTBTaPAq4 jj9tJ3RXIIdHfzWPH8gdncUwTAk3+m+/stIDnoDilsEXMrTk6BGcFmKqus57eFpjSj2r SR3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=e72hcJBb; 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 k123si2169356ybf.412.2018.02.21.03.09.25 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:09:25 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=e72hcJBb; 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]:60051 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSH7-0006aP-1y for patch@linaro.org; Wed, 21 Feb 2018 06:09:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35349) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDX-0003wt-Jm for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:44 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDT-0006fw-PE for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:43 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:35064) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDT-0006fh-IK for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:39 -0500 Received: by mail-wr0-x241.google.com with SMTP id l43so3289700wrc.2 for ; Wed, 21 Feb 2018 03:05:39 -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=vXkNsIDqo1oNimk5xnCFWIScB/6Sj4wc1llJWSRVUwE=; b=e72hcJBbhCJgtlhl6UjBJ/sjVxkAckPXmae11e8DR4eE1vuYSBZuqe0TUdHvBV2PDP S16chsjtuYmx4bKs55zDUnsL30z8raVPN7LsWjUcC3V1Xcoaqc6iwIoEKk3zH4hsfjhb oCK/XXfx68G2V+i+hR9aZYQ2iDvGusN5Y4AiY= 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=vXkNsIDqo1oNimk5xnCFWIScB/6Sj4wc1llJWSRVUwE=; b=tYMBZgaiJshGZQWtKXuk5opcvmdzNfWdQGFYOKTAaN8PRMJBIZwtt5RyAON+3xRAUD K63YaImkKaZFxSZvYg/+vE5WTF3qPtcErc+nrlEe77Qj+48F3GBKNG8HAXLOCEMIQcjL BBC9/Nu5UcRQplRta8i4VDzD5V3wvszM71lk9zpgt3OqvB5OWiLEzLCpPTVzdcJm0zRN 0aV2dFvkNxIsCVrGV+HyQDsayYyzvJuWTZd1jZ83z2r2M8s6HtpWWTtVpfbc1d2yhs6i RMO2S1EsVwHbSoqWtiVoKGFzwYXWufoxz18FHU9oNi0halzLULEoUNl0CGqxDVuCiHRm ezKw== X-Gm-Message-State: APf1xPDdvgfu9I2gd3ZAz7QrYK72nDwDnrOxwvl+MlpbmhM1eoJb5uEg j/voPuklXUn52k6xM1lkswMp7A== X-Received: by 10.28.245.25 with SMTP id t25mr1652429wmh.77.1519211138507; Wed, 21 Feb 2018 03:05:38 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id z1sm26971517wre.25.2018.02.21.03.05.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:32 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id C0BC13E047D; Wed, 21 Feb 2018 11:05:23 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:07 +0000 Message-Id: <20180221110523.859-8-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 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 Wed Feb 21 11:05: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: 129027 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp498778ljc; Wed, 21 Feb 2018 03:14:55 -0800 (PST) X-Google-Smtp-Source: AH8x226boYC0sMeXwpiM2GUF5l3TEPD3wO1+td+alsOwijOrGLW2IwnKj+ZtSg/YwkQpvKXI2/qH X-Received: by 10.129.98.11 with SMTP id w11mr1906972ywb.381.1519211695612; Wed, 21 Feb 2018 03:14:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211695; cv=none; d=google.com; s=arc-20160816; b=QCjrdzK2TLmDkPlXPb0ruxTlbnyncUM8wpI2V67WlQMxVPtvVOTtatokXFibgSg14b A6zw85KADjHi0MZ74e2x2Ul/Rx5gLWmKwf6YSJpkFjlyPJUPyH1zb4H6B/2mMrMWDOon ZGaHtkVIkoPkf0DIWc9LdjuBCtEnX302D0iror+PGutLRAaRPYPCQenLsplC2wwfrrPb YGHTEVseFQYvQy2FUWMTTCYLYLz0Jam7//Vb5OdtLvPDKG5s0wnzRMveGK2eckYTqyMZ 8qYG5oAC5SjmdZ6Xa1QgFU528ioCgannRgwGxD19p+bitRLwfVhNWpZytNOH82hcaMmJ vTVw== 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=vcyRTgec4QkGUdIqcv+Jm4YjeN1OF/RseFEzHdlCSR8=; b=rz6g9Up0K1GDcTrEL7ngRIe0tLb2LVnQaIaAJftfKFqPO5XbHt01wRaMjXR047FpJV mjgvp499Dyao+yvoWuO/TKzJBsvpuoSX4Uo66WLchuKoO2GghkXdtNsBZJciuRQOxJcZ JFtMMSQXEKntBrfXmOcqibbUcXjtODKqLyQ15dHkHOR2MSW6EtgAJ8ziGJ4kT7PREs4p mVeWjzjTF8cx9OqfKA6OEv3if1BTTdwLyrlFDjpShiRibINj0ot3mdxl9m1DPdj43f/Z M/Qdc3tPjfUZXA9BY12p4bpVvw5yJFmcpEUwen7/y4SP1mlCtGkcdARZcgNDZMZavkBH KgkQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=S3tgro8K; 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 o126si1278677ywe.153.2018.02.21.03.14.55 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:14:55 -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=S3tgro8K; 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]:60085 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSMQ-0002t6-VT for patch@linaro.org; Wed, 21 Feb 2018 06:14:55 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35337) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDW-0003wK-9p for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDV-0006gk-HF for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:42 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:37640) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDV-0006gK-AL for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:41 -0500 Received: by mail-wr0-x244.google.com with SMTP id z12so3287370wrg.4 for ; Wed, 21 Feb 2018 03:05:41 -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=vcyRTgec4QkGUdIqcv+Jm4YjeN1OF/RseFEzHdlCSR8=; b=S3tgro8KC6aSvTMhWbjHpxdopASSIHoupjupLongRiqw6Kff9T+mSoe1JfIy1drPRP uSUk6vUuLGPoHI66T/tefwBa07bwC1p3CcFVqQpnAcHoNuFoPNklw26M2WMQxPeyIQg4 Dl7q+u7ueQekcEq92tncfTtROhxFxo7ZqZTxA= 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=vcyRTgec4QkGUdIqcv+Jm4YjeN1OF/RseFEzHdlCSR8=; b=V4d0IWIiPhzSeeDQ7D7qxKIgyzMRUTjWsLiY7sAJbtWx9YGVHQ5EqFFNhvk/JDWxOj AtyeS7r0NpDqsyKRZJeMyDDSVHcNHI8zbiPPUPCPUHSJ3LLn9oRd+P2oQUKiYG2IsDZS vnJlXYReyYzIxmW9aGtEyA9T5sZgARLmQ+cWAZGYE+zksINRm3to8fCEWJJCEk/FPFnj 3IsaTfrgGWaxhY6MmvNp7wnoP0keJP5oiA65OcezgDqHXRyVHsEKa8J0IR+IvUwEgSW9 EnyhcC0IUbhRSMG0f2cjrhu2cdIjlrE4OBY0T5GbOUzkvo19irJ4lmW6Q32ngSl6TQ3p 9D2Q== X-Gm-Message-State: APf1xPAGSCLY0jJKTbFSj9CXJghnsXYDEWQixmti2AlONVPOW46c8DgO fZ+sWubKDVYS8LrFeKGmpUQH/w== X-Received: by 10.223.189.131 with SMTP id l3mr2582413wrh.140.1519211140303; Wed, 21 Feb 2018 03:05:40 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id w31sm10788360wrc.49.2018.02.21.03.05.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:32 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id D1A863E06B0; Wed, 21 Feb 2018 11:05:23 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:08 +0000 Message-Id: <20180221110523.859-9-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 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 Wed Feb 21 11:05: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: 129029 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp501991ljc; Wed, 21 Feb 2018 03:18:24 -0800 (PST) X-Google-Smtp-Source: AH8x224ZLN7MQdI2JKwugoy9j4QU3bW/MfER+eftNzrZrz17Egd5NE3m2W+xU8QrI/G8WEC0OZBS X-Received: by 10.129.94.84 with SMTP id s81mr1847640ywb.243.1519211904210; Wed, 21 Feb 2018 03:18:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211904; cv=none; d=google.com; s=arc-20160816; b=jfDetYTSVxibWRwvKnSNrsZ/27SeAw+cYV9VxvnUh45LmSUkE6DHj7KFUQDoc8VLHf r1f7fE0RuLT6C1Z8LZyB7/uTZnLQoHOUgQfrplJhgMH5iZH3YX63yDEqL4JXomzsyC7a UJjlilgSLmRR2kE7i5LZ5lgr5Rcr35Sulv6HIltmYetHP0R2QAcuIM3NpxQQxn6Qfw6o AExf0kTjQaWd9lyzqIcVn+8GQcZ8nHHuGqnSA7r/TQyvGO57US5t3SMZqtM7AfvC+ltA kj7+aUT800dUcctDlCxg8jvRl7W2Kb741WIpmWvDeiAbwUXXpEJwv6usrKI7WfT0byQi vFSg== 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=5UqaGIR7VPPMGTMdgTD3t4p+27fH5UfnySnUAHOvKqA=; b=N2dVMsNCY9YKoGWXavbiysJEEV8c4no4PKK6A0YoUPzIEHxUbFLR5BTAbnTTkDSaSh roRZrv8hgTlDkl9xZi+QfA74F7EwGTJ7abtiuSVL3DL8kffsFS+gsHXLKt8HV/Au89HC 2Nzqr4tpiCQOx5PZ9ttiR1dQOcJtKTrmbXQ3u/zg0j3tNIsChvmjgxlgHxnEP3NclywX yC+WHkNhd9RkqVKJHvjyUjRoFugSfpPTJ2wj+iUlaUSwPRDN7egiyTyXfxUESZt4wxe4 YBUWgNN+c9hFp1AGkKsvdNE5c3E/hmuj/S70ogUnW+ASo5z5vS3jsuHPC39k5W2UQ442 KdVg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=MnksuVzK; 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 y79si673797ywa.307.2018.02.21.03.18.24 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:18: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=MnksuVzK; 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]:60101 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSPn-0004qZ-II for patch@linaro.org; Wed, 21 Feb 2018 06:18:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35376) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDd-00041r-HA for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDZ-0006i9-Ig for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:49 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:38138) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDZ-0006hu-CA for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:45 -0500 Received: by mail-wr0-x243.google.com with SMTP id n7so3286743wrn.5 for ; Wed, 21 Feb 2018 03:05:45 -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=5UqaGIR7VPPMGTMdgTD3t4p+27fH5UfnySnUAHOvKqA=; b=MnksuVzKr37KlKKAiiqSSlcxUWJJElE38Ayzdw/Ja0I3NjcYKXorNG0tupVjqxXjiT fiEBWRoGThtWk7D34zVXdEH7l3Aq2qIakaqFrKlxcqzS6oUvoRMYDtuhVukXsS+G7G+5 93ZH5vXdBiqnLOQA76zkgJj/QroOVVcRbtLnE= 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=5UqaGIR7VPPMGTMdgTD3t4p+27fH5UfnySnUAHOvKqA=; b=nABGtIO8tuA+eXk1oRhEIHxQ+1RPdxjl724NKPTpQ35mObJpsiPkM2bysDK1u2PrMK qksBfGTQyFqUVRyf0sSoe1zoNpHEPCTrrsLgEKmh0ghvaESHiHbeXeNdVfUKlinPFnRv eHyHNj9GWDL9aK2EXykB2UiUslsbcpJvfMjnj4uoc3jkQwG3SwKfgrRKX2scf3zxN0kf ddixXwRCkfiju6+1gPO3gRnA/GRX+s+cssXUUO0PD9zl4/xUkT4bybT2Sp20Ta6ej/4E IB/AEqyaeM4Hd7P1FR77XigB0jbDt9nCmdnSBmTREfD/rG1/Rg7hEU12ecKjytuWXnJd rlTQ== X-Gm-Message-State: APf1xPChTcYvJQLz2tW6yB9oGtkkMXnYkFI1AfFeMGjrTNLWJ6MfzBz+ LJ+8+1ynuQR8ojhhs0eoBgsrRw== X-Received: by 10.223.199.10 with SMTP id k10mr1162763wrg.186.1519211144357; Wed, 21 Feb 2018 03:05:44 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id m86sm28764363wmi.40.2018.02.21.03.05.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:36 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id E34AF3E076E; Wed, 21 Feb 2018 11:05:23 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:09 +0000 Message-Id: <20180221110523.859-10-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 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 Wed Feb 21 11:05: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: 129021 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp493411ljc; Wed, 21 Feb 2018 03:09:10 -0800 (PST) X-Google-Smtp-Source: AH8x225Cu06HHHbxiDewFoXYwb4Wksx5gACIpPslXjkpZdD3mc2G8PegxZbRwah8hyeNOWVqM4T/ X-Received: by 10.129.38.214 with SMTP id m205mr1895243ywm.436.1519211349904; Wed, 21 Feb 2018 03:09:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211349; cv=none; d=google.com; s=arc-20160816; b=0XiIEBVH7/nV8bqy5DZpGuxeA3Z/U7y0ACle1pY8TgKkBHa8olXzWoB3YlViNtoNAX GpUwfWG/0QR6pEhf1bW4GQ0K3PdIo3dtnXuaEfbbt4c6FN5XaP+T3M3pCrTV4phCbA9b 5PBHs4bfpXjnrZgeVUsRsi9cR03K9AGcQV0VcTBUk7+sIYiV+MEHlPw0jAQy+bPv5blt IJA5zptkP/eBGWPA/C96IhVJk7Gw51bjHHS5GZh/FofxlJ3t9xENAvB7jjEjw63PssKW 6PlqU8rwCT4jwgxvBtfTaDG4pERLNQk4xCmFEisHeaLJB49lO4MIIoRNtv+PbXgLGAnS uNtA== 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=xg2TzrleE+1h+u0B6reJVfYEHy0RU9XEXCikOjlL9v0=; b=Queh1Sq1+cFAn0Wrh3u1mRFfXgCKEGLwELIfFg66Or/+D+u3GcD569oOEufv01KC+i QVUleq7nGyhW3dZnPlgc602ZEj/EUY5tewPa86j/4tYxQOcxC0DKR3vGUHgJjNfEDuk5 d3mBIN+1/wX8m0cT7Ch5+z05eR4l2Vr6bl/ksZwaoP1rT+569dRClmY5+NhWvuPpdu9r YUBx/yWqoVyVVr6fK7WcnVW4pbVWlZAhQTuzqT5LL42RvmHVxoHdpADqB7oXSsSOWurS btxYKagxLx4O1YWAxIk1wtDsu4TzJb2z/+cAEr5jMdcFQBDYfZCdLy7W2ZzhHtij/f09 NRnA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=UmyLk7JT; 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 v68si1716601ywd.370.2018.02.21.03.09.09 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:09:09 -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=UmyLk7JT; 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]:60044 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSGr-0005VE-6y for patch@linaro.org; Wed, 21 Feb 2018 06:09:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35377) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDd-00041s-Hd for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDb-0006ir-PS for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:49 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:38140) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDb-0006iU-GY for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:47 -0500 Received: by mail-wr0-x244.google.com with SMTP id n7so3287058wrn.5 for ; Wed, 21 Feb 2018 03:05:47 -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=xg2TzrleE+1h+u0B6reJVfYEHy0RU9XEXCikOjlL9v0=; b=UmyLk7JTsq+DfhvUYjSE/nnHxanWkPcHvCl4pIY77DjHVcflP+h5wH2QbtN8E2YoVx Ma+EiVcDTWB594XGOKK5zAnjx73fj3DAm2WjVQlRDtTcfbCDmQpcyzPMJzF7gXAuE3Lb 66CZ6MhkE+wB5YlN3DNIdHzVI+j+2X5FovL3g= 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=xg2TzrleE+1h+u0B6reJVfYEHy0RU9XEXCikOjlL9v0=; b=AkiyRm5Iix0CLLu5ibL1V5GTun9URRoo7NhLrXmzkE7Xqa9Sl15K1ah02EYOf5vzZ4 yCtoRRSNzf3KXPOj57QytjNfKldtYdE8f5l8gTCF2xmN43Z9AhCOoBUy2T5/92lMioeA Izw1Xi/9h+rkNstBATfhHPTDte/4sTDQzD9SUcfLe+nvRnysVZejtXnLP0DoH7H/KUpJ Br98SleZLDxI2PYt6KE0oKatwk6IgDHlQRiCHiUUuMCDl6TyCqwdILnO2FNZKiZXuhj7 AH7vJ7yxzw/ShNaNzXki+VX8tMzYgWxyuwRnQfHaxl0uqBpO1vsduR6teAm4J6PIJiBr H1Sg== X-Gm-Message-State: APf1xPBnJSmenMiby+eNWYgCwIcqyXRLakFnxkyJ9rqgKWNJdXgnsloL 23UUjvGa/52eJZX31ZB/GUh8Uw== X-Received: by 10.28.178.147 with SMTP id b141mr1640027wmf.87.1519211146357; Wed, 21 Feb 2018 03:05:46 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id a14sm9688083wra.27.2018.02.21.03.05.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:36 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 00CDC3E0968; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:10 +0000 Message-Id: <20180221110523.859-11-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 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 Wed Feb 21 11:05: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: 129033 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp506009ljc; Wed, 21 Feb 2018 03:23:09 -0800 (PST) X-Google-Smtp-Source: AH8x227mECXd/6lwz8rXZ5gVAOOv70XTT72t6G5NyYs0uM6IKurXaLLKI1e7Em8j+6RdIULbpPHL X-Received: by 10.129.141.79 with SMTP id w15mr1955158ywj.392.1519212189054; Wed, 21 Feb 2018 03:23:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519212189; cv=none; d=google.com; s=arc-20160816; b=tpPcdDFZ1PvN+AFYc+TUnIEHeKGJe2XkKIP37FR6ovD425pfkfkAiGyRNta+rb8vmZ qxxBBYa5Z9KWcl/E4RLcjLIfLiNKYcP79QFBgPB9+CGfoU+o2odABgbY0cRuX74prvnZ VP+oPbT6ubAGEgYRkO1naDs64Hi55mHMP15+FQ2ec6zT8v4LRm+rgmnfOIZBif9ZewL4 zS47aPOL+Z4UpnBeqmIaD4QhF4hXWwBMfi6trNAofZj582LZF6bzMNqliGvpGkwN7Aqm 5UV347mad8yoMqohUaGRZ5WqbWe9h0ZcVS2/i8bGXn4p8hNUYS0oxdPsJb8nzAE4x6Hr G+IQ== 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=G4I15eP1FC4ba7CHstpPJGkC0lD/nbEYbHzVg9PGUhs=; b=bLynHEje3Yr8QvdCyr77ekuB2uXe8BiwUef1xgVpFLMLL0t2D4f9jiSJHueLGhUKEA NTH+hSIbpH0KR7mNZ/74VHmBNWDewqapRW9DlNs2uzwzhN+x78YnFbIYVzEP2d6xVN6f McVBivbHzfeNiC4zeUqoQGfm1p14CaLAcJkj9Uu4V666PudkfhRTnfc1NruAHeBEdow1 geqUTxfwjcNDUccH7cKzg5IX1mqa1wU4rqbW7ZplBVuGd38kmR5wsGDu/TB8PnuvaHaB 3EhCi7dfynqDmsX/46jvg9QNrpshBe0mC8N5Ppn5+3B52lVo4LFbyB8nn2owRUg8mH5U Ia2Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=LqAQHJ3Y; 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 r188si1657745ywd.462.2018.02.21.03.23.08 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:23:09 -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=LqAQHJ3Y; 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]:60135 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSUO-0000HZ-CM for patch@linaro.org; Wed, 21 Feb 2018 06:23:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37224) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSK0-000134-IJ for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSJz-0002Iw-Ag for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:24 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:45476) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSJz-0002IZ-4I for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:23 -0500 Received: by mail-wr0-x244.google.com with SMTP id p104so3309610wrc.12 for ; Wed, 21 Feb 2018 03:12:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=G4I15eP1FC4ba7CHstpPJGkC0lD/nbEYbHzVg9PGUhs=; b=LqAQHJ3YGbasp4bOhzVtRdzRyqlcUuBcMlykiInJRvwwW2uKzNjpAiqZ1tMbORTqUS Zz4dujBs6nN9gOkfxEab054ZECFgjHk8rfvEsNEdumBZD7qSy8yg48BT26kUT1uc9o8W 7BhK58QhSgSC/ArT2LCJ6T4pmbaBlJksmkoEU= 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=G4I15eP1FC4ba7CHstpPJGkC0lD/nbEYbHzVg9PGUhs=; b=eQ2PPTK/MUoG34/H81h5G7o1oOVQkOZXhWP+Th7raC+ZhB7SKNKrYClsbQNvD8jdQi LOkWjlZe0tUn+RM7O8oTz6qIHBRYLWxpvQrRnVHJUdcQI8xRYYz7s/mcBuGAIXtxYW7d LAA7Qw8OIn8NoesJGxPg//FB6cJjZqnuwawigdnMIwW7HQKuxcnRWfY+CLhynh4mSNM2 3Oj475ah91aOiUKR5giu19JrU/wzlimBC0kANruvVZhm0ejWdiKf6GaJ94Axxm68zQFm kBGMhggHkT6cV/nqW3UbKYLqP7LbEOs1QgZ/xJtZRqDBF7YW2srjMzW9V+toEyS1KT3P RJUw== X-Gm-Message-State: APf1xPBE9ykwo813CIs+AK7OMCGP1R8T89eDPHyUAXSYniCJ/oIzeRSO 1C/5Z27aCPY+BAFwKcYmIEN1Aw== X-Received: by 10.28.46.214 with SMTP id u205mr1901638wmu.136.1519211542063; Wed, 21 Feb 2018 03:12:22 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id c1sm14510664wrf.31.2018.02.21.03.12.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:12:20 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 122973E0980; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:11 +0000 Message-Id: <20180221110523.859-12-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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: Richard Henderson , =?utf-8?q?Alex_Benn?= =?utf-8?b?w6ll?= , 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é -- 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 Wed Feb 21 11:05: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: 129032 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp503951ljc; Wed, 21 Feb 2018 03:20:47 -0800 (PST) X-Google-Smtp-Source: AH8x2259MKxZcIhiBUkcUoCjg9r/e6fh2Z7YgjiWmGzr9Yq5mMTaPgIt5Yy0zjcwynf7wUoVbXNs X-Received: by 2002:a25:dbc9:: with SMTP id g192-v6mr1905450ybf.195.1519212047274; Wed, 21 Feb 2018 03:20:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519212047; cv=none; d=google.com; s=arc-20160816; b=C5uex1lYVRJOdCP/ESNAr4EMlGKQMtQ2DCDzVg4pXxr6LcpLkmhFcDi5hnyJOpmjTO Z6yBgF4q3y1u4hiaHYksBFfZiwnFmYIeviX9j+CXIY4Tn7vkCfQ2VQfxzFIYI8vyNA9C MHqceuT1ox17hAAh8+slvlS/To8Xpc9yqrk6RPe6Lkb8wRifvZw9f0QrMDkcTi2djmeI tONV/HxdlQYKYdSGjQsYssS4wip0VHXdPBR5+9UO+6me8wytaMI1CigT3qrEOkyLW1mn ofPf0JCayc1vwZlBS/IV1fvewLhf7nF9GdBDnjJh/+6MXC9nzN0yMibdO/SF51x4Nan7 90eA== 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=XR8PyRuFoPPXrKMDDk3W6aaN1ZdO641hBWbNiAqNQI0=; b=KgeSv1kKMghrXmS9HiPrB8vRSAXPAKtLh+ccVQlFbXqp8GGaYHMzQgvNsKw1ifaIJ3 EoZeJ0yKZCLwBOLjM9o4weB3xaxBym+5Mmr15W87Q/zBxYxMwWVPaXVluGb2UEfq4Iqb 0K95heAh3EJzguShRo0qzSQOf/CNuxBUL49exkv7ScCxCI/cWInRQBVz+qQjZomflJ/2 sh7pyCxPNTnOaIC82Hpg6zUVFsrEK15br4m+3LETLkFw6q5M2GFe1TvYqkqMUYbkH0Jn 5XeJUKc6R9RgQ5uBlS2O7X7pMfa07ZvWA82DvyBlJDEjf2r+UZbpGgnZVjQyeC1XBR1f 0u8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=XmmJONH1; 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 j2si272323ywj.330.2018.02.21.03.20.46 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:20:47 -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=XmmJONH1; 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]:60115 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSS6-0006jI-Fc for patch@linaro.org; Wed, 21 Feb 2018 06:20:46 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35402) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDe-000422-Fu for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDb-0006ii-Ai for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:50 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:40318) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDa-0006iM-S9 for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:47 -0500 Received: by mail-wr0-x241.google.com with SMTP id o76so3270891wrb.7 for ; Wed, 21 Feb 2018 03:05:46 -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=XR8PyRuFoPPXrKMDDk3W6aaN1ZdO641hBWbNiAqNQI0=; b=XmmJONH1fb1Dk++1UooY+6m0p9hEoDd3fsV5CTk/UA0OcSRE8Clde289q04EPoO1I3 Z9cq9gGsSDaVp04sKKZstM1jEdpwl0jmoZTqIelX/0y9figWEcls3hl9JN9rsK3zpQn+ U1M5sFyBDTiR3gH/sZW9B6ApWPxxE4IhNGCG0= 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=XR8PyRuFoPPXrKMDDk3W6aaN1ZdO641hBWbNiAqNQI0=; b=PfjYAl3MzvE7beY7XXugm3rjN9b8/iIz7uv28XglWiSkLv8SFr+CpJIlGVLHiFWb+O lya01FNCps+a2ZGE7lPbFV9m6naHGVMVBn0TeHlnqKcUPNwKWBMOViiL/CY6/877bg/y AT4toNNQQOU2GVTi8Kpn0ZYXzYeX4ew+zKEhx/pFm+jL6ixzKn9we1oq14bMp7rrCDOw +qxmJWujiMD9cVsbPxjSkp66pbXXaHFcrUCMC74xEiBNRBJuSdbqIY9PNYRXwsE/LgD0 onLhGyvOV2OOgxBDQqlQxAhSZY+to6PFUj+b7SktCU+kt293qaT1P1lNxDbkIpT9+nf+ sPDw== X-Gm-Message-State: APf1xPB89BiNeZ02DQqY/iGywmeoNUjXsfYutta6ewYyVqaJWJDAVREm H2AosQHQeXjaYf5f3lxaw+R9HQ== X-Received: by 10.28.114.8 with SMTP id n8mr1710188wmc.30.1519211145304; Wed, 21 Feb 2018 03:05:45 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 63sm29389269wms.46.2018.02.21.03.05.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:36 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 2661A3E0A37; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:12 +0000 Message-Id: <20180221110523.859-13-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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: Richard Henderson , =?utf-8?q?Alex_Benn?= =?utf-8?b?w6ll?= , 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é -- 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 Wed Feb 21 11:05: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: 129030 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp502528ljc; Wed, 21 Feb 2018 03:18:59 -0800 (PST) X-Google-Smtp-Source: AH8x225kaT3rfCd5vCf5Q18ouXBC0rPUIckHFMwkfSifzXj8MTN3JclcTizl3z7A+ITVWX2YjB21 X-Received: by 10.129.145.6 with SMTP id i6mr1869862ywg.444.1519211939041; Wed, 21 Feb 2018 03:18:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211939; cv=none; d=google.com; s=arc-20160816; b=zIRXjmA5LqEYI97xc83aIfUFzSriKuV4+RWgaIKTbYXeUF6sKVKyvR2IQLp0bvEDUr IXPDxMDnFJZ6xFh/vXIwhOHPZ3dfQgZM4e3+jMw8jSk59NUNq6hKNQ+WyBI9hygibELj kVfaCNzBMaoYxFxzO5/HQ/sHs9HkTdSHI4taSgnHksgkDp6Z45LNDJpQYO2B/ZfU0JW9 GDPskfKd1mPbMvnttU44EY8983dNo2tvjs2SaN7ndZWo1WD/dOnv29bEgavqjZJ9ihLu tm1pu2/EGm3/XCpLVKMthiHJW+fvpSz0oUpzTs6koRMvBUOraN5i3f9tCBjPYGdaP+9q O6bg== 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=yTo3xp1iSRfZojFcGatCU/PuUFM5m+JgD9uPH5DQ4ls=; b=O/0NUzA7eQ/LIVKR+NKwZp48Z32oibhvWbROmiR92jql9TjgFoJ6QcKRuL+kL6wdtz 2K2STdGclY391dD1CnyzmvSUaxINQGqBPoW9HVXzAGDaFxfELTneIbgMsx7JRldnEZNO yIeNr0HeoeyOEmpX+HzvlGzXsz5xQs1cOS2LHOGauOdMXBwzCoyTUmjaLJMurc81ZS/2 JfxKCalmzJ+z9gsCXO+cblos81wGUjZ1FLzpyPHF5RXgTRnwL7t7PUFzgn5O96GEvTGG YvnUSUnHVmApaFclrG5cZkSYrrttNAbczaDV2RWfO/5KziTQPifDvzkUKqiRQ4QMRDay kZWw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=eGou2tZq; 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 m4si3341411ybo.347.2018.02.21.03.18.58 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:18:59 -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=eGou2tZq; 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]:60109 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSQM-00069Y-C3 for patch@linaro.org; Wed, 21 Feb 2018 06:18:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37276) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSK3-00015p-QU for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSK2-0002Kl-7t for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:27 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:44250) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSK1-0002KO-UC for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:26 -0500 Received: by mail-wr0-x241.google.com with SMTP id v65so3313660wrc.11 for ; Wed, 21 Feb 2018 03:12: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=yTo3xp1iSRfZojFcGatCU/PuUFM5m+JgD9uPH5DQ4ls=; b=eGou2tZq2XJ5mHhISgoLPCX8nOzieX+sa0ATGpzgn5QlBBsY9hrKA50VdYZQUIERaK uh22hmpT+wyxLdeoOpINP43Ak+CVvnujZ1DeiYUG0U2nwhuxcEyM39gkzOsuRXvMRylw L6oWoOyaxu26RDHyKDmDwRKmFJ9SUttUpKzMA= 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=yTo3xp1iSRfZojFcGatCU/PuUFM5m+JgD9uPH5DQ4ls=; b=oCoaXEt/p0Uzz7wf0vyrZjURK+A0jsoaVDflzJJL9ZqQgdnsBTi1ldk0fcZCcaIycC ddkEfw5UxUEqyhZ3VeH5/GOstkhUGxtkMyxXPPGGmfREH5syeuTDZ2mIC2C4MUkrX3BI Vt+eG9t/DjbTuHn1GvL/gRS4adL8MhR04VcRUTjERGFyBO99Hy+ir0qf7I4YLqn6RcM8 +iCWp5XLKvn+EdpyrQVkySNQLQGZ6PdAPbd3LDT4IrvvhMfMjEtsExbEquIbtkfqNa5N KtG0NgLcMC5/EyKfFXq2wtw+fuSbUJFau2l4odYezDDZISzBU+pTOmkBbTaFUu9/whsn QjSw== X-Gm-Message-State: APf1xPAJn++hpMnPvVlsLAVmV8a5BIWRoXUSIzfys02jsMGNr42ppzFz frvrvC5DnDEbVs08jGoxZx5UOySOiz4= X-Received: by 10.223.193.69 with SMTP id w5mr2521649wre.42.1519211544835; Wed, 21 Feb 2018 03:12:24 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id e67sm34387157wmd.7.2018.02.21.03.12.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:12:20 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 38FAD3E0B56; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:13 +0000 Message-Id: <20180221110523.859-14-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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: Richard Henderson , =?utf-8?q?Alex_Benn?= =?utf-8?b?w6ll?= , 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 Reviewed-by: Peter Maydell -- 2.15.1 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 Wed Feb 21 11:05: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: 129035 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp508637ljc; Wed, 21 Feb 2018 03:26:18 -0800 (PST) X-Google-Smtp-Source: AH8x225EorWrwTbm1vjq5ktF8FOSPAUqOaDvU5mIidC86/XtQUIxlgaQQANxnrKWoNQ9Zk3/XMdL X-Received: by 2002:a25:7bc7:: with SMTP id w190-v6mr1747821ybc.200.1519212378773; Wed, 21 Feb 2018 03:26:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519212378; cv=none; d=google.com; s=arc-20160816; b=Hp+2ug3MS/EaX8vR0s/gfPCOD7j9xWE8hVpviUIz9nSmgx4v+PgmZnR3fRiEwatt+6 IoRsvyn/ruBwm/AmA+jVrUnmGHjSnT6eIOIKO6NlRg7uW2CQtZTy0JKXqf2IEJdV5WbU WnmPPH1jxo7RcqZnxyOw3h/0qcNXQ9nJNOpp97MG5I7Lb+C4rGLAKjxYUhpiEA7pC4xO ObL8JCGCvyRROJqOBzLsaAaDVCIcXnX94h+0lNRaIjPMVlDIyTh9Gm6GzazosCcT38MM o1iS6BnTeA8ZVmnXstktKvnShwh/u97fxK08Fj70r30ulpBLwrOPu3pirg6CBA0iA695 xdsw== 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=gM/al23tPkdxb/c6upmoSwalu/TcJGrrzTPyrJRa3e4=; b=HFAMZE1vGJPRCHTuwU956EgfoZAzoxLSWRxs6fZ/wuYDL1y5QbpDdYlSmUa8DB/qX0 rSOqAuCL8cwhREQq6vtJ3XuLhiVLJwqscpVAzttfTYXudYKMcD/DkPff6VffPFEVAImb NKa6GGWOFDLBrBQ7dus3taHia8PXol++eALRrmQ7MZRo8Te7hT3+yDAAc3SYpiphiVwN 5IzeGzLO+kYDEAwgZ+Ed2oOFCRk/qCNwPSZ2ZNn7hHUpg6LRTIIR/ChEUDw8S0a/GWW1 w8JaIf02Xc45dMNfao1wuh5MtgKtR9LEr0JY+5BhQ5WkrFbgM34Y6+RNYRdH79yuttwF koMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=cJxzG4iv; 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 w2si1742355ybw.734.2018.02.21.03.26.18 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:26: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=cJxzG4iv; 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]:60158 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSXS-0003P0-5J for patch@linaro.org; Wed, 21 Feb 2018 06:26:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37258) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSK2-00014w-Lb for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSK0-0002Jd-F7 for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:26 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:33337) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSK0-0002JE-3l for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:24 -0500 Received: by mail-wr0-x241.google.com with SMTP id s5so3360329wra.0 for ; Wed, 21 Feb 2018 03:12: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=gM/al23tPkdxb/c6upmoSwalu/TcJGrrzTPyrJRa3e4=; b=cJxzG4ivl98/oip/Bh48YE/bFcPsjkCMnosPzkP45npJ0cir2lpV9PeHKyyATwhdam mdPMHE3NkWs/j3OonE/ff0Kp7nV1qLVJGBBT19q0ugOdFDqS71MrgMQCrcU/3/Sb14H8 FEISHechk+/TIuiF4w5lw0fhIuLtRU6m/ekg4= 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=gM/al23tPkdxb/c6upmoSwalu/TcJGrrzTPyrJRa3e4=; b=XIgy1pPj7ZszHAR0mx21/37XBw/CY4fyWgeCX1tN1hc0XO8RtlhKkZmDJ2QUUcfl7J TCzMBvVnh6UWr4c0dcifAvnNBrKKaqT6diRTGp31qI5wrHxFC0uRFxSeqmkCn8cWlx0O RNbmwBeZVYFzU60NmLaYO+NYfULzzCwtsWdt3cW4aZHxSpl+s+MQ3M8B8bsFSOemV2XC 9qOtH8wQTIjOm10rlSYmLnihM3rUMtolno7aF+SjrJ59JrXaal7nd0nSkbdiFdDhssua idfypfi3c8fJdAv3sukjFiV7mZN/soBHOjLG8QNLjGjNo5ZMZAnri46Nanq23DaCQYYW qo6w== X-Gm-Message-State: APf1xPBPBXUphMzUzEl7IlI8OFl5/eZN242sctBxBEWiePISWxjtAzxV 7O4KmdBhdmf9OI6bDuXClRHBew== X-Received: by 10.223.134.42 with SMTP id 39mr2754946wrv.10.1519211542816; Wed, 21 Feb 2018 03:12:22 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id i33sm26345693wri.70.2018.02.21.03.12.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:12:20 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 4CCDB3E0BFD; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:14 +0000 Message-Id: <20180221110523.859-15-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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: Richard Henderson , =?utf-8?q?Alex_Benn?= =?utf-8?b?w6ll?= , 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 Reviewed-by: Peter Maydell -- 2.15.1 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 Wed Feb 21 11:05: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: 129039 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp511031ljc; Wed, 21 Feb 2018 03:29:16 -0800 (PST) X-Google-Smtp-Source: AH8x224+YcoBHxa1C9dx9k5bd41/oc1x7PJJ7WS7oLb7Nda8YA77/o2OqGRTm+mUZmXoWGUxvm/J X-Received: by 10.129.120.203 with SMTP id t194mr1849675ywc.383.1519212556277; Wed, 21 Feb 2018 03:29:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519212556; cv=none; d=google.com; s=arc-20160816; b=Y+bvUIk/I7ePPuEDfbHkvrDVDsFBWHFlsgrwkabxzN+P1/2ADNoCuLZf0i5tR27HI4 cBjnPhsFJ7Y+cAafkMWNBA0q4FG67L8wDvIWHd6vKP0MoM2oKIdcdxYd0LXLlANFlGVH Rv4Q68ApPJ3sTZ+FE+JyJ1JvNqxKzcZSwQkPhWj1Xccrz1AbtkyarymJNgzKC8hbo303 qG/kY5JylkG+ulcSi4womI8qZ/PqbkGbzfVhSAUfD0UqwbR7oqqM+WEzyr1KvmWJ4Hnp P9eh5LOTSDc9wewUhgSdT3Hs5fxv6jSkLqYotjQrvmxprtiQrK4YvMvev7rhE5vS2g0N Wvag== 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=5lyaK0m/hAte1HB+3Wo1zN+DkN9bIuEXM+2JNUX+esU=; b=JsEjMQrgwtUGHClkFnwl/vo/BQXVfjQ8ppu1WHB8Xs6E4JYSLky/sVN1WKtdHNlONc VTtmdlKZKZ2Wl6kRrs3ODrwmRrNH6R+WSZLN+/HOcpJuIBzH7M2orsZBEnxoOZvkjaap wT9GoOIKS9fSWgrpp03r75H7YiAfu3NI585vX/B9feqvRNnq2jFbl6uG1CJ8w6hwj2oB JRMP8vFzzUTNjTi0cy7h3KrXMs9cmZUI3pYmnSHZlBL4ZBB1N6vwL15WX8BOzJCtEMm2 /N2D+rXtDHCkxdpqNfksd2gi2QsRc461D7voOEvPB26kqz3p7tjp6t6C6i0N8fzmqrcJ +Zqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=NBDiWGBy; 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 q11si4959544ybf.827.2018.02.21.03.29.16 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:29: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=NBDiWGBy; 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]:60181 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSaJ-0005k2-Ic for patch@linaro.org; Wed, 21 Feb 2018 06:29:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37313) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSK5-00015z-La for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSK2-0002Kb-10 for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:29 -0500 Received: from mail-wr0-x235.google.com ([2a00:1450:400c:c0c::235]:35782) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSK1-0002Jz-Jh for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:25 -0500 Received: by mail-wr0-x235.google.com with SMTP id l43so3347089wrc.2 for ; Wed, 21 Feb 2018 03:12: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=5lyaK0m/hAte1HB+3Wo1zN+DkN9bIuEXM+2JNUX+esU=; b=NBDiWGByyVbKbeZyhClk4ps2m4TDwLzPnzX/nG/G3LxLOY/oPcNUOFCusjXgkSUh0f +lXeSY5dN32XuMjHOAyPxIceEZGWmlV2fC4Rl6vH9Azd6ehVwqgZJMBmxcTpvyK9LzFI 6TQ9Uf/Vam2JrYGrd0VJmGReppIjB/dKdpyak= 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=5lyaK0m/hAte1HB+3Wo1zN+DkN9bIuEXM+2JNUX+esU=; b=j7z/TQD+k4b+S9xcf9B+sFJ4LMcXHzhYFeZqJ02sZ1b2Qf+Tis6W346Q1+4jsL4/u/ mGkS9TB3OkW717cDbQZWUSNE3ESjd2zu2gFdzSRT9yLwNX9KWbh0UhmPpabi94tvUbdY 40Hy8LTqZ++qRZOS7YPZP445MZ4Vf9nMv4+gNul6nWsY4jp256dGv02cDKasBqYQ+puj 1omSv0AQ9mowRTtcHMVIB7xfjlP67oAHgG56pzHlYnEsh7/cainRmKoqz5smsZxNV9aN uDWHFSyNKQTraaUyFaxofCLNh3y3Q80tQ1l0h0MpFQJosHmRYZ2zc7rZ+nWQD/dn4PLs TUQQ== X-Gm-Message-State: APf1xPB4wYuUj5ZkQl/Ec99FTuJlEkUTe2OF5Bza5/YcTK8MTUfK5hPT CW2KsRZlgf+2OX4yAGUU8faudU9FScs= X-Received: by 10.28.125.150 with SMTP id y144mr1709881wmc.75.1519211543882; Wed, 21 Feb 2018 03:12:23 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id i6sm27705003wrc.46.2018.02.21.03.12.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:12:20 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 625DA3E0C29; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:15 +0000 Message-Id: <20180221110523.859-16-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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::235 Subject: [Qemu-devel] [PULL 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: Richard Henderson , =?utf-8?q?Alex_Benn?= =?utf-8?b?w6ll?= , 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 Reviewed-by: Peter Maydell -- 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 Wed Feb 21 11:05:16 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: 129028 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp500240ljc; Wed, 21 Feb 2018 03:16:27 -0800 (PST) X-Google-Smtp-Source: AH8x225yYCx2NMxW9LWFIrv3AFSLJ+uvfF1lyFJSXQVqqzu52Xi+lKhsCZoByYFTJux0PgV7vMBd X-Received: by 10.13.204.135 with SMTP id o129mr1864517ywd.101.1519211786866; Wed, 21 Feb 2018 03:16:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211786; cv=none; d=google.com; s=arc-20160816; b=CR+rEB3uwkX+iqWCbBp7zc84WYTahdP5wrWHJr8gu1wKabxwdUV8FUOojvblyQFqLh GQ1r1lR2zWPxpnajjCaGSL9sHoj5r3Mn+MjXh2V0lwljDHryM6Ni2exNu/+/Nny4/5cF XOpUJinetBrRRL8+EKmbIOVge7gv5AagCcQIxvb3t8XstJkbm21yc10NP5uZiRj2NsIT Q9AldwwCt99fHQhdYkMGdOugc1q0XgwTlcFe4+9Dg/3FWWCdR/aIipeqqEDxTN2CeKat TBPQajoWdyCXRRvXQ7FSv4FBktsUbJHUf57KF+vfB84cdFxD7w/KMf38ToZLFEtow4xe lr1Q== 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=q3RcF3MqDRbQQVMiUjWqZrPO5esp3ArczjXvT/Q/fMs=; b=ZUkBBHb6U/V+pWpX76jSYtXkVWAMHhyH1zBNo+n6IzpwzQL71j5IQzksiogVhlCkCj gM88csh54nsUvyWcC9mK7MKU/zAKL+0cSPUPTvPpojPkinfUR7w8xA+fexSQ0i+bgkRI Ze+4aqgHV1gKYNhoB50IDTZEegRe46JxDnuMT9Ra7X30+R2i8zXwfV2bxpjNNPSMfR3G dGUn2gIxxQWw9eenZL4k8YjwLM7wTndZRtZ1eop6o6gP0x0Miq4AmQY2AMYaroWbX7GZ gIrehIRpryNc0E5LbuUgXXY1AbUy3YQmaK9EdxRfSnTPWpfZRILWxS+hwrUNmjNEnb2j pYzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=FY4JdMn+; 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 b5si209861ybi.50.2018.02.21.03.16.26 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:16:26 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=FY4JdMn+; 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]:60098 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSNu-0004E3-4e for patch@linaro.org; Wed, 21 Feb 2018 06:16:26 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35419) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDg-000443-5z for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDe-0006lF-EZ for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:52 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:41252) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDe-0006kk-4o for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:50 -0500 Received: by mail-wr0-x241.google.com with SMTP id f14so3266187wre.8 for ; Wed, 21 Feb 2018 03:05:50 -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=q3RcF3MqDRbQQVMiUjWqZrPO5esp3ArczjXvT/Q/fMs=; b=FY4JdMn+Fr+cJjZi32kDNgolcJ3hKhnRGlXCJ91I9IB3BrCUYTgHMfu6wX1t111p1f ag5D9csiux8yPJkiPG5KHraUUPlFMgSsqGXyr714TqmQLj+h1rM9He7GpNdQZHIEeqLr G7wUn39oe+FI7UQZb4zBk+3fdEHhdzx/WXFcU= 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=q3RcF3MqDRbQQVMiUjWqZrPO5esp3ArczjXvT/Q/fMs=; b=rCrR6HvD6SztlViZt74qduJByE9Uuse7BXK17w/xofcLI15aPOoRDmw43hWmhi+XgO ckpn8heBjmwIUvfbrs8DXtB6FfYeZt2vMxwGT40TO3bqh0CAY0tya1dshOKs+OVsBflH k8t3qtjzTQ+w0cuJl68blttyMrwaRc/l+Oq9DzdyPsreIKkZ9tDB/6x7ywGxAPIFh+BU KPvSDt7FNsuGJzw0WWFsC5ZXQymxySv0pWr/TolJ1blLU3Pls0X+wj0LQk0SmBVYx0zR xHuX/jKnXb633WHIIHWk0HQiFgkUA4ysNrJ5KzsbkUvmOwa1+k3q9617gCH3L7QJlIHX CQGw== X-Gm-Message-State: APf1xPAoXHb/CJhkkh72Z2WCyNDzDyWOQaxPgXMylnv6VfL0Yk7vVkPO xLCpGXgAvCSJKqpGKlcjLQWs1w== X-Received: by 10.223.176.33 with SMTP id f30mr2690884wra.75.1519211148943; Wed, 21 Feb 2018 03:05:48 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id z73sm26359882wmc.3.2018.02.21.03.05.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:40 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 75A6E3E0C5D; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:16 +0000 Message-Id: <20180221110523.859-17-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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: Richard Henderson , =?utf-8?q?Alex_Benn?= =?utf-8?b?w6ll?= , 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 Reviewed-by: Peter Maydell -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index ae4ba6de51..616c6cef07 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -560,6 +560,25 @@ static bool is_qnan(FloatClass c) return c == float_class_qnan; } +static 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; + /* fall through */ + case float_class_qnan: + if (s->default_nan_mode) { + a.cls = float_class_dnan; + } + break; + + default: + g_assert_not_reached(); + } + return a; +} + static FloatParts pick_nan(FloatParts a, FloatParts b, float_status *s) { if (is_snan(a.cls) || is_snan(b.cls)) { @@ -1175,6 +1194,132 @@ 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 = DECOMPOSED_IMPLICIT_BIT >> a.exp; + uint64_t frac_lsbm1 = frac_lsb >> 1; + uint64_t rnd_even_mask = (frac_lsb - 1) | frac_lsb; + uint64_t rnd_mask = rnd_even_mask >> 1; + uint64_t inc; + + switch (rounding_mode) { + case float_round_nearest_even: + inc = ((a.frac & rnd_even_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 : rnd_mask; + break; + case float_round_down: + inc = a.sign ? rnd_mask : 0; + break; + default: + g_assert_not_reached(); + } + + if (a.frac & rnd_mask) { + s->float_exception_flags |= float_flag_inexact; + a.frac += inc; + a.frac &= ~rnd_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 +3050,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 +4193,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 Wed Feb 21 11:05:17 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: 129036 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp509017ljc; Wed, 21 Feb 2018 03:26:46 -0800 (PST) X-Google-Smtp-Source: AH8x226Fiem22LJInxIAQoXV5Gwt4+rRxonz+jzkqSH8ZoEZVa9T7KGSlBQGojIVIONh4zHIijIM X-Received: by 10.129.104.195 with SMTP id d186mr1885805ywc.287.1519212406596; Wed, 21 Feb 2018 03:26:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519212406; cv=none; d=google.com; s=arc-20160816; b=wSmAu46IvIyMiBMagtzioll6n/zvlZ3KlUNqyR6hHhWas8IQItrTvTxOLF7RfpLH/R TwlOKrMTylAyPrHOgolxjLwaSSTtVqczMIpNh9NBqUZ3oh4eYEduzjfKcyVJon8KLGjh CR77jKhWo820+X7X2ADLLQ2X5s95BqUknWU2922+VYH2LcVRgAVw6Q+7/YP6/db1oxth KWT1OVb9jVb1jaSUD+c0F8+YFsLTqkKW0BgH0ff97NZ7I3U7YlRypuReXKfwdMyECV2f Fy2leBX48Z6QW3u3u055/xvTQMTZ77aoRMQIRQh0hUimnYROnTNTKxW1xbGSWarElh3f ue8w== 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=Wqal+JwJ+xlOc4HG2RHFEUOZVmfVy8Hkoc4KIhxN2gw=; b=iEaR1RUcJEUobX26D6YuUrRzoZqQ1q2m7U317P4m54yhr3wKwSxLFqbgz0hJ/ceiyh DAJ2m1aKEzE3NqYHRDMqUbIRu18ab+dvA6OBCqj+wD91iW5+++KtFs6CHqpkkcv5PM1l 2MLopOdAz6ZWvmRmVycXUifnCORq1hSv0m+14EXR2Xg0a1dNxTgEl4Q76kNMVjr8Yimu mAez+iWKp8laj4/A7IRwCboIMPkvuQcLLH6pLJReONTFk5RxmNeD71ntVheo/hvHvpcq /KbgwP8CDaSuKJ3bo62H6RnfKCFQjVWNERjE/hsR/Q2jEp+sFmmbhQaT1O1dZYoSR7K/ ESvQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Db9wYzA+; 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 o15si290989ybm.11.2018.02.21.03.26.46 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:26:46 -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=Db9wYzA+; 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]:60169 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSXt-0004PM-Td for patch@linaro.org; Wed, 21 Feb 2018 06:26:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37264) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSK3-00015M-5x for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSJz-0002J8-EH for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:27 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:41377) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSJz-0002IO-0n for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:23 -0500 Received: by mail-wr0-x243.google.com with SMTP id f14so3321752wre.8 for ; Wed, 21 Feb 2018 03:12: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=Wqal+JwJ+xlOc4HG2RHFEUOZVmfVy8Hkoc4KIhxN2gw=; b=Db9wYzA+/qN57okxGGffh3wgXhXoDl4iImP4Og8WOaCjysoM0DRQK21Ke8P4YYW0sA uU/bq7FS5IeAJ5nsfnKYbcHz67+WKWJFhnx1N6MMsgsMa0ybpf+DFoqUacdK0MyAwrl7 qJEyjC/d3LpIXOuxkZUbaFfrxmO8ZFlBp9ywE= 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=Wqal+JwJ+xlOc4HG2RHFEUOZVmfVy8Hkoc4KIhxN2gw=; b=TefdGPObkNu4OThzQJvn7mPhZNF6GCTu9DYgnz4A6tfPOtYDFdxkQDNbOuGkxf7kaD OSaCnlGSgTh8dDhMq+S265r1ZyGcLRARKtxmcucZ9w8Qjz7GdZosQsgYEI1zAuiKnuyY N9qqq1C/dH0TrsGJ3cEK3h/i8zFJxHoa9grkOsBxEXGpBtU62nB/TTZ2dUCpchMoCTQ7 V18SVJzQ9GTErdnPWYh0nj1MJJoODpZAt27YsnP+mAEE9jlvaGpvAJ+Cj5GD3pmZxxGn lOhj100etoS8btZRabV6SAiIIUlFhsDXFQrojEsn516zX2pTko7W06Gi0I35Jou5rwxA CyCA== X-Gm-Message-State: APf1xPALhiOcDppc4cDpT5MWkrQrKdbJc0/PlK35TIhssWU12QFJrmts KghU9zsilPaOUO3HIIsFQ8fC9JiF6NQ= X-Received: by 10.28.36.136 with SMTP id k130mr1867113wmk.124.1519211541302; Wed, 21 Feb 2018 03:12:21 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id s9sm27230522wra.4.2018.02.21.03.12.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:12:20 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 88F423E0C74; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:17 +0000 Message-Id: <20180221110523.859-18-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 616c6cef07..da0c43c0e7 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1320,6 +1320,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 @@ -2671,288 +2851,8 @@ float128 uint64_to_float128(uint64_t a, float_status *status) return normalizeRoundAndPackFloat128(0, 0x406E, a, 0, status); } -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32_t float32_to_int32(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64; - - a = float32_squash_input_denormal(a, status); - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( ( aExp == 0xFF ) && aSig ) aSign = 0; - if ( aExp ) aSig |= 0x00800000; - shiftCount = 0xAF - aExp; - aSig64 = aSig; - aSig64 <<= 32; - if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64 ); - return roundAndPackInt32(aSign, aSig64, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ -int32_t float32_to_int32_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - int32_t z; - a = float32_squash_input_denormal(a, status); - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0x9E; - if ( 0 <= shiftCount ) { - if ( float32_val(a) != 0xCF000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; - } - return (int32_t) 0x80000000; - } - else if ( aExp <= 0x7E ) { - if (aExp | aSig) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - aSig = ( aSig | 0x00800000 )<<8; - z = aSig>>( - shiftCount ); - if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { - status->float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 16-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int16_t float32_to_int16_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - int32_t z; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0x8E; - if ( 0 <= shiftCount ) { - if ( float32_val(a) != 0xC7000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return 0x7FFF; - } - } - return (int32_t) 0xffff8000; - } - else if ( aExp <= 0x7E ) { - if ( aExp | aSig ) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - shiftCount -= 0x10; - aSig = ( aSig | 0x00800000 )<<8; - z = aSig>>( - shiftCount ); - if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { - status->float_exception_flags |= float_flag_inexact; - } - if ( aSign ) { - z = - z; - } - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int64_t float32_to_int64(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64, aSigExtra; - a = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = 0xBE - aExp; - if ( shiftCount < 0 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - if ( aExp ) aSig |= 0x00800000; - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); - return roundAndPackInt64(aSign, aSig64, aSigExtra, status); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| unsigned integer is returned. Otherwise, if the conversion overflows, the -| largest unsigned integer is returned. If the 'a' is negative, the result -| is rounded and zero is returned; values that do not round to zero will -| raise the inexact exception flag. -*----------------------------------------------------------------------------*/ - -uint64_t float32_to_uint64(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64, aSigExtra; - a = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac(a); - aExp = extractFloat32Exp(a); - aSign = extractFloat32Sign(a); - if ((aSign) && (aExp > 126)) { - float_raise(float_flag_invalid, status); - if (float32_is_any_nan(a)) { - return LIT64(0xFFFFFFFFFFFFFFFF); - } else { - return 0; - } - } - shiftCount = 0xBE - aExp; - if (aExp) { - aSig |= 0x00800000; - } - if (shiftCount < 0) { - float_raise(float_flag_invalid, status); - return LIT64(0xFFFFFFFFFFFFFFFF); - } - - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra); - return roundAndPackUint64(aSign, aSig64, aSigExtra, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit unsigned integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest unsigned integer is returned. Otherwise, if the -| conversion overflows, the largest unsigned integer is returned. If the -| 'a' is negative, the result is rounded and zero is returned; values that do -| not round to zero will raise the inexact flag. -*----------------------------------------------------------------------------*/ - -uint64_t float32_to_uint64_round_to_zero(float32 a, float_status *status) -{ - signed char current_rounding_mode = status->float_rounding_mode; - set_float_rounding_mode(float_round_to_zero, status); - int64_t v = float32_to_uint64(a, status); - set_float_rounding_mode(current_rounding_mode, status); - return v; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest positive integer is returned. Otherwise, if the -| conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int64_t float32_to_int64_round_to_zero(float32 a, float_status *status) -{ - flag aSign; - int aExp; - int shiftCount; - uint32_t aSig; - uint64_t aSig64; - int64_t z; - a = float32_squash_input_denormal(a, status); - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0xBE; - if ( 0 <= shiftCount ) { - if ( float32_val(a) != 0xDF000000 ) { - float_raise(float_flag_invalid, status); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (int64_t) LIT64( 0x8000000000000000 ); - } - else if ( aExp <= 0x7E ) { - if (aExp | aSig) { - status->float_exception_flags |= float_flag_inexact; - } - return 0; - } - aSig64 = aSig | 0x00800000; - aSig64 <<= 40; - z = aSig64>>( - shiftCount ); - if ( (uint64_t) ( aSig64<<( shiftCount & 63 ) ) ) { - status->float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} /*---------------------------------------------------------------------------- | Returns the result of converting the single-precision floating-point value @@ -3558,236 +3458,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 @@ -7055,252 +6725,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 Wed Feb 21 11:05:18 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: 129038 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp510974ljc; Wed, 21 Feb 2018 03:29:12 -0800 (PST) X-Google-Smtp-Source: AH8x225cHj/6uXMXMv59+wlBL4OZXFr4XbkcRWy/viBc6a8niKyyVWUnJXQQ7wt70SCeEzekdbiB X-Received: by 2002:a25:b685:: with SMTP id s5-v6mr1964351ybj.10.1519212552329; Wed, 21 Feb 2018 03:29:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519212552; cv=none; d=google.com; s=arc-20160816; b=UJBsTKMfgFjhoMtx+k/RFTdeseVBy5HJKG7tove6rPaLb0YWoVPWTO+yhTIkBadQWQ /KlJHJCksmRHEpy6RbWJxvDXRKIt13o7QM+JQ6Y+r0WRnn5MJvFxcgsihC/2VOek9JBa fQOi2yD/B4cO9Jw6NIZ3ExNBSAws8nidmVP6f8Mh86/fgHVP7hTai4YaBa0TRE6QZ5I7 w9JgN9LzvahT9nedLEemLIKSEpSyXDehDlDh0No2eFu7oLQnkeaySmvFpdIVm7dfNq4n trVwICFgNlMbBhOiLL0gwhE0ORFJU7/iOBybmRQZhfEzt9vxWzOCjFyK67ru3sITXe+q WjAg== 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=ofw+612EJnycmLoqeGzrS8VE5fPUOvxMqCWpPPVENsQ=; b=s+xEuV9ZwN0x5QdEp+wpzI8CFjk8Sf51YXoBU7u0QgtKwgbz0uu/1nQ9F8fiwaEZ71 129cT95935T1Jp5D9YHf7qJaXuG6L7GPq47gESzd7Xut3by42/bEg5NbdIjFpShWpG8v M7hbYzn07sSJ2+xvIvSh6NF2JAZ+AzTiiRt9xbcuPjZAjF9I94fMy6JYYV+oVNm4Ro+N 6SVM5/ANzfykPzmd8H12yL8EYZG8lTkad5RjHHASQZBW7Hyoff+FQLXwFiX5ds8m6q1N Il7NrtVvD/agXN8datMuZcJ+8aGg6GA/1WC9K7Suo8MzznJOTddlL4YSzmwh64IYPWp4 KwVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=gYQTJPRp; 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 d190si4681105ywe.175.2018.02.21.03.29.12 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:29:12 -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=gYQTJPRp; 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]:60183 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSaF-0006I5-Mt for patch@linaro.org; Wed, 21 Feb 2018 06:29:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37339) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSK7-00017p-AW for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSK4-0002MM-Qz for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:31 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:38265) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSK4-0002Lj-Fd for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:28 -0500 Received: by mail-wr0-x242.google.com with SMTP id n7so3344979wrn.5 for ; Wed, 21 Feb 2018 03:12: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=ofw+612EJnycmLoqeGzrS8VE5fPUOvxMqCWpPPVENsQ=; b=gYQTJPRpu6jxhWDMAigO5MWa4Vh3miWWgBR7UDypqc2GMGcYZEGoyWXtiGoG80/wtn jRhl3lnDaDz/LzoSyIkTqfdsBMvyQgKnn49yPm7uth9Q7R6pQbYmhpCJnEYF5j7XMRWD zETwO9dB2U8Xu5ggrsP2Q+iyCenWYS6UQWRl4= 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=ofw+612EJnycmLoqeGzrS8VE5fPUOvxMqCWpPPVENsQ=; b=NR3g8e3M5icmXlQCCrpnyk7HP3199dM+UKQ90t8eZ+vRcdhbPwcqrkCewRv1rOThwZ oCGCTl2i7G2GFN2H/5lmVLI6zFmwpeuFSEC2GWlO10wdeorFasTHtKdgGq/5p1az3ofV qbDNTtpHhqhQqrHfdMcIL8aIXR97owfK2168xmRT6cnxdjyALbhTiBBtZ5iFFC6Kuqyy ZyGvst4FZlCBhuqVbvljA9PhZYE4iM320FaYabtK7X051K3bP0Z3YU+7pvxROCopGate xDfMwv8XMVdXaDsh6QQVWYO8E1pldK2YcBO419gX+IvFFi9Ps+/dH7VgsmD4NacfmNHJ aO/w== X-Gm-Message-State: APf1xPDx1GTHnqAKliy4nN6Es4f+7gLr2t+SgHeEyzpJHeVeAUmWs7j1 cSc9MlrblrpRF/xanky6nBu1sHxuz/E= X-Received: by 10.28.43.66 with SMTP id r63mr1713877wmr.30.1519211547307; Wed, 21 Feb 2018 03:12:27 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id m55sm5238275wrf.38.2018.02.21.03.12.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:12:24 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 9B9A23E0CC8; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:18 +0000 Message-Id: <20180221110523.859-19-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index da0c43c0e7..4313d3a602 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1500,6 +1500,169 @@ FLOAT_TO_UINT(64, 64) #undef FLOAT_TO_UINT +/* + * Integer to float conversions + * + * Returns the result of converting the two's complement integer `a' + * to the floating-point format. The conversion is performed according + * to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. + */ + +static 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 @@ -2591,43 +2754,6 @@ static float128 normalizeRoundAndPackFloat128(flag zSign, int32_t zExp, } -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the single-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 int32_to_float32(int32_t a, float_status *status) -{ - flag zSign; - - if ( a == 0 ) return float32_zero; - if ( a == (int32_t) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); - zSign = ( a < 0 ); - return normalizeRoundAndPackFloat32(zSign, 0x9C, zSign ? -a : a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the double-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 int32_to_float64(int32_t a, float_status *status) -{ - flag zSign; - uint32_t absA; - int8_t shiftCount; - uint64_t zSig; - - if ( a == 0 ) return float64_zero; - zSign = ( a < 0 ); - absA = zSign ? - a : a; - shiftCount = countLeadingZeros32( absA ) + 21; - zSig = absA; - return packFloat64( zSign, 0x432 - shiftCount, zSig<= 0) { - return packFloat32(0, 0x95 - shiftcount, a << shiftcount); - } - /* Otherwise we need to do a round-and-pack. roundAndPackFloat32() - * expects the binary point between bits 30 and 29, hence the + 7. - */ - shiftcount += 7; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<= shiftcount; - } - - return roundAndPackFloat32(0, 0x9c - shiftcount, a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 64-bit unsigned integer `a' -| to the double-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 uint64_to_float64(uint64_t a, float_status *status) -{ - int exp = 0x43C; - int shiftcount; - - if (a == 0) { - return float64_zero; - } - - shiftcount = countLeadingZeros64(a) - 1; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<= shiftcount; - } - return roundAndPackFloat64(0, exp - shiftcount, a, status); -} - /*---------------------------------------------------------------------------- | Returns the result of converting the 64-bit unsigned integer `a' | to the quadruple-precision floating-point format. The conversion is performed @@ -6714,19 +6731,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 Wed Feb 21 11:05:19 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: 129026 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp497406ljc; Wed, 21 Feb 2018 03:13:31 -0800 (PST) X-Google-Smtp-Source: AH8x22555NYTz9r3vE86XkNhOMCms5C7KGZikMupA7ICp/INYWgg267FPMZgOwWX4r5KFMj+l5qy X-Received: by 2002:a25:65c4:: with SMTP id z187-v6mr1979290ybb.270.1519211611401; Wed, 21 Feb 2018 03:13:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211611; cv=none; d=google.com; s=arc-20160816; b=JVTfj0X4GPOCws8v0vi+0Ttn4tWfySU0+bsEC6tmOQnwkQW0yDop7bfHGZKA2dNKfe XuEUwUeWXg9yc/vj1co2Wuy9/UmCC9OUPw1gvq3pdxCQIox4O3qjQcvXrajKns7FnnQm QfV4+kgnqIsrQtSWrFV8VY2lscNXNlWlfaGCiMGH+o1yNGa7yNqhpruSZz8L6i7byFHq Qe/uVDzn30d8nfWmj1AjXUnXatpTRIZYwxkK10O8tbR+AIUTNoa4Q4PSXVrwbBsZvn2G hiQgJ86woQrO8K/Ads+0oz3BaWbMbkuw6T4z4cqdEy6kz5EQ0yHJVLnPQ5ujzG3G6czC 3qrg== 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=iQKLE+gYstVMNpyf46wR6ckSx7XPdTfzR3aJa3Ouhi4=; b=fNW2upLNRyPSUMqGUsvLaFcVtWOzagUao1zEQFlQG2MrpGoU0q9dD1a/memSYgBzUY 2hgx2uVGy5XIyfAPZAgv3LxS/070FMe1bGMzLfvMtbhjbv+VNHJ10t0OQbT9G4XFnS5V kCPt+/2AZ6DXZOycHGtLSzZgbANX3KBB8GdIsxW96N512ELnCsqRvxY/IIj78rTAgrZt cikqG3o5d68IefVT1CN7uXco2njErm2KWlLx3tf0GP9u9MWJhFLe2QFA7QCMzZZgElQX y4V9/13khchpgN1W/nnNh+t07lSROqMg5EnDxF8qk2ZrvM4J4jhSmKjo48CEbfLiavuQ TfVg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=JG4k+i9y; 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 x188si3767704ywf.271.2018.02.21.03.13.31 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:13:31 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=JG4k+i9y; 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]:60079 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSL4-0001bj-K6 for patch@linaro.org; Wed, 21 Feb 2018 06:13:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35399) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDe-000420-Ew for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDd-0006ka-By for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:50 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:34347) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDd-0006k7-4y for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:49 -0500 Received: by mail-wr0-x242.google.com with SMTP id m5so3302538wrg.1 for ; Wed, 21 Feb 2018 03:05:49 -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=iQKLE+gYstVMNpyf46wR6ckSx7XPdTfzR3aJa3Ouhi4=; b=JG4k+i9yVU+7Ib2CquIMcUKomZc0jfH2QcOOcyDVvEWrq155/uNpNPkl957YrkobzD PafIsI4uvqcrCi8FYaB+PqODAKslxBUm3/1s+COnMb8PV1ZXLMkeGkNp3MOXe33l5uig mR7O1vz21QPE4LBm8EIzFhvIQB3YwpgN8eJSM= 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=iQKLE+gYstVMNpyf46wR6ckSx7XPdTfzR3aJa3Ouhi4=; b=Kcq5Yd26dNHjdb266hBGTCnyUmA8RtHI4H7tXXi2A+2eeDw1TwFgXFgLf754qGwFqO lAf2XQ9D5afUeSu3ezyd93yDb03VYh5TxVU/zvr22PYPjY8Tj2M4VrouPnDj1b8EMJpg Cj/hBgrQkuvhHqSXsTBnxZI+a6eJ0OPO95iLLG2JEO26JL1ICYyOB1lR5DLkL2UwOuLC miCGDQTqzXLq6lWRC8odEHgemW1fmph8hvOtUKwXwiW3tFGLDK88d/AOXboByJj8Aiot UJdcEkir2Fxm6r4siVd29cRdHUbao59YSIQMHYxekrgiQ7cUOisd0uW8nFkJQdEhPz5R f1cA== X-Gm-Message-State: APf1xPAlCnz8AcyJnQNVauVp+SFC5qkR54Lss708iIPWGx+1kCQxJu3y 0hhgbU96c4uxkOnnqnOJ1KmOJw== X-Received: by 10.223.147.198 with SMTP id 64mr2735660wrp.250.1519211148041; Wed, 21 Feb 2018 03:05:48 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id s125sm6927285wmf.4.2018.02.21.03.05.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:40 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id AD8603E0CCF; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:19 +0000 Message-Id: <20180221110523.859-20-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 4313d3a602..a07b8556b0 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1663,6 +1663,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 @@ -6986,79 +7019,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 Wed Feb 21 11:05:20 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: 129034 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp507930ljc; Wed, 21 Feb 2018 03:25:28 -0800 (PST) X-Google-Smtp-Source: AH8x227VvF9eS2yVqmzoB6nxb8l6XZlvXJ4T2oNEHQ0DH8FjtLaeGaK12UElKbfjU7xCqdeM2IIW X-Received: by 2002:a25:8609:: with SMTP id y9-v6mr1908495ybk.298.1519212328801; Wed, 21 Feb 2018 03:25:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519212328; cv=none; d=google.com; s=arc-20160816; b=NAwSj2SWINemenQ35NsWUghrI4WEez3DZcpo1CX1lEUWvBOV//bV/dKI9C3NLVUBTC iTDc9ycp2sp8qz9gpUUhb0ssUpsboZA1BVG5aBkNByvFFbkfCxdAGuES9mO6Nm+ebOnF aCKiNqyj1cBMRngpbzvn00R05IXd/gx6uxZgzLzjhAz/B2SF4TSPde++HjezD2V8LU2/ 1AyswWsQDRADZ9KHBA9A8XkvmhdED+YTZL5HLl+Gt0q5GmnmcsZwSbRxLphITjMUdtmZ pAVzufTQui5g0rJc96NySLo7yLGkEKJ2/cUhkLqOyiopO13XbHrrY3Ke+JrzcrAvpOIz dedA== 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=9fdkXXlkeER3jmfcO4v9LVRyq7gjZK8fiioUDS6ywt4=; b=hC1HgJHiuEZeW7L4JlWl2NAbjg76xXAsfIPZr08sbla0j2jdD0812a3pmYu7hINHO+ QeUozvpM8fqW1Vd7PXDCQK5Tyr8K7q/JUIJrHsrq188jKo7ksaMKuaG560hF3voY6ZbY sbGjSR3713Rt167oV+EBprMzqII3DXBIIDCV4QLatVgZr7tqFBRwoGkN5+3xad7H0AqM RFlS1/Px4ddt2tcSpJjflC6arMEC/vnocfD8w2KCven14RA7tNJu9K0zbl1FH4KSKuF6 +q+JGMNQuVKS2GYO2XsgcuwuAQZ3CeZFNapLMPwwfYdgA0O5+G/uzAXsGEjBx+2H54cs //Cw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ENgRoyz6; 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 n22si2058085ywn.440.2018.02.21.03.25.28 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:25:28 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=ENgRoyz6; 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]:60151 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSWe-0002aj-3p for patch@linaro.org; Wed, 21 Feb 2018 06:25:28 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37357) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSKA-0001Au-0v for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSK5-0002NG-W1 for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:33 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:35200) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSK5-0002MX-NB for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:29 -0500 Received: by mail-wr0-x244.google.com with SMTP id l43so3348040wrc.2 for ; Wed, 21 Feb 2018 03:12:29 -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=9fdkXXlkeER3jmfcO4v9LVRyq7gjZK8fiioUDS6ywt4=; b=ENgRoyz602Wjpl2G/n5hItdHjX7R9ma5eaUxfNyA5v+foAiZfkgBfLQncno0E27LTy 7JbHskRZGRppwGePpcF0RXiHViOZwMdAJHv9rBr1Fw4ZiFxW4mnAuY3eSRVi7Vk9fXEk xjQ24gUFCp5Og0xBfR8kENqSpDbInVUknHDeU= 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=9fdkXXlkeER3jmfcO4v9LVRyq7gjZK8fiioUDS6ywt4=; b=UJmxKfMztuUdh0vNjLBp0N08uYwDzTnuVd6y0s1FGM6VH+FXn28V7Fl9DPlbK1QXvs /6SzLG91tJOfUs49PjgGHhjVe5c5TR54NgWrtGieoL6XdNe/oK+aJ6cjSyDD/HHxyLwA xKPwTrDWwYZmwUp0x3LNHncTJ/p7xkYmxotYX2/x0TLwc+65M3wK5/Md6d73tX8CdT9E C8qVvQrsFZRO/r5YTIyZwXtmc/nhhT1KKIQtJ6ldbs66njdbpbYhEW7SxyIyhb35gz0Z zRa/EOYsAXzZcgIYBHOD7jSogvh4O+q7VEPaG6guizFnAG6x+ZzS5Mqz2aZRWRjPSJEC d9tg== X-Gm-Message-State: APf1xPCl0hy0d2VOnGPX2bMDdA3fB4RNnEiI5eTAJFBRVtB9sbeUoBH/ 9WId5aD7svpv6kLDZNERNMopDQ== X-Received: by 10.28.10.206 with SMTP id 197mr1806861wmk.61.1519211548615; Wed, 21 Feb 2018 03:12:28 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 27sm29062845wry.5.2018.02.21.03.12.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:12:24 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id C0ACA3E0CDE; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:20 +0000 Message-Id: <20180221110523.859-21-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index a07b8556b0..7a53c36da4 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1663,6 +1663,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) { @@ -6912,113 +7032,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 Wed Feb 21 11:05:21 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: 129031 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp503153ljc; Wed, 21 Feb 2018 03:19:50 -0800 (PST) X-Google-Smtp-Source: AH8x226ep0bIqcxbqaKsm8rsneGWMuPtwsp4DfrfC5Da8QpNU3HesiDg9P9v35bvA8OiH4TizKT1 X-Received: by 10.13.224.65 with SMTP id j62mr1802134ywe.185.1519211990259; Wed, 21 Feb 2018 03:19:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519211990; cv=none; d=google.com; s=arc-20160816; b=TmWrQfXTPxZTqRem6tDoFJpo9/JQ+qE3ZZP9RN94E+4dkq5Z+G62UsBxPolHKL+Z+L v3S7APGH1EH9rOF3GMV1FWrT4t9CXdkzI7CMy/OrZJgX6eHIvMGZoZWCt+W5OfqiGIbd Fdk6vypqFPYwiYjcf2vL4OgUTMRcqFlUEXowD43bbbFEi6eKK5V1aTkiL8/NKmltYVdM h4jrFQKGGDHvFuDVp6Y2MRL+q+ObwkzmvZL8p/WHPj9Yj9zGpnbtnKLiPIeTMl3Bev68 KntQD/PVTNA6EXw0M0WFSyeO4fzX2/cW2jXbxPLIFLfowFDrdWWia2XnMzA3lN+hkeAK aitA== 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=RnV04Edpog3RnuLmmy7/hRUb4LfDq7/ZIw1VFw1SSvA=; b=iQH2qC5u3vX4cP7c03rsM+TRnOUuwyBk8fR7sVZT98J9nKUMguM6zIs8lxVsPzkPwi 59RF++p074ZwPBsSUxZwswNYCRF/D9eec2SxvH3ipSQ88VN7tdzcGiQbLxqtMG6pbJL9 tUDI6qPhzeBNYNbC71q4eAlWaFCyCQkvkhoZA5YrBN3qmxzUOqWCqk08dI1lWJqgF8/f OSRagVgL2quIWxqnI5gPXwBtqtAAEU4g0DL7lLxRIpwpLAw0hM99mQP3z/KvVZ2K+RUE Lb4PWD6+Kl+xfB8BKY8zxB8cQNNKH0/ICh6Sc7kY/tHSqHvg1NpFeHXysHvqqIWo7Gh5 5GjQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=iP3CukeX; 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 f187si1535361ywd.455.2018.02.21.03.19.50 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:19:50 -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=iP3CukeX; 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]:60117 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSRB-0006pT-HQ for patch@linaro.org; Wed, 21 Feb 2018 06:19:49 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35466) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSDm-0004D2-2W for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:06:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSDf-0006mi-M8 for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:58 -0500 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:34347) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSDf-0006mO-Bp for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:05:51 -0500 Received: by mail-wr0-x241.google.com with SMTP id m5so3302882wrg.1 for ; Wed, 21 Feb 2018 03:05:51 -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=RnV04Edpog3RnuLmmy7/hRUb4LfDq7/ZIw1VFw1SSvA=; b=iP3CukeX8x1Rf37TN34THfCs2QCelXPtkxCWACJ68NVlv37167T2gJkYbBzxpNYtoz 9TIEqF81LW9/4Abde4g2eTgV/ujWmaIgWZi0HUA3bB56AoR0Snms++oVLncBLVHfYJVm C0BxcXii0HqCci1YDdxu9CFC9Ujuh+0JI+PY4= 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=RnV04Edpog3RnuLmmy7/hRUb4LfDq7/ZIw1VFw1SSvA=; b=k9zv2RCkztrAylbbuPt6m7GtzukHf7+pbLQNnqlE4kpFia3thyWAJhpyxSDDG8mhmQ r7m5OD6zZRDdQ+5Pv1YZMpeKRmQUtJvcjaNHK3+szQ2lj8OFu8LH1QIiWYu3GwxLSA4N 8SyUld3u0wrJ0HPBS6q7f3/RQB1N/rWmooa0r/Ew4fiXXdI1SFSA9u+EYGKMc1S7ruQi kYWy2s3zbWTuM/y2FI4kbadmzU6V1ELUoK5ZiCsyGP+fUGoRsxZyKJ5ybwoaTPicgIlP EKrKz3mrnpHFaElkPewvXyst9Uw6uX8RjGHCNf8AiQe2WJQQRVtTwx84DMW7/AOygrBh AOPA== X-Gm-Message-State: APf1xPC0dg2z9S32nFc/uVT6YT5cKAeOZVeH8iO1s1EenHu2Obryn9A0 qEjduQUY/XU/A+IHpXP82MJ4uQ== X-Received: by 10.28.166.206 with SMTP id p197mr1662999wme.81.1519211150218; Wed, 21 Feb 2018 03:05:50 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 41sm39191488wrc.12.2018.02.21.03.05.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:05:46 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id D2D8B3E0176; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:21 +0000 Message-Id: <20180221110523.859-22-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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 -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 7a53c36da4..4bc425d7e4 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1783,6 +1783,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) { @@ -6884,60 +6964,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 Wed Feb 21 11:05:22 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: 129037 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp509071ljc; Wed, 21 Feb 2018 03:26:51 -0800 (PST) X-Google-Smtp-Source: AH8x226UXlr+CbeJtth52ul3k5MynGGe8w+nJDApp87iPVU8zNDtClwqFsiZgERN2Qi/xlLHPmMC X-Received: by 2002:a25:d146:: with SMTP id i67-v6mr1930129ybg.495.1519212411613; Wed, 21 Feb 2018 03:26:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519212411; cv=none; d=google.com; s=arc-20160816; b=Gty3SbGDxvTXmPjFhAYo+kIDDwh1dz87OpUklPHYqhysaXqa+lPFsPZVHC+QLIZ7lz BRLI02xj4EQwa/8kfIaHNT5mH4U/vg7HRgCUHF/IwoIpSHoMYC34zd3+S5YUvPapFjB2 H10JOjC+Wuseq/XgcKkB4+noTEfZeBvxwDTynU+k06Zg0rPcHyPp62zyIDWxEOB8WLMc iJ8j9/hLmwBiZK3O/9fCS9KfSBGiYTtzs/iYmA1muC990fYq+c99PuqV0zwJmQW71y/D nivdY8LF5aIudzTNsb7NvSMhf2fCLRyXEDLJoOQ9PvamM3FIeRlxhz9RROVKSG5aIAKi zDlA== 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=yn69zVGmuNidSJ9HxRcTZD6IcAUFa/6Ul7HJQ+7g54s=; b=CL7kU56f3gxSxXv/pqfVq16WNDnVotcd3hpIAvM4eeCnDTlaZ9ylQ/WeBwK1Jnsl5m pCuvSK3Yc7dszTn89tlbnqRDrG2DTCg8mBiDKK09sc+cq2qVs+/2J6JLAa/pCBmu5y8s q1r9lBjV+gNZUaT0EWXoV6I7k6CrZfYqRjYvP2n5Rx3HoU0Tmh1fnYhFApeAEqb2msYs DYtR86a6R53gHYGGl+P2NMKQ143PPCWXvS1NCYH26vSb8TJm3r3AgPYzGLI0wXYUXtzh 6c86J/w48WhhXD1vHBWRZOBABzPKpdTnegVCuUqPOUJmJ/cy5kDOXbkE7NUf3t7EePHQ YCbQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=hBWxKtss; 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 r196si2205271ybc.582.2018.02.21.03.26.51 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Feb 2018 03:26:51 -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=hBWxKtss; 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]:60166 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSXz-0003sJ-0G for patch@linaro.org; Wed, 21 Feb 2018 06:26:51 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37316) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoSK5-000160-Mt for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoSK3-0002LZ-Oa for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:29 -0500 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:40457) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eoSK3-0002L7-Fs for qemu-devel@nongnu.org; Wed, 21 Feb 2018 06:12:27 -0500 Received: by mail-wr0-x242.google.com with SMTP id o76so3326904wrb.7 for ; Wed, 21 Feb 2018 03:12: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=yn69zVGmuNidSJ9HxRcTZD6IcAUFa/6Ul7HJQ+7g54s=; b=hBWxKtsssuHQGHM57DH3DkrROPfSJAIHmFChZ6CH+jxt8DPlRJ6oAdwKB9D8YNNgyi IPzZ5iHw3hX7jl+Iwj3rXGfitcC2uBfNXmrltL/BbMAsXMT/dTsLXiUG/LEDQSYCi205 MmyG5Ap6q+Fhd9GEeDYRbM6NuLbabdxMWaRfQ= 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=yn69zVGmuNidSJ9HxRcTZD6IcAUFa/6Ul7HJQ+7g54s=; b=NO/ey8aD1O4heYK+CewTCyTxgUTvWKLm6hKtBYU1z5/vRrZ69zLlqUQztYEkEnRznu 6vBlChuw4UvU9D+hXkZ+Z23apWRkHHPSNs0eAsvYKG90ZAkGZ4HoAGmyd0Lu7M6k38px P22ZnH3lw66IrtVzs/aPWwL034aIz97xoc+1HfSj5QT1iLYdLr4IIssdWR7hkEXqXmZW wl7qJm0wTbCQUyYCl2/jHzDJfwneGYig9x0n/4UZ4HV/unpy2HctkAlxtkMN2RT6Rdy2 1ojA0qtAwD4M5ylxmbrgVVmJyEk22Zc2I6GgP/1cOVjSgXekGkcrzRhEDbTTV2F66WGm Hm+w== X-Gm-Message-State: APf1xPAyx6Nym/BLP5QlQIuFa+9SRNnVLtpwtDrFReSWxBM+NtNPLc/j dTtFX7NAqBSdY6rwdYNgh5/mcg== X-Received: by 10.223.166.135 with SMTP id t7mr2659642wrc.260.1519211546353; Wed, 21 Feb 2018 03:12:26 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id n24sm30580073wmi.21.2018.02.21.03.12.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 03:12:24 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id E5CE43E0CEF; Wed, 21 Feb 2018 11:05:24 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Feb 2018 11:05:22 +0000 Message-Id: <20180221110523.859-23-alex.bennee@linaro.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180221110523.859-1-alex.bennee@linaro.org> References: <20180221110523.859-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] [PULL 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. There is a minor optimisation to avoid calculating more bits of precision than we need however this still brings a performance drop, especially for float64 operations. Suggested-by: Richard Henderson Signed-off-by: Alex Bennée Reviewed-by: Peter Maydell Reviewed-by: Richard Henderson -- 2.15.1 diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 4bc425d7e4..e7fb0d357a 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1896,6 +1896,102 @@ 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. + * + * This does mean however the calculation is slower than before, + * especially for 64 bit floats. + */ + +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 __attribute__((flatten)) 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 __attribute__((flatten)) 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 __attribute__((flatten)) 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 @@ -3303,62 +3399,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 @@ -4202,61 +4242,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);