From nobody Wed Nov 5 08:00:05 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534206555548492.4110503469974; Mon, 13 Aug 2018 17:29:15 -0700 (PDT) Received: from localhost ([::1]:41906 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNCr-00064e-27 for importer@patchew.org; Mon, 13 Aug 2018 20:29:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51735) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNAr-0004ul-88 for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fpNAp-0000lH-99 for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:01 -0400 Received: from mail-pf1-x443.google.com ([2607:f8b0:4864:20::443]:36770) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fpNAo-0000l5-Vf for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:26:59 -0400 Received: by mail-pf1-x443.google.com with SMTP id b11-v6so8426302pfo.3 for ; Mon, 13 Aug 2018 17:26:58 -0700 (PDT) Received: from cloudburst.twiddle.net (97-113-8-179.tukw.qwest.net. [97.113.8.179]) by smtp.gmail.com with ESMTPSA id w192-v6sm22266976pfd.74.2018.08.13.17.26.56 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 13 Aug 2018 17:26:56 -0700 (PDT) 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; bh=Z0RRHmbU8S7q89dF0ZkeGStiklNYdjIB7xN9dKPYJR0=; b=gW9z6P9haA5cu7WVPhQfAfMNOdKWm/dEEEW7Au5xp05iNSEMKfOauTIF5f/ZpR51q0 KIHB7WmNoPPWzq5ktygZH434RsWRjchOMr75ISFTNpsW2RZHqlroUfFTlEho9tEsdRwj gZiph80iVSyWSiVvvsa8kk5CDE6T70QB7WU1U= 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; bh=Z0RRHmbU8S7q89dF0ZkeGStiklNYdjIB7xN9dKPYJR0=; b=iHhAZm1EuzPVFvUduXK2YDiljRoknh3rvYr3jtnx2xwOgkcPhk1Egac5pXHJKDTWRR XJDFjV/Z+WicspLzDnjyOPrN8qLkvntiNPjRNEX+Mh8wToT5vk9Rgi5pDtB1tFVWT9t7 x3AKl6UnEH2kKCFe07YsubbHz3V8J4Ri9SVc2b0ob2bufxTp549stBGsUae4NyAmjmeL XtX4ae/Qf4VY1m2l1V2uHzh60FrqkRiaErvnWRQoOC3ue50eHSBbPWvfwhgHH5+CuBDu L0V7bVZxrladoVOBzLjj6u56aHgPHOxFolrQaAqbSbb4KajKzaDVkQBCRerzp6ijLmD4 jcpg== X-Gm-Message-State: AOUpUlGfjwqf8ZP1nCK3+HR+dKAWh2YwXUuTXhoRtgljABDRcyN41FCY uZwUz1xV9MGG1sBwZrR9j2GbsuDTIzc= X-Google-Smtp-Source: AA+uWPwChQC1V/pD+CWhxmZr1gs3q2waOw+HvfwD37gX/IYZAvOTX4KQboFEuYG81ptzKNuCqsyhMg== X-Received: by 2002:a63:de4c:: with SMTP id y12-v6mr18747592pgi.435.1534206417647; Mon, 13 Aug 2018 17:26:57 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 13 Aug 2018 17:26:50 -0700 Message-Id: <20180814002653.12828-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180814002653.12828-1-richard.henderson@linaro.org> References: <20180814002653.12828-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::443 Subject: [Qemu-devel] [PATCH 1/4] softfloat: Add scaling int-to-float routines 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: laurent.desnogues@gmail.com, peter.maydell@linaro.org, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell --- include/fpu/softfloat.h | 56 ++++++++---- fpu/softfloat.c | 188 +++++++++++++++++++++++++++++----------- 2 files changed, 179 insertions(+), 65 deletions(-) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 69f4dbc4db..038e375e71 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -190,22 +190,54 @@ enum { /*------------------------------------------------------------------------= ---- | Software IEC/IEEE integer-to-floating-point conversion routines. *-------------------------------------------------------------------------= ---*/ + +float16 int16_to_float16_scalbn(int16_t a, int, float_status *status); +float16 int32_to_float16_scalbn(int32_t a, int, float_status *status); +float16 int64_to_float16_scalbn(int64_t a, int, float_status *status); +float16 uint16_to_float16_scalbn(uint16_t a, int, float_status *status); +float16 uint32_to_float16_scalbn(uint32_t a, int, float_status *status); +float16 uint64_to_float16_scalbn(uint64_t a, int, 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); + +float32 int16_to_float32_scalbn(int16_t, int, float_status *status); +float32 int32_to_float32_scalbn(int32_t, int, float_status *status); +float32 int64_to_float32_scalbn(int64_t, int, float_status *status); +float32 uint16_to_float32_scalbn(uint16_t, int, float_status *status); +float32 uint32_to_float32_scalbn(uint32_t, int, float_status *status); +float32 uint64_to_float32_scalbn(uint64_t, int, float_status *status); + 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 int64_to_float32(int64_t, float_status *status); float32 uint16_to_float32(uint16_t, float_status *status); float32 uint32_to_float32(uint32_t, float_status *status); +float32 uint64_to_float32(uint64_t, float_status *status); + +float64 int16_to_float64_scalbn(int16_t, int, float_status *status); +float64 int32_to_float64_scalbn(int32_t, int, float_status *status); +float64 int64_to_float64_scalbn(int64_t, int, float_status *status); +float64 uint16_to_float64_scalbn(uint16_t, int, float_status *status); +float64 uint32_to_float64_scalbn(uint32_t, int, float_status *status); +float64 uint64_to_float64_scalbn(uint64_t, int, float_status *status); + +float64 int16_to_float64(int16_t, float_status *status); +float64 int32_to_float64(int32_t, float_status *status); +float64 int64_to_float64(int64_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); -float32 int64_to_float32(int64_t, float_status *status); -float64 int64_to_float64(int64_t, float_status *status); -floatx80 int64_to_floatx80(int64_t, float_status *status); -float128 int64_to_float128(int64_t, float_status *status); -float32 uint64_to_float32(uint64_t, float_status *status); float64 uint64_to_float64(uint64_t, float_status *status); + +floatx80 int32_to_floatx80(int32_t, float_status *status); +floatx80 int64_to_floatx80(int64_t, float_status *status); + +float128 int32_to_float128(int32_t, float_status *status); +float128 int64_to_float128(int64_t, float_status *status); float128 uint64_to_float128(uint64_t, float_status *status); =20 /*------------------------------------------------------------------------= ---- @@ -227,12 +259,6 @@ 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); -float16 int32_to_float16(int32_t a, float_status *status); -float16 int64_to_float16(int64_t a, float_status *status); -float16 uint16_to_float16(uint16_t a, float_status *status); -float16 uint32_to_float16(uint32_t a, float_status *status); -float16 uint64_to_float16(uint64_t a, float_status *status); =20 /*------------------------------------------------------------------------= ---- | Software half-precision operations. diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 7d63cffdeb..12f373cbad 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1603,81 +1603,122 @@ FLOAT_TO_UINT(64, 64) * to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. */ =20 -static FloatParts int_to_float(int64_t a, float_status *status) +static FloatParts int_to_float(int64_t a, int scale, float_status *status) { - FloatParts r =3D {}; + FloatParts r =3D { .sign =3D false }; + if (a =3D=3D 0) { r.cls =3D float_class_zero; - r.sign =3D false; - } else if (a =3D=3D (1ULL << 63)) { - r.cls =3D float_class_normal; - r.sign =3D true; - r.frac =3D DECOMPOSED_IMPLICIT_BIT; - r.exp =3D 63; } else { - uint64_t f; - if (a < 0) { - f =3D -a; - r.sign =3D true; - } else { - f =3D a; - r.sign =3D false; - } - int shift =3D clz64(f) - 1; + uint64_t f =3D a; + int shift; + r.cls =3D float_class_normal; - r.exp =3D (DECOMPOSED_BINARY_POINT - shift); - r.frac =3D f << shift; + if (a < 0) { + f =3D -f; + r.sign =3D true; + } + shift =3D clz64(f) - 1; + scale =3D MIN(MAX(scale, -0x10000), 0x10000); + + r.exp =3D DECOMPOSED_BINARY_POINT - shift + scale; + r.frac =3D (shift < 0 ? DECOMPOSED_IMPLICIT_BIT : f << shift); } =20 return r; } =20 +float16 int64_to_float16_scalbn(int64_t a, int scale, float_status *status) +{ + FloatParts pa =3D int_to_float(a, scale, status); + return float16_round_pack_canonical(pa, status); +} + +float16 int32_to_float16_scalbn(int32_t a, int scale, float_status *status) +{ + return int64_to_float16_scalbn(a, scale, status); +} + +float16 int16_to_float16_scalbn(int16_t a, int scale, float_status *status) +{ + return int64_to_float16_scalbn(a, scale, status); +} + float16 int64_to_float16(int64_t a, float_status *status) { - FloatParts pa =3D int_to_float(a, status); - return float16_round_pack_canonical(pa, status); + return int64_to_float16_scalbn(a, 0, status); } =20 float16 int32_to_float16(int32_t a, float_status *status) { - return int64_to_float16(a, status); + return int64_to_float16_scalbn(a, 0, status); } =20 float16 int16_to_float16(int16_t a, float_status *status) { - return int64_to_float16(a, status); + return int64_to_float16_scalbn(a, 0, status); +} + +float32 int64_to_float32_scalbn(int64_t a, int scale, float_status *status) +{ + FloatParts pa =3D int_to_float(a, scale, status); + return float32_round_pack_canonical(pa, status); +} + +float32 int32_to_float32_scalbn(int32_t a, int scale, float_status *status) +{ + return int64_to_float32_scalbn(a, scale, status); +} + +float32 int16_to_float32_scalbn(int16_t a, int scale, float_status *status) +{ + return int64_to_float32_scalbn(a, scale, status); } =20 float32 int64_to_float32(int64_t a, float_status *status) { - FloatParts pa =3D int_to_float(a, status); - return float32_round_pack_canonical(pa, status); + return int64_to_float32_scalbn(a, 0, status); } =20 float32 int32_to_float32(int32_t a, float_status *status) { - return int64_to_float32(a, status); + return int64_to_float32_scalbn(a, 0, status); } =20 float32 int16_to_float32(int16_t a, float_status *status) { - return int64_to_float32(a, status); + return int64_to_float32_scalbn(a, 0, status); +} + +float64 int64_to_float64_scalbn(int64_t a, int scale, float_status *status) +{ + FloatParts pa =3D int_to_float(a, scale, status); + return float64_round_pack_canonical(pa, status); +} + +float64 int32_to_float64_scalbn(int32_t a, int scale, float_status *status) +{ + return int64_to_float64_scalbn(a, scale, status); +} + +float64 int16_to_float64_scalbn(int16_t a, int scale, float_status *status) +{ + return int64_to_float64_scalbn(a, scale, status); } =20 float64 int64_to_float64(int64_t a, float_status *status) { - FloatParts pa =3D int_to_float(a, status); - return float64_round_pack_canonical(pa, status); + return int64_to_float64_scalbn(a, 0, status); } =20 float64 int32_to_float64(int32_t a, float_status *status) { - return int64_to_float64(a, status); + return int64_to_float64_scalbn(a, 0, status); } =20 float64 int16_to_float64(int16_t a, float_status *status) { - return int64_to_float64(a, status); + return int64_to_float64_scalbn(a, 0, status); } =20 =20 @@ -1689,73 +1730,120 @@ float64 int16_to_float64(int16_t a, float_status *= status) * IEC/IEEE Standard for Binary Floating-Point Arithmetic. */ =20 -static FloatParts uint_to_float(uint64_t a, float_status *status) +static FloatParts uint_to_float(uint64_t a, int scale, float_status *statu= s) { - FloatParts r =3D { .sign =3D false}; + FloatParts r =3D { .sign =3D false }; =20 if (a =3D=3D 0) { r.cls =3D float_class_zero; } else { - int spare_bits =3D clz64(a) - 1; + scale =3D MIN(MAX(scale, -0x10000), 0x10000); r.cls =3D float_class_normal; - r.exp =3D DECOMPOSED_BINARY_POINT - spare_bits; - if (spare_bits < 0) { - shift64RightJamming(a, -spare_bits, &a); + if ((int64_t)a < 0) { + r.exp =3D DECOMPOSED_BINARY_POINT + 1 + scale; + shift64RightJamming(a, 1, &a); r.frac =3D a; } else { - r.frac =3D a << spare_bits; + int shift =3D clz64(a) - 1; + r.exp =3D DECOMPOSED_BINARY_POINT - shift + scale; + r.frac =3D a << shift; } } =20 return r; } =20 +float16 uint64_to_float16_scalbn(uint64_t a, int scale, float_status *stat= us) +{ + FloatParts pa =3D uint_to_float(a, scale, status); + return float16_round_pack_canonical(pa, status); +} + +float16 uint32_to_float16_scalbn(uint32_t a, int scale, float_status *stat= us) +{ + return uint64_to_float16_scalbn(a, scale, status); +} + +float16 uint16_to_float16_scalbn(uint16_t a, int scale, float_status *stat= us) +{ + return uint64_to_float16_scalbn(a, scale, status); +} + float16 uint64_to_float16(uint64_t a, float_status *status) { - FloatParts pa =3D uint_to_float(a, status); - return float16_round_pack_canonical(pa, status); + return uint64_to_float16_scalbn(a, 0, status); } =20 float16 uint32_to_float16(uint32_t a, float_status *status) { - return uint64_to_float16(a, status); + return uint64_to_float16_scalbn(a, 0, status); } =20 float16 uint16_to_float16(uint16_t a, float_status *status) { - return uint64_to_float16(a, status); + return uint64_to_float16_scalbn(a, 0, status); +} + +float32 uint64_to_float32_scalbn(uint64_t a, int scale, float_status *stat= us) +{ + FloatParts pa =3D uint_to_float(a, scale, status); + return float32_round_pack_canonical(pa, status); +} + +float32 uint32_to_float32_scalbn(uint32_t a, int scale, float_status *stat= us) +{ + return uint64_to_float32_scalbn(a, scale, status); +} + +float32 uint16_to_float32_scalbn(uint16_t a, int scale, float_status *stat= us) +{ + return uint64_to_float32_scalbn(a, scale, status); } =20 float32 uint64_to_float32(uint64_t a, float_status *status) { - FloatParts pa =3D uint_to_float(a, status); - return float32_round_pack_canonical(pa, status); + return uint64_to_float32_scalbn(a, 0, status); } =20 float32 uint32_to_float32(uint32_t a, float_status *status) { - return uint64_to_float32(a, status); + return uint64_to_float32_scalbn(a, 0, status); } =20 float32 uint16_to_float32(uint16_t a, float_status *status) { - return uint64_to_float32(a, status); + return uint64_to_float32_scalbn(a, 0, status); +} + +float64 uint64_to_float64_scalbn(uint64_t a, int scale, float_status *stat= us) +{ + FloatParts pa =3D uint_to_float(a, scale, status); + return float64_round_pack_canonical(pa, status); +} + +float64 uint32_to_float64_scalbn(uint32_t a, int scale, float_status *stat= us) +{ + return uint64_to_float64_scalbn(a, scale, status); +} + +float64 uint16_to_float64_scalbn(uint16_t a, int scale, float_status *stat= us) +{ + return uint64_to_float64_scalbn(a, scale, status); } =20 float64 uint64_to_float64(uint64_t a, float_status *status) { - FloatParts pa =3D uint_to_float(a, status); - return float64_round_pack_canonical(pa, status); + return uint64_to_float64_scalbn(a, 0, status); } =20 float64 uint32_to_float64(uint32_t a, float_status *status) { - return uint64_to_float64(a, status); + return uint64_to_float64_scalbn(a, 0, status); } =20 float64 uint16_to_float64(uint16_t a, float_status *status) { - return uint64_to_float64(a, status); + return uint64_to_float64_scalbn(a, 0, status); } =20 /* Float Min/Max */ --=20 2.17.1 From nobody Wed Nov 5 08:00:05 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534206555641177.35970161866942; Mon, 13 Aug 2018 17:29:15 -0700 (PDT) Received: from localhost ([::1]:41908 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNCw-00068B-MM for importer@patchew.org; Mon, 13 Aug 2018 20:29:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51765) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNAt-0004v2-KJ for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fpNAr-0000mh-3A for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:03 -0400 Received: from mail-pf1-x42c.google.com ([2607:f8b0:4864:20::42c]:35114) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fpNAq-0000le-Nx for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:01 -0400 Received: by mail-pf1-x42c.google.com with SMTP id p12-v6so8436010pfh.2 for ; Mon, 13 Aug 2018 17:27:00 -0700 (PDT) Received: from cloudburst.twiddle.net (97-113-8-179.tukw.qwest.net. [97.113.8.179]) by smtp.gmail.com with ESMTPSA id w192-v6sm22266976pfd.74.2018.08.13.17.26.57 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 13 Aug 2018 17:26:58 -0700 (PDT) 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; bh=5JI5USC+CHtcFYZVAxo8JWQ3Tzdlx39X5MPBgBCoTr0=; b=CmqQkQCLHE3wC7h+wRqDkTZezcfFSkDYw5BLzXlO14VWq4xH1rmYapvBlchweALWhU 9o1PET0jE9YdVEOjOhoUvILOdfTzE8cvR3bsCM5ctKlTRunbYQa4VgKpgf5mmFbpItnU fqqXIGIPvt//m2NElhHdySIE/0D2GXzD1NKOM= 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; bh=5JI5USC+CHtcFYZVAxo8JWQ3Tzdlx39X5MPBgBCoTr0=; b=b6UE0X0R80C6uWcNqQI3mJuqmVLeowyg5BOq84c5u0vRRbAwU618zvnXrnZw4r5YA9 6nWC+x2TH9R5obn/VAAY8+kj9XP9jaCvucGdL27vR2azrLSkIOzA2P8YjWnnpZq/rG/e 5pYb+6MPBSd0uXeofnhclaB0Qoq26uB4H4gySkNXefg5novQco01+ZenyeGbt3U14YSr iLR4rAGWZeNr0bfwWyIF8dFwePfOsER2bb9zFzaSNXp43Gu8fjXFlhDiJpU9wHzRJANG Wr6Y7YEEloUGL/H0qdMjXkF7+YK0vCje2peqFxRgqtE1aN1WMrVQdDmepReeoONhAXeD p6ZQ== X-Gm-Message-State: AOUpUlHXgnmEN7oh8ywcqTa3GN/sTeZXGvbDBQwmCMajSD8SM0mJCQCN OhfYsGqR6YGk/wBxaaIIxV6JrLpdVAs= X-Google-Smtp-Source: AA+uWPzTyN/zHuSmbaxfwyNp/riYuoYw9P0YAgEwx74vVN8OI3bbVXI5Aj/cl/As7O6br8ze0Uk2/w== X-Received: by 2002:a63:4d5:: with SMTP id 204-v6mr18820503pge.129.1534206419092; Mon, 13 Aug 2018 17:26:59 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 13 Aug 2018 17:26:51 -0700 Message-Id: <20180814002653.12828-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180814002653.12828-1-richard.henderson@linaro.org> References: <20180814002653.12828-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::42c Subject: [Qemu-devel] [PATCH 2/4] softfloat: Add scaling float-to-int routines 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: laurent.desnogues@gmail.com, peter.maydell@linaro.org, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell --- include/fpu/softfloat.h | 85 ++++++--- fpu/softfloat.c | 391 ++++++++++++++++++++++++++++++++-------- 2 files changed, 379 insertions(+), 97 deletions(-) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 038e375e71..cc1b58b029 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -243,21 +243,34 @@ float128 uint64_to_float128(uint64_t, float_status *s= tatus); /*------------------------------------------------------------------------= ---- | Software half-precision conversion routines. *-------------------------------------------------------------------------= ---*/ + float16 float32_to_float16(float32, bool ieee, float_status *status); float32 float16_to_float32(float16, bool ieee, float_status *status); float16 float64_to_float16(float64 a, bool ieee, float_status *status); float64 float16_to_float64(float16 a, bool ieee, float_status *status); + +int16_t float16_to_int16_scalbn(float16, int, int, float_status *status); +int32_t float16_to_int32_scalbn(float16, int, int, float_status *status); +int64_t float16_to_int64_scalbn(float16, int, int, 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); + +int16_t float16_to_int16_round_to_zero(float16, float_status *status); +int32_t float16_to_int32_round_to_zero(float16, float_status *status); int64_t float16_to_int64_round_to_zero(float16, float_status *status); + +uint16_t float16_to_uint16_scalbn(float16 a, int, int, float_status *statu= s); +uint32_t float16_to_uint32_scalbn(float16 a, int, int, float_status *statu= s); +uint64_t float16_to_uint64_scalbn(float16 a, int, int, float_status *statu= s); + +uint16_t float16_to_uint16(float16 a, float_status *status); +uint32_t float16_to_uint32(float16 a, float_status *status); +uint64_t float16_to_uint64(float16 a, float_status *status); + +uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status); +uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status); uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); =20 /*------------------------------------------------------------------------= ---- @@ -347,18 +360,31 @@ float16 float16_default_nan(float_status *status); /*------------------------------------------------------------------------= ---- | Software IEC/IEEE single-precision conversion routines. *-------------------------------------------------------------------------= ---*/ + +int16_t float32_to_int16_scalbn(float32, int, int, float_status *status); +int32_t float32_to_int32_scalbn(float32, int, int, float_status *status); +int64_t float32_to_int64_scalbn(float32, int, int, float_status *status); + int16_t float32_to_int16(float32, float_status *status); -uint16_t float32_to_uint16(float32, float_status *status); -int16_t float32_to_int16_round_to_zero(float32, float_status *status); -uint16_t float32_to_uint16_round_to_zero(float32, float_status *status); int32_t float32_to_int32(float32, float_status *status); -int32_t float32_to_int32_round_to_zero(float32, float_status *status); -uint32_t float32_to_uint32(float32, float_status *status); -uint32_t float32_to_uint32_round_to_zero(float32, float_status *status); int64_t float32_to_int64(float32, float_status *status); -uint64_t float32_to_uint64(float32, float_status *status); -uint64_t float32_to_uint64_round_to_zero(float32, float_status *status); + +int16_t float32_to_int16_round_to_zero(float32, float_status *status); +int32_t float32_to_int32_round_to_zero(float32, float_status *status); int64_t float32_to_int64_round_to_zero(float32, float_status *status); + +uint16_t float32_to_uint16_scalbn(float32, int, int, float_status *status); +uint32_t float32_to_uint32_scalbn(float32, int, int, float_status *status); +uint64_t float32_to_uint64_scalbn(float32, int, int, float_status *status); + +uint16_t float32_to_uint16(float32, float_status *status); +uint32_t float32_to_uint32(float32, float_status *status); +uint64_t float32_to_uint64(float32, float_status *status); + +uint16_t float32_to_uint16_round_to_zero(float32, float_status *status); +uint32_t float32_to_uint32_round_to_zero(float32, float_status *status); +uint64_t float32_to_uint64_round_to_zero(float32, float_status *status); + float64 float32_to_float64(float32, float_status *status); floatx80 float32_to_floatx80(float32, float_status *status); float128 float32_to_float128(float32, float_status *status); @@ -476,18 +502,31 @@ float32 float32_default_nan(float_status *status); /*------------------------------------------------------------------------= ---- | Software IEC/IEEE double-precision conversion routines. *-------------------------------------------------------------------------= ---*/ + +int16_t float64_to_int16_scalbn(float64, int, int, float_status *status); +int32_t float64_to_int32_scalbn(float64, int, int, float_status *status); +int64_t float64_to_int64_scalbn(float64, int, int, float_status *status); + int16_t float64_to_int16(float64, float_status *status); -uint16_t float64_to_uint16(float64, float_status *status); -int16_t float64_to_int16_round_to_zero(float64, float_status *status); -uint16_t float64_to_uint16_round_to_zero(float64, float_status *status); int32_t float64_to_int32(float64, float_status *status); -int32_t float64_to_int32_round_to_zero(float64, float_status *status); -uint32_t float64_to_uint32(float64, float_status *status); -uint32_t float64_to_uint32_round_to_zero(float64, float_status *status); int64_t float64_to_int64(float64, float_status *status); + +int16_t float64_to_int16_round_to_zero(float64, float_status *status); +int32_t float64_to_int32_round_to_zero(float64, float_status *status); int64_t float64_to_int64_round_to_zero(float64, float_status *status); -uint64_t float64_to_uint64(float64 a, float_status *status); -uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *status); + +uint16_t float64_to_uint16_scalbn(float64, int, int, float_status *status); +uint32_t float64_to_uint32_scalbn(float64, int, int, float_status *status); +uint64_t float64_to_uint64_scalbn(float64, int, int, float_status *status); + +uint16_t float64_to_uint16(float64, float_status *status); +uint32_t float64_to_uint32(float64, float_status *status); +uint64_t float64_to_uint64(float64, float_status *status); + +uint16_t float64_to_uint16_round_to_zero(float64, float_status *status); +uint32_t float64_to_uint32_round_to_zero(float64, float_status *status); +uint64_t float64_to_uint64_round_to_zero(float64, float_status *status); + float32 float64_to_float32(float64, float_status *status); floatx80 float64_to_floatx80(float64, float_status *status); float128 float64_to_float128(float64, float_status *status); diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 12f373cbad..59ca356d0e 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1293,19 +1293,23 @@ float32 float64_to_float32(float64 a, float_status = *s) * Arithmetic. */ =20 -static FloatParts round_to_int(FloatParts a, int rounding_mode, float_stat= us *s) +static FloatParts round_to_int(FloatParts a, int rmode, + int scale, float_status *s) { - if (is_nan(a.cls)) { - return return_nan(a, s); - } - switch (a.cls) { + case float_class_qnan: + case float_class_snan: + return return_nan(a, s); + case float_class_zero: case float_class_inf: - case float_class_qnan: /* already "integral" */ break; + case float_class_normal: + scale =3D MIN(MAX(scale, -0x10000), 0x10000); + a.exp +=3D scale; + if (a.exp >=3D DECOMPOSED_BINARY_POINT) { /* already integral */ break; @@ -1314,7 +1318,7 @@ static FloatParts round_to_int(FloatParts a, int roun= ding_mode, float_status *s) bool one; /* all fractional */ s->float_exception_flags |=3D float_flag_inexact; - switch (rounding_mode) { + switch (rmode) { case float_round_nearest_even: one =3D a.exp =3D=3D -1 && a.frac > DECOMPOSED_IMPLICIT_BI= T; break; @@ -1347,7 +1351,7 @@ static FloatParts round_to_int(FloatParts a, int roun= ding_mode, float_status *s) uint64_t rnd_mask =3D rnd_even_mask >> 1; uint64_t inc; =20 - switch (rounding_mode) { + switch (rmode) { case float_round_nearest_even: inc =3D ((a.frac & rnd_even_mask) !=3D frac_lsbm1 ? frac_l= sbm1 : 0); break; @@ -1387,28 +1391,28 @@ static FloatParts round_to_int(FloatParts a, int ro= unding_mode, float_status *s) float16 float16_round_to_int(float16 a, float_status *s) { FloatParts pa =3D float16_unpack_canonical(a, s); - FloatParts pr =3D round_to_int(pa, s->float_rounding_mode, s); + FloatParts pr =3D round_to_int(pa, s->float_rounding_mode, 0, s); return float16_round_pack_canonical(pr, s); } =20 float32 float32_round_to_int(float32 a, float_status *s) { FloatParts pa =3D float32_unpack_canonical(a, s); - FloatParts pr =3D round_to_int(pa, s->float_rounding_mode, s); + FloatParts pr =3D round_to_int(pa, s->float_rounding_mode, 0, s); return float32_round_pack_canonical(pr, s); } =20 float64 float64_round_to_int(float64 a, float_status *s) { FloatParts pa =3D float64_unpack_canonical(a, s); - FloatParts pr =3D round_to_int(pa, s->float_rounding_mode, s); + FloatParts pr =3D round_to_int(pa, s->float_rounding_mode, 0, s); return float64_round_pack_canonical(pr, s); } =20 float64 float64_trunc_to_int(float64 a, float_status *s) { FloatParts pa =3D float64_unpack_canonical(a, s); - FloatParts pr =3D round_to_int(pa, float_round_to_zero, s); + FloatParts pr =3D round_to_int(pa, float_round_to_zero, 0, s); return float64_round_pack_canonical(pr, s); } =20 @@ -1423,13 +1427,13 @@ float64 float64_trunc_to_int(float64 a, float_statu= s *s) * is returned. */ =20 -static int64_t round_to_int_and_pack(FloatParts in, int rmode, +static int64_t round_to_int_and_pack(FloatParts in, int rmode, int scale, int64_t min, int64_t max, float_status *s) { uint64_t r; int orig_flags =3D get_float_exception_flags(s); - FloatParts p =3D round_to_int(in, rmode, s); + FloatParts p =3D round_to_int(in, rmode, scale, s); =20 switch (p.cls) { case float_class_snan: @@ -1469,38 +1473,158 @@ static int64_t round_to_int_and_pack(FloatParts in= , int rmode, } } =20 -#define FLOAT_TO_INT(fsz, isz) \ -int ## isz ## _t float ## fsz ## _to_int ## isz(float ## fsz a, \ - float_status *s) \ -{ \ - FloatParts p =3D 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 =3D float ## fsz ## _unpack_canonical(a, s); \ - return round_to_int_and_pack(p, float_round_to_zero, \ - INT ## isz ## _MIN, INT ## isz ## _MAX,\ - s); \ +int16_t float16_to_int16_scalbn(float16 a, int rmode, int scale, + float_status *s) +{ + return round_to_int_and_pack(float16_unpack_canonical(a, s), + rmode, scale, INT16_MIN, INT16_MAX, s); } =20 -FLOAT_TO_INT(16, 16) -FLOAT_TO_INT(16, 32) -FLOAT_TO_INT(16, 64) +int32_t float16_to_int32_scalbn(float16 a, int rmode, int scale, + float_status *s) +{ + return round_to_int_and_pack(float16_unpack_canonical(a, s), + rmode, scale, INT32_MIN, INT32_MAX, s); +} =20 -FLOAT_TO_INT(32, 16) -FLOAT_TO_INT(32, 32) -FLOAT_TO_INT(32, 64) +int64_t float16_to_int64_scalbn(float16 a, int rmode, int scale, + float_status *s) +{ + return round_to_int_and_pack(float16_unpack_canonical(a, s), + rmode, scale, INT64_MIN, INT64_MAX, s); +} =20 -FLOAT_TO_INT(64, 16) -FLOAT_TO_INT(64, 32) -FLOAT_TO_INT(64, 64) +int16_t float32_to_int16_scalbn(float32 a, int rmode, int scale, + float_status *s) +{ + return round_to_int_and_pack(float32_unpack_canonical(a, s), + rmode, scale, INT16_MIN, INT16_MAX, s); +} =20 -#undef FLOAT_TO_INT +int32_t float32_to_int32_scalbn(float32 a, int rmode, int scale, + float_status *s) +{ + return round_to_int_and_pack(float32_unpack_canonical(a, s), + rmode, scale, INT32_MIN, INT32_MAX, s); +} + +int64_t float32_to_int64_scalbn(float32 a, int rmode, int scale, + float_status *s) +{ + return round_to_int_and_pack(float32_unpack_canonical(a, s), + rmode, scale, INT64_MIN, INT64_MAX, s); +} + +int16_t float64_to_int16_scalbn(float64 a, int rmode, int scale, + float_status *s) +{ + return round_to_int_and_pack(float64_unpack_canonical(a, s), + rmode, scale, INT16_MIN, INT16_MAX, s); +} + +int32_t float64_to_int32_scalbn(float64 a, int rmode, int scale, + float_status *s) +{ + return round_to_int_and_pack(float64_unpack_canonical(a, s), + rmode, scale, INT32_MIN, INT32_MAX, s); +} + +int64_t float64_to_int64_scalbn(float64 a, int rmode, int scale, + float_status *s) +{ + return round_to_int_and_pack(float64_unpack_canonical(a, s), + rmode, scale, INT64_MIN, INT64_MAX, s); +} + +int16_t float16_to_int16(float16 a, float_status *s) +{ + return float16_to_int16_scalbn(a, s->float_rounding_mode, 0, s); +} + +int32_t float16_to_int32(float16 a, float_status *s) +{ + return float16_to_int32_scalbn(a, s->float_rounding_mode, 0, s); +} + +int64_t float16_to_int64(float16 a, float_status *s) +{ + return float16_to_int64_scalbn(a, s->float_rounding_mode, 0, s); +} + +int16_t float32_to_int16(float32 a, float_status *s) +{ + return float32_to_int16_scalbn(a, s->float_rounding_mode, 0, s); +} + +int32_t float32_to_int32(float32 a, float_status *s) +{ + return float32_to_int32_scalbn(a, s->float_rounding_mode, 0, s); +} + +int64_t float32_to_int64(float32 a, float_status *s) +{ + return float32_to_int64_scalbn(a, s->float_rounding_mode, 0, s); +} + +int16_t float64_to_int16(float64 a, float_status *s) +{ + return float64_to_int16_scalbn(a, s->float_rounding_mode, 0, s); +} + +int32_t float64_to_int32(float64 a, float_status *s) +{ + return float64_to_int32_scalbn(a, s->float_rounding_mode, 0, s); +} + +int64_t float64_to_int64(float64 a, float_status *s) +{ + return float64_to_int64_scalbn(a, s->float_rounding_mode, 0, s); +} + +int16_t float16_to_int16_round_to_zero(float16 a, float_status *s) +{ + return float16_to_int16_scalbn(a, float_round_to_zero, 0, s); +} + +int32_t float16_to_int32_round_to_zero(float16 a, float_status *s) +{ + return float16_to_int32_scalbn(a, float_round_to_zero, 0, s); +} + +int64_t float16_to_int64_round_to_zero(float16 a, float_status *s) +{ + return float16_to_int64_scalbn(a, float_round_to_zero, 0, s); +} + +int16_t float32_to_int16_round_to_zero(float32 a, float_status *s) +{ + return float32_to_int16_scalbn(a, float_round_to_zero, 0, s); +} + +int32_t float32_to_int32_round_to_zero(float32 a, float_status *s) +{ + return float32_to_int32_scalbn(a, float_round_to_zero, 0, s); +} + +int64_t float32_to_int64_round_to_zero(float32 a, float_status *s) +{ + return float32_to_int64_scalbn(a, float_round_to_zero, 0, s); +} + +int16_t float64_to_int16_round_to_zero(float64 a, float_status *s) +{ + return float64_to_int16_scalbn(a, float_round_to_zero, 0, s); +} + +int32_t float64_to_int32_round_to_zero(float64 a, float_status *s) +{ + return float64_to_int32_scalbn(a, float_round_to_zero, 0, s); +} + +int64_t float64_to_int64_round_to_zero(float64 a, float_status *s) +{ + return float64_to_int64_scalbn(a, float_round_to_zero, 0, s); +} =20 /* * Returns the result of converting the floating-point value `a' to @@ -1515,11 +1639,12 @@ FLOAT_TO_INT(64, 64) * flag. */ =20 -static uint64_t round_to_uint_and_pack(FloatParts in, int rmode, uint64_t = max, - float_status *s) +static uint64_t round_to_uint_and_pack(FloatParts in, int rmode, int scale, + uint64_t max, float_status *s) { int orig_flags =3D get_float_exception_flags(s); - FloatParts p =3D round_to_int(in, rmode, s); + FloatParts p =3D round_to_int(in, rmode, scale, s); + uint64_t r; =20 switch (p.cls) { case float_class_snan: @@ -1532,8 +1657,6 @@ static uint64_t round_to_uint_and_pack(FloatParts in,= int rmode, uint64_t max, case float_class_zero: return 0; case float_class_normal: - { - uint64_t r; if (p.sign) { s->float_exception_flags =3D orig_flags | float_flag_invalid; return 0; @@ -1555,45 +1678,165 @@ static uint64_t round_to_uint_and_pack(FloatParts = in, int rmode, uint64_t max, if (r > max) { s->float_exception_flags =3D orig_flags | float_flag_invalid; return max; - } else { - return r; } - } + return r; default: g_assert_not_reached(); } } =20 -#define FLOAT_TO_UINT(fsz, isz) \ -uint ## isz ## _t float ## fsz ## _to_uint ## isz(float ## fsz a, \ - float_status *s) \ -{ \ - FloatParts p =3D 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 =3D float ## fsz ## _unpack_canonical(a, s); \ - return round_to_uint_and_pack(p, float_round_to_zero, \ - UINT ## isz ## _MAX, s); \ +uint16_t float16_to_uint16_scalbn(float16 a, int rmode, int scale, + float_status *s) +{ + return round_to_uint_and_pack(float16_unpack_canonical(a, s), + rmode, scale, UINT16_MAX, s); } =20 -FLOAT_TO_UINT(16, 16) -FLOAT_TO_UINT(16, 32) -FLOAT_TO_UINT(16, 64) +uint32_t float16_to_uint32_scalbn(float16 a, int rmode, int scale, + float_status *s) +{ + return round_to_uint_and_pack(float16_unpack_canonical(a, s), + rmode, scale, UINT32_MAX, s); +} =20 -FLOAT_TO_UINT(32, 16) -FLOAT_TO_UINT(32, 32) -FLOAT_TO_UINT(32, 64) +uint64_t float16_to_uint64_scalbn(float16 a, int rmode, int scale, + float_status *s) +{ + return round_to_uint_and_pack(float16_unpack_canonical(a, s), + rmode, scale, UINT64_MAX, s); +} =20 -FLOAT_TO_UINT(64, 16) -FLOAT_TO_UINT(64, 32) -FLOAT_TO_UINT(64, 64) +uint16_t float32_to_uint16_scalbn(float32 a, int rmode, int scale, + float_status *s) +{ + return round_to_uint_and_pack(float32_unpack_canonical(a, s), + rmode, scale, UINT16_MAX, s); +} =20 -#undef FLOAT_TO_UINT +uint32_t float32_to_uint32_scalbn(float32 a, int rmode, int scale, + float_status *s) +{ + return round_to_uint_and_pack(float32_unpack_canonical(a, s), + rmode, scale, UINT32_MAX, s); +} + +uint64_t float32_to_uint64_scalbn(float32 a, int rmode, int scale, + float_status *s) +{ + return round_to_uint_and_pack(float32_unpack_canonical(a, s), + rmode, scale, UINT64_MAX, s); +} + +uint16_t float64_to_uint16_scalbn(float64 a, int rmode, int scale, + float_status *s) +{ + return round_to_uint_and_pack(float64_unpack_canonical(a, s), + rmode, scale, UINT16_MAX, s); +} + +uint32_t float64_to_uint32_scalbn(float64 a, int rmode, int scale, + float_status *s) +{ + return round_to_uint_and_pack(float64_unpack_canonical(a, s), + rmode, scale, UINT32_MAX, s); +} + +uint64_t float64_to_uint64_scalbn(float64 a, int rmode, int scale, + float_status *s) +{ + return round_to_uint_and_pack(float64_unpack_canonical(a, s), + rmode, scale, UINT64_MAX, s); +} + +uint16_t float16_to_uint16(float16 a, float_status *s) +{ + return float16_to_uint16_scalbn(a, s->float_rounding_mode, 0, s); +} + +uint32_t float16_to_uint32(float16 a, float_status *s) +{ + return float16_to_uint32_scalbn(a, s->float_rounding_mode, 0, s); +} + +uint64_t float16_to_uint64(float16 a, float_status *s) +{ + return float16_to_uint64_scalbn(a, s->float_rounding_mode, 0, s); +} + +uint16_t float32_to_uint16(float32 a, float_status *s) +{ + return float32_to_uint16_scalbn(a, s->float_rounding_mode, 0, s); +} + +uint32_t float32_to_uint32(float32 a, float_status *s) +{ + return float32_to_uint32_scalbn(a, s->float_rounding_mode, 0, s); +} + +uint64_t float32_to_uint64(float32 a, float_status *s) +{ + return float32_to_uint64_scalbn(a, s->float_rounding_mode, 0, s); +} + +uint16_t float64_to_uint16(float64 a, float_status *s) +{ + return float64_to_uint16_scalbn(a, s->float_rounding_mode, 0, s); +} + +uint32_t float64_to_uint32(float64 a, float_status *s) +{ + return float64_to_uint32_scalbn(a, s->float_rounding_mode, 0, s); +} + +uint64_t float64_to_uint64(float64 a, float_status *s) +{ + return float64_to_uint64_scalbn(a, s->float_rounding_mode, 0, s); +} + +uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *s) +{ + return float16_to_uint16_scalbn(a, float_round_to_zero, 0, s); +} + +uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *s) +{ + return float16_to_uint32_scalbn(a, float_round_to_zero, 0, s); +} + +uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *s) +{ + return float16_to_uint64_scalbn(a, float_round_to_zero, 0, s); +} + +uint16_t float32_to_uint16_round_to_zero(float32 a, float_status *s) +{ + return float32_to_uint16_scalbn(a, float_round_to_zero, 0, s); +} + +uint32_t float32_to_uint32_round_to_zero(float32 a, float_status *s) +{ + return float32_to_uint32_scalbn(a, float_round_to_zero, 0, s); +} + +uint64_t float32_to_uint64_round_to_zero(float32 a, float_status *s) +{ + return float32_to_uint64_scalbn(a, float_round_to_zero, 0, s); +} + +uint16_t float64_to_uint16_round_to_zero(float64 a, float_status *s) +{ + return float64_to_uint16_scalbn(a, float_round_to_zero, 0, s); +} + +uint32_t float64_to_uint32_round_to_zero(float64 a, float_status *s) +{ + return float64_to_uint32_scalbn(a, float_round_to_zero, 0, s); +} + +uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *s) +{ + return float64_to_uint64_scalbn(a, float_round_to_zero, 0, s); +} =20 /* * Integer to float conversions --=20 2.17.1 From nobody Wed Nov 5 08:00:05 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534206669693495.33033542280714; Mon, 13 Aug 2018 17:31:09 -0700 (PDT) Received: from localhost ([::1]:41921 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNEl-0007jm-VF for importer@patchew.org; Mon, 13 Aug 2018 20:31:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51753) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNAs-0004us-Ru for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fpNAr-0000o1-SY for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:02 -0400 Received: from mail-pg1-x52a.google.com ([2607:f8b0:4864:20::52a]:39699) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fpNAr-0000mx-NI for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:01 -0400 Received: by mail-pg1-x52a.google.com with SMTP id a11-v6so8278914pgw.6 for ; Mon, 13 Aug 2018 17:27:01 -0700 (PDT) Received: from cloudburst.twiddle.net (97-113-8-179.tukw.qwest.net. [97.113.8.179]) by smtp.gmail.com with ESMTPSA id w192-v6sm22266976pfd.74.2018.08.13.17.26.59 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 13 Aug 2018 17:26:59 -0700 (PDT) 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; bh=8O4/e0LK0zeeyoKlBYwAe9tKELxEjfMaZ46nQW8OB88=; b=JHCjQYsBRTk6smEnBqa3IRxwLx6WYz9r0YKo5K7l3okgWQqWY8EmVY0XW7MFtWGiV+ TCEUK3/Gx2krjmYFlhNHj196G2NajiBKONbAg9tgOvPkkNl+0I9trBSLkA2vRV3mYVA7 EyfnDWjqm8ySd40kdPqbrDZUTqr0Tqsi/daAs= 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; bh=8O4/e0LK0zeeyoKlBYwAe9tKELxEjfMaZ46nQW8OB88=; b=i4lQlva4MngsJNCAvjanRYjAsJFmod9jDEJhxgeWLcSSUm/Xxjmu1K1kx1rm58D1O+ JUVMkbof1SUAqGOENVOTqpp0dWkO2AD3Rk9tpambxs2EyvRU7wB5PQlkM7yjVBfSCP4e UnNBId/F3A2b+J0UqA48QRoO/52g5QPUpeSN1X2xUsyHb4lqc8opGc5wxMEe/N9Qev1j H/z4rxPVFqy5qlKicVkZTLIuolGWCVabHWCHRYWmGDQEzYVA/dm9J3//Rhfz1Nh5pPRF oeQEe1NdYn0vZFSwTxoS2zqoFZuKMXUbwF/b6xLmukuwt9Hy6BAXhIG0/yqmLFAJb0tX UwXQ== X-Gm-Message-State: AOUpUlHXoYOzv+w19i46b11TNgh4kEXhPUXzb3TPhU/2uHKin9sisMhf V0g5xWtZTtPWPeThXkbvTicMCUPBKF0= X-Google-Smtp-Source: AA+uWPyadEKrYheIIg4XGovKWe1YkseicM0EmUWC5HQ5croV2zTmRLxS4Azf1+kKyx4me1FdxIiRMA== X-Received: by 2002:a63:5758:: with SMTP id h24-v6mr18822824pgm.432.1534206420347; Mon, 13 Aug 2018 17:27:00 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 13 Aug 2018 17:26:52 -0700 Message-Id: <20180814002653.12828-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180814002653.12828-1-richard.henderson@linaro.org> References: <20180814002653.12828-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::52a Subject: [Qemu-devel] [PATCH 3/4] target/arm: Use the int-to-float-scale softfloat routines 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: laurent.desnogues@gmail.com, peter.maydell@linaro.org, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell --- target/arm/helper.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 61454a77ec..38439a2ee8 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11550,12 +11550,7 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMStat= e *env) #define VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \ void *fpstp) \ -{ \ - float_status *fpst =3D fpstp; \ - float##fsz tmp; \ - tmp =3D itype##_to_##float##fsz(x, fpst); \ - return float##fsz##_scalbn(tmp, -(int)shift, fpst); \ -} +{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); } =20 /* Notice that we want only input-denormal exception flags from the * scalbn operation: the other possible flags (overflow+inexact if @@ -11608,38 +11603,24 @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64) #undef VFP_CONV_FLOAT_FIX_ROUND #undef VFP_CONV_FIX_A64 =20 -/* Conversion to/from f16 can overflow to infinity before/after scaling. - * Therefore we convert to f64, scale, and then convert f64 to f16; or - * vice versa for conversion to integer. - * - * For 16- and 32-bit integers, the conversion to f64 never rounds. - * For 64-bit integers, any integer that would cause rounding will also - * overflow to f16 infinity, so there is no double rounding problem. - */ - -static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst) -{ - return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst); -} - uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst) { - return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst); + return int32_to_float16_scalbn(x, -shift, fpst); } =20 uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst) { - return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst); + return uint32_to_float16_scalbn(x, -shift, fpst); } =20 uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst) { - return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst); + return int64_to_float16_scalbn(x, -shift, fpst); } =20 uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst) { - return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst); + return uint64_to_float16_scalbn(x, -shift, fpst); } =20 static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst) --=20 2.17.1 From nobody Wed Nov 5 08:00:05 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534206555480966.1174694304499; Mon, 13 Aug 2018 17:29:15 -0700 (PDT) Received: from localhost ([::1]:41907 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNCr-00065S-Op for importer@patchew.org; Mon, 13 Aug 2018 20:29:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51771) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNAu-0004vk-IS for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fpNAt-0000pI-Dd for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:04 -0400 Received: from mail-pg1-x52b.google.com ([2607:f8b0:4864:20::52b]:44848) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fpNAt-0000ou-4d for qemu-devel@nongnu.org; Mon, 13 Aug 2018 20:27:03 -0400 Received: by mail-pg1-x52b.google.com with SMTP id r1-v6so8272987pgp.11 for ; Mon, 13 Aug 2018 17:27:02 -0700 (PDT) Received: from cloudburst.twiddle.net (97-113-8-179.tukw.qwest.net. [97.113.8.179]) by smtp.gmail.com with ESMTPSA id w192-v6sm22266976pfd.74.2018.08.13.17.27.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 13 Aug 2018 17:27:00 -0700 (PDT) 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; bh=FsfX1H1P09zN5YuN9E7d+yIJbDJFVwowhQcrFqKWv7Y=; b=OfVLEVlSt5dG4GTIjlTZdjq45/2TYvg4psrXFov3cxzuLqqJN1QWejz16F4gLyvUsd RHiOpYpHQJTY/nZJ2u4ZWP0aa4GIUMNbcC9XA2SUpD0oaRWcXqKTOp9eDNcMcQqUewnd eZubRuG0pCFhDBNbCfR6IkH3vf7Z8XK+DCa8w= 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; bh=FsfX1H1P09zN5YuN9E7d+yIJbDJFVwowhQcrFqKWv7Y=; b=hIjBlGThjerFg6aDlOS5Qk5zGyv2O3MsaSYhVkg+UhVu3n4Xb8t2uRXR5kbLprpmzU koJMGWTW7n0gctGpbfGYmi6eQkEEyb1/Qr4jdq3ALTTehqpkH2PzEg5WszvS5cqfxWIp lazrf4h57vo0FQAzGOMTytGw/8zzFqo3/DoPvQ1vAzUyJTEMrTpPtfFLYNHjhCcrB+6G mLh+4oCRoMrkOJ4E2xiOMCOZmYCE8n4d7i/bscxGgmjosvoFrn4jLBYfo8TOZc64876T XejF0W/+QZABi+6BwaWHHl3TLWfrHD/hHIZ40K8GyNint3TeldblfOeJ+m4Za1O01r1r tOEg== X-Gm-Message-State: AOUpUlE6musHRFr5l/N5dMA5PS1q5vgOunaAXRq5+0z99QWOtpz2f9hg RvvJwHGwnBhrcDHKNE2tC7aN3qctHl4= X-Google-Smtp-Source: AA+uWPwGFKgeoeHFMjJrpS6R8T4Zcx5xcHIgi8OqovNWD4YRuntwjY3d+ksFP0JQOXTB3gkwhHZ1Tg== X-Received: by 2002:a62:1f06:: with SMTP id f6-v6mr21250386pff.140.1534206421761; Mon, 13 Aug 2018 17:27:01 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 13 Aug 2018 17:26:53 -0700 Message-Id: <20180814002653.12828-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180814002653.12828-1-richard.henderson@linaro.org> References: <20180814002653.12828-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::52b Subject: [Qemu-devel] [PATCH 4/4] target/arm: Use the float-to-int-scale softfloat routines 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: laurent.desnogues@gmail.com, peter.maydell@linaro.org, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell --- target/arm/helper.c | 101 ++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 38439a2ee8..e4a7d97805 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11552,38 +11552,28 @@ float##fsz HELPER(vfp_##name##to##p)(uint##isz##_= t x, uint32_t shift, \ void *fpstp) \ { return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); } =20 -/* Notice that we want only input-denormal exception flags from the - * scalbn operation: the other possible flags (overflow+inexact if - * we overflow to infinity, output-denormal) aren't correct for the - * complete scale-and-convert operation. - */ -#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, round) \ -uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \ - uint32_t shift, \ - void *fpstp) \ -{ \ - float_status *fpst =3D fpstp; \ - int old_exc_flags =3D get_float_exception_flags(fpst); \ - float##fsz tmp; \ - if (float##fsz##_is_any_nan(x)) { \ - float_raise(float_flag_invalid, fpst); \ - return 0; \ - } \ - tmp =3D float##fsz##_scalbn(x, shift, fpst); \ - old_exc_flags |=3D get_float_exception_flags(fpst) \ - & float_flag_input_denormal; \ - set_float_exception_flags(old_exc_flags, fpst); \ - return float##fsz##_to_##itype##round(tmp, fpst); \ +#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ROUND, suff) \ +uint##isz##_t HELPER(vfp_to##name##p##suff)(float##fsz x, uint32_t shift, \ + void *fpst) \ +{ \ + if (unlikely(float##fsz##_is_any_nan(x))) { \ + float_raise(float_flag_invalid, fpst); \ + return 0; \ + } \ + return float##fsz##_to_##itype##_scalbn(x, ROUND, shift, fpst); \ } =20 #define VFP_CONV_FIX(name, p, fsz, isz, itype) \ VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ -VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, _round_to_zero) \ -VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ) +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \ + float_round_to_zero, _round_to_zero) \ +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \ + get_float_rounding_mode(fpst), ) =20 #define VFP_CONV_FIX_A64(name, p, fsz, isz, itype) \ VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \ -VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ) +VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \ + get_float_rounding_mode(fpst), ) =20 VFP_CONV_FIX(sh, d, 64, 64, int16) VFP_CONV_FIX(sl, d, 64, 64, int32) @@ -11623,53 +11613,64 @@ uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t s= hift, void *fpst) return uint64_to_float16_scalbn(x, -shift, fpst); } =20 -static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst) -{ - if (unlikely(float16_is_any_nan(f))) { - float_raise(float_flag_invalid, fpst); - return 0; - } else { - int old_exc_flags =3D get_float_exception_flags(fpst); - float64 ret; - - ret =3D float16_to_float64(f, true, fpst); - ret =3D float64_scalbn(ret, shift, fpst); - old_exc_flags |=3D get_float_exception_flags(fpst) - & float_flag_input_denormal; - set_float_exception_flags(old_exc_flags, fpst); - - return ret; - } -} - uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst) { - return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst); + if (unlikely(float16_is_any_nan(x))) { + float_raise(float_flag_invalid, fpst); + return 0; + } + return float16_to_int16_scalbn(x, get_float_rounding_mode(fpst), + shift, fpst); } =20 uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst) { - return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst); + if (unlikely(float16_is_any_nan(x))) { + float_raise(float_flag_invalid, fpst); + return 0; + } + return float16_to_uint16_scalbn(x, get_float_rounding_mode(fpst), + shift, fpst); } =20 uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst) { - return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst); + if (unlikely(float16_is_any_nan(x))) { + float_raise(float_flag_invalid, fpst); + return 0; + } + return float16_to_int32_scalbn(x, get_float_rounding_mode(fpst), + shift, fpst); } =20 uint32_t HELPER(vfp_toulh)(uint32_t x, uint32_t shift, void *fpst) { - return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst); + if (unlikely(float16_is_any_nan(x))) { + float_raise(float_flag_invalid, fpst); + return 0; + } + return float16_to_uint32_scalbn(x, get_float_rounding_mode(fpst), + shift, fpst); } =20 uint64_t HELPER(vfp_tosqh)(uint32_t x, uint32_t shift, void *fpst) { - return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst); + if (unlikely(float16_is_any_nan(x))) { + float_raise(float_flag_invalid, fpst); + return 0; + } + return float16_to_int64_scalbn(x, get_float_rounding_mode(fpst), + shift, fpst); } =20 uint64_t HELPER(vfp_touqh)(uint32_t x, uint32_t shift, void *fpst) { - return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst); + if (unlikely(float16_is_any_nan(x))) { + float_raise(float_flag_invalid, fpst); + return 0; + } + return float16_to_uint64_scalbn(x, get_float_rounding_mode(fpst), + shift, fpst); } =20 /* Set the current fp rounding mode and return the old one. --=20 2.17.1