From patchwork Thu Dec 19 22:00:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 22657 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ve0-f197.google.com (mail-ve0-f197.google.com [209.85.128.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 7E3C123FCA for ; Thu, 19 Dec 2013 22:00:22 +0000 (UTC) Received: by mail-ve0-f197.google.com with SMTP id oz11sf1934583veb.4 for ; Thu, 19 Dec 2013 14:00:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=XxtVLPOta39HNn6VYHU2rrc6TeG6FJoG7dPG1vK/TJs=; b=GGl6Quv7jT5HXWuSdvkugifiyu/YWnwf58SQ97BVuJk+/xiLcx1CqOVP0iS8FUpGnN uHKksgCCmB8K+JWozLRDTQ5Ks/0CifG6OfC6PW3T7z3HRhscYbf3gq0IKiuvv0Sr0DHL Msiu+8YdA71ac5q0sxpcaR98qUuJv5cvODheAhx+NQgkbEf/T1jQunaAP8AZDc0NlkVy oAxy2Y6Xri/O6hqF1kgt/k3GN6vKLCJZVmGC543AgBIA691xGwv05t83LIEoJP3rYjrw npEBG9JZ8FS9GD0DGzb4wvqDFYYeWXsLGCT3FqGWiHhR0WKKwHCeVQHxbNoAzuC8xFU2 TrtA== X-Gm-Message-State: ALoCoQm1lw7EzyWjizNlN1D3s43WB2BuqKwXZNCkGsqIdxAqBgLW18QZS1dqZ00Jp+/u+l8gMhJy X-Received: by 10.58.34.142 with SMTP id z14mr1719401vei.23.1387490421145; Thu, 19 Dec 2013 14:00:21 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.120.164 with SMTP id ld4ls505053qeb.51.gmail; Thu, 19 Dec 2013 14:00:21 -0800 (PST) X-Received: by 10.220.17.131 with SMTP id s3mr282699vca.20.1387490420999; Thu, 19 Dec 2013 14:00:20 -0800 (PST) Received: from mail-vc0-f172.google.com (mail-vc0-f172.google.com [209.85.220.172]) by mx.google.com with ESMTPS id g10si987333vcm.10.2013.12.19.14.00.20 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 19 Dec 2013 14:00:20 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.172 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.172; Received: by mail-vc0-f172.google.com with SMTP id ij19so1025400vcb.3 for ; Thu, 19 Dec 2013 14:00:20 -0800 (PST) X-Received: by 10.221.64.17 with SMTP id xg17mr2695641vcb.5.1387490420887; Thu, 19 Dec 2013 14:00:20 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.59.13.131 with SMTP id ey3csp17145ved; Thu, 19 Dec 2013 14:00:20 -0800 (PST) X-Received: by 10.194.143.100 with SMTP id sd4mr251064wjb.69.1387490419490; Thu, 19 Dec 2013 14:00:19 -0800 (PST) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id bn3si2129996wjc.87.2013.12.19.14.00.19 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 19 Dec 2013 14:00:19 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::1 as permitted sender) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1Vtldi-0004Ar-RZ; Thu, 19 Dec 2013 22:00:18 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Tom Musta Subject: [PATCH] softfloat: Only raise Invalid when conversions to int are out of range Date: Thu, 19 Dec 2013 22:00:18 +0000 Message-Id: <1387490418-16020-1-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.172 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , We implement a number of float-to-integer conversions using conversion to an integer type with a wider range and then a check against the narrower range we are actually converting to. If we find the result to be out of range we correctly raise the Invalid exception, but we must also suppress other exceptions which might have been raised by the conversion function we called. This won't throw away exceptions we should have preserved, because for the 'core' exception flags the IEEE spec mandates that the only valid combinations of exception that can be raised by a single operation are Inexact + Overflow and Inexact + Underflow. For the non-IEEE softfloat flag for input denormals, we can guarantee that that flag won't have been set for out of range float-to-int conversions because a squashed denormal by definition goes to plus or minus zero, which is always in range after conversion to integer zero. This bug has been fixed for some of the float-to-int conversion routines by previous patches; fix it for the remaining functions as well, so that they all restore the pre-conversion status flags prior to raising Invalid. Signed-off-by: Peter Maydell --- NB that I've worded the commit message on the assumption that the patches Tom Musta has written for PPC bugs go in first; as it happens the patches don't actually conflict, though. Some of these fix wrong-exception-flags bugs in 32 bit ARM VCVT. fpu/softfloat.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index dbda61b..253e6b3 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -6432,17 +6432,18 @@ uint32 float32_to_uint32( float32 a STATUS_PARAM ) { int64_t v; uint32 res; + int old_exc_flags = get_float_exception_flags(status); v = float32_to_int64(a STATUS_VAR); if (v < 0) { res = 0; - float_raise( float_flag_invalid STATUS_VAR); } else if (v > 0xffffffff) { res = 0xffffffff; - float_raise( float_flag_invalid STATUS_VAR); } else { - res = v; + return v; } + set_float_exception_flags(old_exc_flags, status); + float_raise(float_flag_invalid STATUS_VAR); return res; } @@ -6450,17 +6451,18 @@ uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM ) { int64_t v; uint32 res; + int old_exc_flags = get_float_exception_flags(status); v = float32_to_int64_round_to_zero(a STATUS_VAR); if (v < 0) { res = 0; - float_raise( float_flag_invalid STATUS_VAR); } else if (v > 0xffffffff) { res = 0xffffffff; - float_raise( float_flag_invalid STATUS_VAR); } else { - res = v; + return v; } + set_float_exception_flags(old_exc_flags, status); + float_raise(float_flag_invalid STATUS_VAR); return res; } @@ -6468,17 +6470,18 @@ uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM) { int64_t v; uint_fast16_t res; + int old_exc_flags = get_float_exception_flags(status); v = float32_to_int64_round_to_zero(a STATUS_VAR); if (v < 0) { res = 0; - float_raise( float_flag_invalid STATUS_VAR); } else if (v > 0xffff) { res = 0xffff; - float_raise( float_flag_invalid STATUS_VAR); } else { - res = v; + return v; } + set_float_exception_flags(old_exc_flags, status); + float_raise(float_flag_invalid STATUS_VAR); return res; } @@ -6522,17 +6525,18 @@ uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM) { int64_t v; uint_fast16_t res; + int old_exc_flags = get_float_exception_flags(status); v = float64_to_int64_round_to_zero(a STATUS_VAR); if (v < 0) { res = 0; - float_raise( float_flag_invalid STATUS_VAR); } else if (v > 0xffff) { res = 0xffff; - float_raise( float_flag_invalid STATUS_VAR); } else { - res = v; + return v; } + set_float_exception_flags(old_exc_flags, status); + float_raise(float_flag_invalid STATUS_VAR); return res; }