From nobody Tue Apr 15 15:41:28 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; 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 1535103395166795.6280889785038; Fri, 24 Aug 2018 02:36:35 -0700 (PDT) Received: from localhost ([::1]:40670 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ft8W8-0001O8-Qr for importer@patchew.org; Fri, 24 Aug 2018 05:36:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35311) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ft8Tc-00073L-Th for qemu-devel@nongnu.org; Fri, 24 Aug 2018 05:33:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ft8Tb-0002r2-0t for qemu-devel@nongnu.org; Fri, 24 Aug 2018 05:33:56 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44860) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ft8Ta-0002N1-MQ for qemu-devel@nongnu.org; Fri, 24 Aug 2018 05:33:54 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1ft8TV-0006LQ-6S for qemu-devel@nongnu.org; Fri, 24 Aug 2018 10:33:49 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 24 Aug 2018 10:32:52 +0100 Message-Id: <20180824093343.11346-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180824093343.11346-1-peter.maydell@linaro.org> References: <20180824093343.11346-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 01/52] 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Richard Henderson Signed-off-by: Richard Henderson Message-id: 20180814002653.12828-2-richard.henderson@linaro.org Reviewed-by: Peter Maydell Signed-off-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 69f4dbc4db7..038e375e713 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 7d63cffdeb8..12f373cbade 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.18.0