From nobody Wed Nov 5 10:41:21 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 --- 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