From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57803) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1idJ-000077-6l for qemu-devel@nongnu.org; Mon, 30 Jun 2014 16:57:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X1idI-0004mf-Ag for qemu-devel@nongnu.org; Mon, 30 Jun 2014 16:57:01 -0400 Received: from zeniv.linux.org.uk ([2002:c35c:fd02::1]:35088) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1idI-0004eB-39 for qemu-devel@nongnu.org; Mon, 30 Jun 2014 16:57:00 -0400 Date: Mon, 30 Jun 2014 21:56:35 +0100 From: Al Viro Message-ID: <20140630205635.GG18016@ZenIV.linux.org.uk> References: <20140624043423.GX18016@ZenIV.linux.org.uk> <20140624165244.GY18016@ZenIV.linux.org.uk> <53A9C47C.2050002@twiddle.net> <20140624203244.GZ18016@ZenIV.linux.org.uk> <53A9E650.2020709@twiddle.net> <20140624212450.GB18016@ZenIV.linux.org.uk> <53A9EE7E.4020802@twiddle.net> <20140625070117.GD18016@ZenIV.linux.org.uk> <20140626055541.GF18016@ZenIV.linux.org.uk> <53B1AEEF.8010108@twiddle.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <53B1AEEF.8010108@twiddle.net> Sender: Al Viro Subject: Re: [Qemu-devel] [RFC] alpha qemu arithmetic exceptions List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Richard Henderson Cc: qemu-devel@nongnu.org On Mon, Jun 30, 2014 at 11:39:43AM -0700, Richard Henderson wrote: > Looks good. > > I've split it up into a couple of smaller patches, made some sylistic tweaks > and pushed it to > > git://github.com/rth7680/qemu.git axp-next > > I'm starting to do some testing now, but a glance though would be helpful. > Especially to see if I didn't make some silly mistake in the process. The only problem I see at a glance is that CVTTQ should raise IOV|INE in ranges 2^63..2^64-1 and -2^64+1..-2^63-1 as well. That's what this || ((int64_t)(ret-sign) < 0) thing there was about and yes, it does match the behaviour of actual hardware (verified both on EV45 and EV67). FWIW, it might be better to do what float64_to_int64_round_to_zero() is doing - i.e. if (shift >= 0) { if (shift < 64) ret = frac << shift; if (shift < 11 || a == LIT64(0xC3E0000000000000)) exc = 0; } since frac is between 1ULL<<52 and (1ULL<<53)-1, i.e. shift greater than 11 is guaranteed to overflow, shift less than 11 is guaranteed not to and shift exactly 11 won't overflow only in one case - frac == 1ULL<<52, sign = 1 (i.e. when we have -2^63 there). BTW, shift == 63 is interesting - we certainly overflow, but we want the result to be 0 or 2^63 depending on the least significant bit of mantissa, not "always 0". IOW, 0x4720000000000000 should yield IOV|INE, with result being 0 and 0x4720000000000001 - IOV|INE and result 0x8000000000000000. Again, verified on actual hardware; the last patch I posted had been incorrect in the last case (both cases yield 0 with it, same as in mainline qemu). Incremental on top of your branch would be diff --git a/target-alpha/fpu_helper.c b/target-alpha/fpu_helper.c --- a/target-alpha/fpu_helper.c +++ b/target-alpha/fpu_helper.c @@ -722,12 +722,10 @@ static inline uint64_t inline_cvttq(CPUAlphaState *env, uint64_t a, /* In this case the number is so large that we must shift the fraction left. There is no rounding to do. */ exc = float_flag_int_overflow | float_flag_inexact; - if (shift < 63) { - ret = frac << shift; - if ((ret >> shift) == frac) { - exc = 0; - } - } + if (shift < 64) + ret = frac << shift; + if (shift < 11 || a == LIT64( 0xC3E0000000000000)) + exc = 0; } else { uint64_t round;