From patchwork Tue Aug 14 00:26:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 144063 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp3689541ljj; Mon, 13 Aug 2018 17:27:29 -0700 (PDT) X-Google-Smtp-Source: AA+uWPwWlVd0vF8SXLtSmuKetl+ngt/QdmFHJvK6BJvNsqHmq0E5MyluzUoueyAtTCfIWiH2NbRM X-Received: by 2002:a0c:94f1:: with SMTP id k46-v6mr17239912qvk.113.1534206449741; Mon, 13 Aug 2018 17:27:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534206449; cv=none; d=google.com; s=arc-20160816; b=zTtLiZ2OjceL3lqEMbuQS9dY4uEg70H7w1sesJNr91YhP0IPUhPY+sxnO4waY44UFa RfWLb+boALqsBkJGu8Ujh8l0f+3ASosS7lJbVbmIKPtN9yc18qXj+69n+Szs+yBySfzh w/UhC7FA/vBpbwkvKrsasBr31fTbB2i1Av6YW1eieVv25Md/thUx0+UKP5jq13H8jRib mx96pt8+ZR55TRQCcI4fkE4F31EYxOmIgb2SVMvC0Rhxwj+Rpv9qxMO67KAbkV1NJOQj Do+h18vxtPGrXMhr4urNCKbBoQNl/hAYeCnGnAmygg4Eo4JqxW2bQsdqkKGLj0FuzcqB Ih0A== 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:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=Z0RRHmbU8S7q89dF0ZkeGStiklNYdjIB7xN9dKPYJR0=; b=eXNSmP8u08aQKd9TLKe8sp011mvXPUHXgDEyCd147NsC+NIE6AYCKoE58AzUfVm5tk VtXty9gmtIzZJbvHNQgccG1mIZqgg3ANFeHgu3gvdozDWk1NxDMJCsK0nPKtNCkCjs1f Qgzx3RSmn9+UuOE8Y5peypSpxlNdJNnga1fNkDlnxxM32fa0PJTUKxkBs4REikdG0Rvr QZhqs0UDjNxUvxXOQpHIQNxgAxHaHr82XY4agVx44KbECWnLO8ToMItBdim6FuE2QNhk eXugGubzuR23sXOX+3JRm4w+8UnCYoyV6QlxBMV34oumCVBx0SOj3zjXHjGF/iGvQGVV I9Jg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=gW9z6P9h; 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 100-v6si4522601qkv.335.2018.08.13.17.27.29 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 13 Aug 2018 17:27:29 -0700 (PDT) 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=gW9z6P9h; 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]:41901 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNBJ-0004wK-5p for patch@linaro.org; Mon, 13 Aug 2018 20:27:29 -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) 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-Received: by 2002:a63:de4c:: with SMTP id y12-v6mr18747592pgi.435.1534206417647; Mon, 13 Aug 2018 17:26:57 -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) 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+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- include/fpu/softfloat.h | 56 ++++++++---- fpu/softfloat.c | 188 +++++++++++++++++++++++++++++----------- 2 files changed, 179 insertions(+), 65 deletions(-) -- 2.17.1 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); /*---------------------------------------------------------------------------- @@ -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); /*---------------------------------------------------------------------------- | 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. */ -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 = {}; + FloatParts r = { .sign = false }; + 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; + uint64_t f = a; + int shift; + r.cls = float_class_normal; - r.exp = (DECOMPOSED_BINARY_POINT - shift); - r.frac = f << shift; + if (a < 0) { + f = -f; + r.sign = true; + } + shift = clz64(f) - 1; + scale = MIN(MAX(scale, -0x10000), 0x10000); + + r.exp = DECOMPOSED_BINARY_POINT - shift + scale; + r.frac = (shift < 0 ? DECOMPOSED_IMPLICIT_BIT : f << shift); } return r; } +float16 int64_to_float16_scalbn(int64_t a, int scale, float_status *status) +{ + FloatParts pa = 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 = int_to_float(a, status); - return float16_round_pack_canonical(pa, status); + return int64_to_float16_scalbn(a, 0, status); } float16 int32_to_float16(int32_t a, float_status *status) { - return int64_to_float16(a, status); + return int64_to_float16_scalbn(a, 0, status); } 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 = 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); } float32 int64_to_float32(int64_t a, float_status *status) { - FloatParts pa = int_to_float(a, status); - return float32_round_pack_canonical(pa, status); + return int64_to_float32_scalbn(a, 0, status); } float32 int32_to_float32(int32_t a, float_status *status) { - return int64_to_float32(a, status); + return int64_to_float32_scalbn(a, 0, status); } 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 = 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); } float64 int64_to_float64(int64_t a, float_status *status) { - FloatParts pa = int_to_float(a, status); - return float64_round_pack_canonical(pa, status); + return int64_to_float64_scalbn(a, 0, status); } float64 int32_to_float64(int32_t a, float_status *status) { - return int64_to_float64(a, status); + return int64_to_float64_scalbn(a, 0, status); } float64 int16_to_float64(int16_t a, float_status *status) { - return int64_to_float64(a, status); + return int64_to_float64_scalbn(a, 0, status); } @@ -1689,73 +1730,120 @@ float64 int16_to_float64(int16_t a, float_status *status) * IEC/IEEE Standard for Binary Floating-Point Arithmetic. */ -static FloatParts uint_to_float(uint64_t a, float_status *status) +static FloatParts uint_to_float(uint64_t a, int scale, float_status *status) { - FloatParts r = { .sign = false}; + FloatParts r = { .sign = false }; if (a == 0) { r.cls = float_class_zero; } else { - int spare_bits = clz64(a) - 1; + scale = MIN(MAX(scale, -0x10000), 0x10000); r.cls = float_class_normal; - r.exp = DECOMPOSED_BINARY_POINT - spare_bits; - if (spare_bits < 0) { - shift64RightJamming(a, -spare_bits, &a); + if ((int64_t)a < 0) { + r.exp = DECOMPOSED_BINARY_POINT + 1 + scale; + shift64RightJamming(a, 1, &a); r.frac = a; } else { - r.frac = a << spare_bits; + int shift = clz64(a) - 1; + r.exp = DECOMPOSED_BINARY_POINT - shift + scale; + r.frac = a << shift; } } return r; } +float16 uint64_to_float16_scalbn(uint64_t a, int scale, float_status *status) +{ + FloatParts pa = 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 *status) +{ + return uint64_to_float16_scalbn(a, scale, status); +} + +float16 uint16_to_float16_scalbn(uint16_t a, int scale, float_status *status) +{ + return uint64_to_float16_scalbn(a, scale, status); +} + float16 uint64_to_float16(uint64_t a, float_status *status) { - FloatParts pa = uint_to_float(a, status); - return float16_round_pack_canonical(pa, status); + return uint64_to_float16_scalbn(a, 0, status); } float16 uint32_to_float16(uint32_t a, float_status *status) { - return uint64_to_float16(a, status); + return uint64_to_float16_scalbn(a, 0, status); } 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 *status) +{ + FloatParts pa = 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 *status) +{ + return uint64_to_float32_scalbn(a, scale, status); +} + +float32 uint16_to_float32_scalbn(uint16_t a, int scale, float_status *status) +{ + return uint64_to_float32_scalbn(a, scale, 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); + return uint64_to_float32_scalbn(a, 0, status); } float32 uint32_to_float32(uint32_t a, float_status *status) { - return uint64_to_float32(a, status); + return uint64_to_float32_scalbn(a, 0, status); } 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 *status) +{ + FloatParts pa = 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 *status) +{ + return uint64_to_float64_scalbn(a, scale, status); +} + +float64 uint16_to_float64_scalbn(uint16_t a, int scale, float_status *status) +{ + return uint64_to_float64_scalbn(a, scale, 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); + return uint64_to_float64_scalbn(a, 0, status); } float64 uint32_to_float64(uint32_t a, float_status *status) { - return uint64_to_float64(a, status); + return uint64_to_float64_scalbn(a, 0, status); } float64 uint16_to_float64(uint16_t a, float_status *status) { - return uint64_to_float64(a, status); + return uint64_to_float64_scalbn(a, 0, status); } /* Float Min/Max */ From patchwork Tue Aug 14 00:26:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 144065 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp3691359ljj; Mon, 13 Aug 2018 17:30:01 -0700 (PDT) X-Google-Smtp-Source: AA+uWPwr+P2reTeIXqZAoT74DtHfgi+22WPWbKnfvX5RmPOpB+qfZwOAkQNjVF/lsTvc6asXwLoi X-Received: by 2002:a37:d98f:: with SMTP id q15-v6mr18085573qkl.167.1534206601580; Mon, 13 Aug 2018 17:30:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534206601; cv=none; d=google.com; s=arc-20160816; b=yXJ6sElG73PMQZewoPq5/rcKWKfkyo7A1QDRgXqd6+covOWOtVzPv4cqwYi1s7wbwM csuBjrX73CDxlbmYFALfvX/x46peZn8RsWk3VOhTBdvNXG/x/zcS5nudNO6GyMqVM4zn 0U5vkdLoCgta+ngAbDI/s+0fdiHJGC6uF2ReDb1nyny4jq9g8zEomWMK4wMeTxvO3nd2 VqumzCMP+URm+N4Z+NP4fMbi12Jy4D825JZFYx+MUXlyhPlrnnfLrICEoVsxQk0UxDeq oidnAVBWm/NSGllpwPC6KfMW1E7doeLO9WJ3gQw8/wKB176sEQEmnK0ZkzjSuJzJLzTb ESig== 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:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=5JI5USC+CHtcFYZVAxo8JWQ3Tzdlx39X5MPBgBCoTr0=; b=z5Woat71TtY7ebeH1m1GXXhhCFiq+5JoscT3+2P95oQ9d5W6MqfH1aqQlRXTHmt4Mn 9AkktXwu6dH+XYKoBl3lCnkp1GXBDdOPbbSy07cNZD9PDKNGcfdX5+8L+/5LhGY/LWPD LMEwvlKyWl2vKADoS3Mc4+/6NU8aJmgZmd4pGqv6/t5J0Rf7ROFGxX626RKIFmFq0l7y +sCTxzf/+uu0AOy3Do24O+EJ3DFsDT5+qMUMB2OpEcRlMjDgHOYSIdtUVQ8ixMrpaSU5 0Ax3xkQO9IKvHpY0/XxI34qIxR/mMGzTAKTAmhxCO6GrJvlMAPcHkNEcZZRDt0abdWiA B6uw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=CmqQkQCL; 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 g22-v6si1994197qtf.251.2018.08.13.17.30.01 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 13 Aug 2018 17:30:01 -0700 (PDT) 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=CmqQkQCL; 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]:41908 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNDl-00068B-0K for patch@linaro.org; Mon, 13 Aug 2018 20:30:01 -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) 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-Received: by 2002:a63:4d5:: with SMTP id 204-v6mr18820503pge.129.1534206419092; Mon, 13 Aug 2018 17:26:59 -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) 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+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- include/fpu/softfloat.h | 85 ++++++--- fpu/softfloat.c | 391 ++++++++++++++++++++++++++++++++-------- 2 files changed, 379 insertions(+), 97 deletions(-) -- 2.17.1 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 *status); /*---------------------------------------------------------------------------- | 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 *status); +uint32_t float16_to_uint32_scalbn(float16 a, int, int, float_status *status); +uint64_t float16_to_uint64_scalbn(float16 a, int, int, float_status *status); + +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); /*---------------------------------------------------------------------------- @@ -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. */ -static FloatParts round_to_int(FloatParts a, int rounding_mode, float_status *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 = MIN(MAX(scale, -0x10000), 0x10000); + a.exp += scale; + if (a.exp >= DECOMPOSED_BINARY_POINT) { /* already integral */ break; @@ -1314,7 +1318,7 @@ static FloatParts round_to_int(FloatParts a, int rounding_mode, float_status *s) bool one; /* all fractional */ s->float_exception_flags |= float_flag_inexact; - switch (rounding_mode) { + switch (rmode) { case float_round_nearest_even: one = a.exp == -1 && a.frac > DECOMPOSED_IMPLICIT_BIT; break; @@ -1347,7 +1351,7 @@ static FloatParts round_to_int(FloatParts a, int rounding_mode, float_status *s) uint64_t rnd_mask = rnd_even_mask >> 1; uint64_t inc; - switch (rounding_mode) { + switch (rmode) { case float_round_nearest_even: inc = ((a.frac & rnd_even_mask) != frac_lsbm1 ? frac_lsbm1 : 0); break; @@ -1387,28 +1391,28 @@ static FloatParts round_to_int(FloatParts a, int rounding_mode, float_status *s) 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); + FloatParts pr = round_to_int(pa, s->float_rounding_mode, 0, 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); + FloatParts pr = round_to_int(pa, s->float_rounding_mode, 0, 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); + FloatParts pr = round_to_int(pa, s->float_rounding_mode, 0, 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); + FloatParts pr = round_to_int(pa, float_round_to_zero, 0, s); return float64_round_pack_canonical(pr, s); } @@ -1423,13 +1427,13 @@ float64 float64_trunc_to_int(float64 a, float_status *s) * is returned. */ -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 = get_float_exception_flags(s); - FloatParts p = round_to_int(in, rmode, s); + FloatParts p = round_to_int(in, rmode, scale, s); switch (p.cls) { case float_class_snan: @@ -1469,38 +1473,158 @@ static int64_t round_to_int_and_pack(FloatParts in, int rmode, } } -#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); \ +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); } -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); +} -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); +} -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); +} -#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); +} /* * Returns the result of converting the floating-point value `a' to @@ -1515,11 +1639,12 @@ FLOAT_TO_INT(64, 64) * flag. */ -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 = get_float_exception_flags(s); - FloatParts p = round_to_int(in, rmode, s); + FloatParts p = round_to_int(in, rmode, scale, s); + uint64_t r; 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 = 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 = orig_flags | float_flag_invalid; return max; - } else { - return r; } - } + 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, 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); } -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); +} -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); +} -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); +} -#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); +} /* * Integer to float conversions From patchwork Tue Aug 14 00:26:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 144066 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp3691615ljj; Mon, 13 Aug 2018 17:30:18 -0700 (PDT) X-Google-Smtp-Source: AA+uWPxCja35LvO6s5gvvSoqJ4wS7gXw+N9WoTW6V5KRwUlsWfChz9X+oBjeXVRjIkqwBFAoMGlz X-Received: by 2002:aed:2518:: with SMTP id v24-v6mr19087789qtc.151.1534206618774; Mon, 13 Aug 2018 17:30:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534206618; cv=none; d=google.com; s=arc-20160816; b=a02vFKBgLbIjoE/ynMJkNmYJbd/Sip9FNgsKPgIkZqfkk1PwW2rLiFYwZhX1AbroLy +mVLEAXHfI1GUW7PtxJEbEhIfYF7S8X1HzQ1GEloQKFMN3hGAvICcoMc8AO4/eg36UUq gTnzhQDtrwQyjGJ14nSC6nwAJs+c+zhHxMKlBPR0j/rJOcxlqC7f4brDQMZw6pOCTlMz As354CzEUykubcG8jWZshWxK994dseg1l1rRcu4AIZBgN5OoJrjGevQa1lbSkfCIq9pb nbvkO9UnEmbRWqAyLxvQ7TQgmNkkc5o9QHRi+cNPdMC2+nKk5vE7TZY3CJiMU7/5Byuz Cs8g== 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:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=8O4/e0LK0zeeyoKlBYwAe9tKELxEjfMaZ46nQW8OB88=; b=OXbVr3p2HOUDMQsc64TNZ4o8D/w2TcgliHbGXxW8wQIpqqRmIlxxVr04xa2k+FAoU/ g+MHCrv2TL7PfRAR04eYwUlfWXIciVA13XUurPhVXca/ODBMwQ023GdWFyJj+oM7aPgg 5GAMyPpgIYOLNS5KSFKqvyHVa41T7cYT1OLssHx/8NJpgfARB6W9naeZ4WEM5IdNy3GG KuGc0bB3SpzicB4j4gqw5YE/K4isU8FdlfSGyoZkWozw99V0HXpbg/4y4gNXeuqvcvi8 raKtS4PNhj6QpWj94Bgb6G+Ick3PPjrkOuZMmmDO3S8aS46GkuhBLXo0HH2O6nEq/Bv2 JICQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=JHCjQYsB; 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 i35-v6si6007658qvc.125.2018.08.13.17.30.18 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 13 Aug 2018 17:30:18 -0700 (PDT) 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=JHCjQYsB; 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]:41914 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNE2-0007Eg-8N for patch@linaro.org; Mon, 13 Aug 2018 20:30:18 -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) 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-Received: by 2002:a63:5758:: with SMTP id h24-v6mr18822824pgm.432.1534206420347; 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.59 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 13 Aug 2018 17:26:59 -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+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- target/arm/helper.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) -- 2.17.1 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, CPUARMState *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 = fpstp; \ - float##fsz tmp; \ - tmp = itype##_to_##float##fsz(x, fpst); \ - return float##fsz##_scalbn(tmp, -(int)shift, fpst); \ -} +{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); } /* 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 -/* 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); } 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); } 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); } 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); } static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst) From patchwork Tue Aug 14 00:26:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 144064 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp3689559ljj; Mon, 13 Aug 2018 17:27:30 -0700 (PDT) X-Google-Smtp-Source: AA+uWPwHFnkEQhGbB6hAGBXf0Tf5QiEd0f2sUAoclIUl64h4eavaDEPDgQr4XiZBYE2qnojIfF/c X-Received: by 2002:aed:3c34:: with SMTP id t49-v6mr18087050qte.404.1534206450892; Mon, 13 Aug 2018 17:27:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534206450; cv=none; d=google.com; s=arc-20160816; b=Q7n+veBQgPnCufhmn4aAhllgjesFo5a8mPP2UOQsmRjxRYxh+Zb0s+DIVYe+dXpmwB 9zVJsGqDxTn0/gXB7FI1ozkwvbHfld/SiinyylClKaEtgrvEZiUEZc+p5HKqt+A/jZ08 bpzaoarR/KsnqEpO4BLGl515YKFQ+kdZ8Wl++suQfJJKJ5l0iWSl4D1D4MiKNzlyyJRh 8XECXiii98rYN8fmmDuIIvouizD6FDo+GfUUBhAzzIIJ3fNgS1gFgAQpH/EWtBKPPNhg WBeRKAad0vfoNDs5MiqT1T7X6BxTD6ELsViNoaZJdkYWye1qvLuMl3STeL2/cVFeS/GJ swWg== 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:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=FsfX1H1P09zN5YuN9E7d+yIJbDJFVwowhQcrFqKWv7Y=; b=pGdaIAjC94AiSUIgcIVTf7B07ZTWcqAMudud/R2OiRjADZzvX5wl/oT1MxZFCIBjGa coMdHxnZYdzynyvYe2eoJjqI+bT6y9XKPtYitbjQwiC9adPTZCBt/QbNHwBg59Ix7+Kn O2qN2HDntv+G0Agh0zOnW7n9cYE/EjfjFghlJC+6/YaBFmfwAeOdaogGQ7WePYcUZOoM iICfHkJkKYfh/+rym3onet8hToYvbzFpkV58fRxRkTyIXttzOA6F7IR/jaXwyrPKIo8m EODfgR3rCktXkYROkSjCA45tIV/WCPVUv2C3tA7+a92JtuVlpfsLfiCRP+DUvCJMzGin ZYFQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=OfVLEVlS; 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 46-v6si5575788qtv.342.2018.08.13.17.27.30 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 13 Aug 2018 17:27:30 -0700 (PDT) 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=OfVLEVlS; 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]:41902 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpNBK-0004xZ-AW for patch@linaro.org; Mon, 13 Aug 2018 20:27:30 -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) 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-Received: by 2002:a62:1f06:: with SMTP id f6-v6mr21250386pff.140.1534206421761; 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.27.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 13 Aug 2018 17:27:00 -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+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- target/arm/helper.c | 101 ++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 50 deletions(-) -- 2.17.1 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); } -/* 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 = fpstp; \ - int old_exc_flags = get_float_exception_flags(fpst); \ - float##fsz tmp; \ - if (float##fsz##_is_any_nan(x)) { \ - float_raise(float_flag_invalid, fpst); \ - return 0; \ - } \ - tmp = float##fsz##_scalbn(x, shift, fpst); \ - old_exc_flags |= 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); \ } #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), ) #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), ) 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 shift, void *fpst) return uint64_to_float16_scalbn(x, -shift, fpst); } -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 = get_float_exception_flags(fpst); - float64 ret; - - ret = float16_to_float64(f, true, fpst); - ret = float64_scalbn(ret, shift, fpst); - old_exc_flags |= 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); } 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); } 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); } 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); } 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); } 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); } /* Set the current fp rounding mode and return the old one.