From patchwork Mon Dec 14 01:50:46 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 41060 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B8F17B6F08 for ; Mon, 14 Dec 2009 13:43:13 +1100 (EST) Received: from localhost ([127.0.0.1]:51054 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NK0ty-00067Q-UR for incoming@patchwork.ozlabs.org; Sun, 13 Dec 2009 21:43:10 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NK0lu-0002pD-CV for qemu-devel@nongnu.org; Sun, 13 Dec 2009 21:34:50 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NK0lt-0002oX-3A for qemu-devel@nongnu.org; Sun, 13 Dec 2009 21:34:49 -0500 Received: from [199.232.76.173] (port=59844 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NK0ls-0002oD-Jr for qemu-devel@nongnu.org; Sun, 13 Dec 2009 21:34:48 -0500 Received: from are.twiddle.net ([75.149.56.221]:33410) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NK0lr-000134-NA for qemu-devel@nongnu.org; Sun, 13 Dec 2009 21:34:48 -0500 Received: by are.twiddle.net (Postfix, from userid 5000) id CC751D6D; Sun, 13 Dec 2009 18:34:45 -0800 (PST) Message-Id: <6ff344fd3f909c5f897e18af89a95f18c265ac13.1260755765.git.rth@twiddle.net> In-Reply-To: References: From: Richard Henderson Date: Sun, 13 Dec 2009 17:50:46 -0800 To: qemu-devel@nongnu.org X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [Qemu-devel] [PATCH 5/5] target-alpha: Fix float32_to_s vs zero exponent. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org There was a bug in float32_to_s that incorrectly mapped a zero exponent to 0x38. This meant 0.0f != 0. At the same time, fix a generic type punning bug in helper_memory_to_s and helper_s_to_memory. Signed-off-by: Richard Henderson --- target-alpha/op_helper.c | 44 ++++++++++++++++++++++++++++++++------------ 1 files changed, 32 insertions(+), 12 deletions(-) diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index ff120ad..b2abf6c 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -625,37 +625,57 @@ uint64_t helper_sqrtg (uint64_t a) /* S floating (single) */ + +/* Taken from linux/arch/alpha/kernel/traps.c, s_mem_to_reg. */ +static inline uint64_t float32_to_s_int(uint32_t fi) +{ + uint32_t frac = fi & 0x7fffff; + uint32_t sign = fi >> 31; + uint32_t exp_msb = (fi >> 30) & 1; + uint32_t exp_low = (fi >> 23) & 0x7f; + uint32_t exp; + + exp = (exp_msb << 10) | exp_low; + if (exp_msb) { + if (exp_low == 0x7f) + exp = 0x7ff; + } else { + if (exp_low != 0x00) + exp |= 0x380; + } + + return (((uint64_t)sign << 63) + | ((uint64_t)exp << 52) + | ((uint64_t)frac << 29)); +} + static inline uint64_t float32_to_s(float32 fa) { CPU_FloatU a; - uint64_t r; - a.f = fa; + return float32_to_s_int(a.l); +} - r = (((uint64_t)(a.l & 0xc0000000)) << 32) | (((uint64_t)(a.l & 0x3fffffff)) << 29); - if (((a.l & 0x7f800000) != 0x7f800000) && (!(a.l & 0x40000000))) - r |= 0x7ll << 59; - return r; +static inline uint32_t s_to_float32_int(uint64_t a) +{ + return ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff); } static inline float32 s_to_float32(uint64_t a) { CPU_FloatU r; - r.l = ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff); + r.l = s_to_float32_int(a); return r.f; } uint32_t helper_s_to_memory (uint64_t a) { - /* Memory format is the same as float32 */ - float32 fa = s_to_float32(a); - return *(uint32_t*)(&fa); + return s_to_float32_int(a); } uint64_t helper_memory_to_s (uint32_t a) { - /* Memory format is the same as float32 */ - return float32_to_s(*(float32*)(&a)); + return float32_to_s_int(a); } uint64_t helper_adds (uint64_t a, uint64_t b)