From patchwork Sun Feb 4 04:11:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 126807 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp927027ljc; Sat, 3 Feb 2018 20:21:24 -0800 (PST) X-Google-Smtp-Source: AH8x2266ip/Qq+vyVyZNMwF4xz79M2N00p4cc22kkkDV4lpiOGjidYQeKvGWju50j0awXllY7qIT X-Received: by 10.129.31.213 with SMTP id f204mr28795440ywf.337.1517718084211; Sat, 03 Feb 2018 20:21:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517718084; cv=none; d=google.com; s=arc-20160816; b=jNNxDjfe6154H9jQqYBoCqTb/1CKVWQp3ukfVzogWywDxPQbMTWpGRSWvCbCLn5SLB aLgkchiuPnqO47AJPPvc0WblrHQ+poz28JGXhb/lG87QL1LaXtW4GzmTqqYFzz+PbyxC hxxoPC4rccYY+KW07QNEIm5XYP82Z6If968XMBBmqec21p9VVTGt3o0oBHkLhBH3V5MD oBgDF14ausQhrksP7I6SNySXtN9ztkL3gNNXFZYaR3y9xcg0JQnNDdfpP8otz4DMLVvd 6H1aLOdp10vU7jQZjTAxg4detTs3MHZ2fnSvqqSCmPHA8HC4EOjA1NXPywAJfrTALBr7 aE5Q== 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=ATHx72EGmqJVtVfqfpVoh+QbN7FSKFE2TYN2C4U2Y1w=; b=P3y4lvZtOUMZh9ZmDOqY6XH/Y5mEqc9BaFM1qOhdVsBE1Ga9eBnB/16961e52nPgXC p2RwdkWqgQTt9xVlzGven7Tp51eyPJTyGU+X/QoAiWmo877+FCk2c8pspXUnzMChd+tw hwMulyNnPj22WZQuYmC8sMiYb5qZKdIs3RzA9kLNAAKDZdcMejv9J+emL/pR2Dl7l8ra qox/SibgQuwsdfOWCPqUesfPu5D8NLxA0Ql96q7k0zzesnRXEIwEB/b/p6FtLAt9Z6J5 prRmH68v7zNwM/UjtJS+fQWI5q+hvZr7599iQGorZWdx6GQZQuOINdIt3thjDvI+oYiW vk5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=dqV0oWSU; 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 17si444865ywk.315.2018.02.03.20.21.23 for (version=TLS1 cipher=AES128-SHA bits=128/128); Sat, 03 Feb 2018 20:21:24 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=dqV0oWSU; 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]:58306 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eiBnv-0004Jm-Ir for patch@linaro.org; Sat, 03 Feb 2018 23:21:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47416) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eiBf0-0004rX-C1 for qemu-devel@nongnu.org; Sat, 03 Feb 2018 23:12:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eiBew-00051Q-4n for qemu-devel@nongnu.org; Sat, 03 Feb 2018 23:12:10 -0500 Received: from mail-pf0-x244.google.com ([2607:f8b0:400e:c00::244]:33373) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eiBev-00050Q-Sn for qemu-devel@nongnu.org; Sat, 03 Feb 2018 23:12:06 -0500 Received: by mail-pf0-x244.google.com with SMTP id u15so3376195pfa.0 for ; Sat, 03 Feb 2018 20:12:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ATHx72EGmqJVtVfqfpVoh+QbN7FSKFE2TYN2C4U2Y1w=; b=dqV0oWSU8YzKt7XGbnXqTv3zoHT8UPGkWwXOQGcrVwn0vVi1UazMHK7wzHqtzwMtOv lR82kdMzPrheoqZSRU8QH+EW4CcbHRqX4iItM9Ez/v82v7AlnGZxD3cxKh/UzkUNroNw DPN6I8f4EzvS6GHx8JcEZeUFo4wO5A19QhjXY= 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=ATHx72EGmqJVtVfqfpVoh+QbN7FSKFE2TYN2C4U2Y1w=; b=Rog3iYKo5j5DOc3Gj8wBiW71SNbr5PexA5A58NfspjTdn7DYjM1lCjNnbghFWn1tzV NfJ57V+4OV6jyHVM2i1oZXVg1zYetQ8i7UdYgeQJrpaQzbfT1n/tRQAq8xTVqEVG07bh Y3CZMYjErorM5OpICnCz2cMEpuibv+bNufppDqPFfjNRKV406dE9mO7MgJxBNG2s6YuT Cxa7nk5HgJ1WGiCGlpor7er0M/9GyVxAE3mcF5U9D4ZDEul0CcNijx1w68XybJGfOaNr DM/IDoHswoah5hP7rc1Jx3aQYDhF3hCaOC6sTi1t5+pPkb4xBupNs2MPHt8aj3+i9rUI FQXw== X-Gm-Message-State: AKwxytdBOnaxY88wgyxKzDBB6LUlFJeyl8kMR5gqarChhv7KQazhKFRE Vyv3J49tT1U2CebiNrRK2X/zGgm6zQ8= X-Received: by 10.98.101.71 with SMTP id z68mr44831082pfb.181.1517717524574; Sat, 03 Feb 2018 20:12:04 -0800 (PST) Received: from cloudburst.twiddle.net (174-21-6-47.tukw.qwest.net. [174.21.6.47]) by smtp.gmail.com with ESMTPSA id k3sm1399425pgr.12.2018.02.03.20.12.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 03 Feb 2018 20:12:03 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 3 Feb 2018 20:11:29 -0800 Message-Id: <20180204041136.17525-18-richard.henderson@linaro.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180204041136.17525-1-richard.henderson@linaro.org> References: <20180204041136.17525-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::244 Subject: [Qemu-devel] [PATCH 17/24] fpu: Implement int/uint_to_float with soft-fp.h X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, cota@braap.org, alex.bennee@linaro.org, hsp.cat7@gmail.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Add conversions to float16. For consistency, add float128 conversions from int16_t/uint16_t. Signed-off-by: Richard Henderson --- include/fpu/softfloat.h | 50 +++++------ fpu/floatxx.inc.c | 55 ++++++++++++ fpu/softfloat.c | 227 ------------------------------------------------ 3 files changed, 78 insertions(+), 254 deletions(-) -- 2.14.3 diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index cd39131c10..311c4aba1e 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -190,41 +190,37 @@ enum { /*---------------------------------------------------------------------------- | Software IEC/IEEE integer-to-floating-point conversion routines. *----------------------------------------------------------------------------*/ +float16 int16_to_float16(int16_t, float_status *status); +float16 int32_to_float16(int32_t, float_status *status); +float16 int64_to_float16(int64_t, float_status *status); +float16 uint16_to_float16(uint16_t, float_status *status); +float16 uint32_to_float16(uint32_t, float_status *status); +float16 uint64_to_float16(uint64_t, float_status *status); + +float32 int16_to_float32(int16_t, float_status *status); float32 int32_to_float32(int32_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(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); +float64 uint64_to_float64(uint64_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 int16_to_float128(int16_t, float_status *status); +float128 int32_to_float128(int32_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); +float128 uint16_to_float128(uint16_t, float_status *status); +float128 uint32_to_float128(uint32_t, float_status *status); float128 uint64_to_float128(uint64_t, float_status *status); -/* We provide the int16 versions for symmetry of API with float-to-int */ -static inline float32 int16_to_float32(int16_t v, float_status *status) -{ - return int32_to_float32(v, status); -} - -static inline float32 uint16_to_float32(uint16_t v, float_status *status) -{ - return uint32_to_float32(v, status); -} - -static inline float64 int16_to_float64(int16_t v, float_status *status) -{ - return int32_to_float64(v, status); -} - -static inline float64 uint16_to_float64(uint16_t v, float_status *status) -{ - return uint32_to_float64(v, status); -} - /*---------------------------------------------------------------------------- | Software half-precision conversion routines. *----------------------------------------------------------------------------*/ diff --git a/fpu/floatxx.inc.c b/fpu/floatxx.inc.c index da6c17afab..5ca6c924ab 100644 --- a/fpu/floatxx.inc.c +++ b/fpu/floatxx.inc.c @@ -141,3 +141,58 @@ DO_FLOAT_TO_UINT(glue(FLOATXX,_to_uint64_round_to_zero), 64, FP_TO_INT_) #undef DO_FLOAT_TO_INT #undef DO_FLOAT_TO_UINT + +FLOATXX glue(int64_to_,FLOATXX)(int64_t a, float_status *status) +{ + FP_DECL_EX; + glue(FP_DECL_, FS)(R); + FLOATXX r; + + FP_INIT_ROUNDMODE; + glue(FP_FROM_INT_, FS)(R, a, 64, uint64_t); + glue(FP_PACK_RAW_, FS)(r, R); + FP_HANDLE_EXCEPTIONS; + return r; +} + +FLOATXX glue(int16_to_,FLOATXX)(int16_t a, float_status *status) +{ + return glue(int64_to_,FLOATXX)(a, status); +} + +FLOATXX glue(int32_to_,FLOATXX)(int32_t a, float_status *status) +{ + return glue(int64_to_,FLOATXX)(a, status); +} + +/* The code within _FP_FROM_INT always tests A against 0. For the + unsigned conversion, this may result in a compiler warning. + For -Werror, we need to suppress this. */ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" + +FLOATXX glue(uint64_to_,FLOATXX)(uint64_t a, float_status *status) +{ + FP_DECL_EX; + glue(FP_DECL_, FS)(R); + FLOATXX r; + + FP_INIT_ROUNDMODE; + glue(FP_FROM_INT_, FS)(R, a, 64, uint64_t); + glue(FP_PACK_RAW_, FS)(r, R); + FP_HANDLE_EXCEPTIONS; + return r; +} + +#pragma GCC diagnostic pop + +FLOATXX glue(uint16_to_,FLOATXX)(uint16_t a, float_status *status) +{ + return glue(uint64_to_,FLOATXX)(a, status); +} + +FLOATXX glue(uint32_to_,FLOATXX)(uint32_t a, float_status *status) +{ + return glue(uint64_to_,FLOATXX)(a, status); +} diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3fe12abab1..47b8c4815b 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1234,44 +1234,6 @@ static float128 normalizeRoundAndPackFloat128(flag zSign, int32_t zExp, } -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the single-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 int32_to_float32(int32_t a, float_status *status) -{ - flag zSign; - - if ( a == 0 ) return float32_zero; - if ( a == (int32_t) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); - zSign = ( a < 0 ); - return normalizeRoundAndPackFloat32(zSign, 0x9C, zSign ? -a : a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 32-bit two's complement integer `a' -| to the double-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 int32_to_float64(int32_t a, float_status *status) -{ - flag zSign; - uint32_t absA; - int8_t shiftCount; - uint64_t zSig; - - if ( a == 0 ) return float64_zero; - zSign = ( a < 0 ); - absA = zSign ? - a : a; - shiftCount = countLeadingZeros32( absA ) + 21; - zSig = absA; - return packFloat64( zSign, 0x432 - shiftCount, zSig<= 0) { - return packFloat32(0, 0x95 - shiftcount, a << shiftcount); - } - /* Otherwise we need to do a round-and-pack. roundAndPackFloat32() - * expects the binary point between bits 30 and 29, hence the + 7. - */ - shiftcount += 7; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<= shiftcount; - } - - return roundAndPackFloat32(0, 0x9c - shiftcount, a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 64-bit unsigned integer `a' -| to the double-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 uint64_to_float64(uint64_t a, float_status *status) -{ - int exp = 0x43C; - int shiftcount; - - if (a == 0) { - return float64_zero; - } - - shiftcount = countLeadingZeros64(a) - 1; - if (shiftcount < 0) { - shift64RightJamming(a, -shiftcount, &a); - } else { - a <<= shiftcount; - } - return roundAndPackFloat64(0, exp - shiftcount, a, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the 64-bit unsigned integer `a' -| to the quadruple-precision floating-point format. The conversion is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 uint64_to_float128(uint64_t a, float_status *status) -{ - if (a == 0) { - return float128_zero; - } - return normalizeRoundAndPackFloat128(0, 0x406E, a, 0, status); -} - /*---------------------------------------------------------------------------- | Returns the result of converting the single-precision floating-point value | `a' to the double-precision floating-point format. The conversion is @@ -5354,17 +5138,6 @@ int float128_unordered_quiet(float128 a, float128 b, float_status *status) return 0; } -/* misc functions */ -float32 uint32_to_float32(uint32_t a, float_status *status) -{ - return int64_to_float32(a, status); -} - -float64 uint32_to_float64(uint32_t a, float_status *status) -{ - return int64_to_float64(a, status); -} - #define COMPARE(s, nan_exp) \ static inline int float ## s ## _compare_internal(float ## s a, float ## s b,\ int is_quiet, float_status *status) \