From patchwork Tue Sep 23 20:41:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 392669 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2A10F140095 for ; Wed, 24 Sep 2014 06:41:36 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; q=dns; s=default; b=ALJgVsqkToc7nE121AnUUUPUtYH7x GDFuN9KpsYvQoNNxN9NXiSoQeWYJUun/9fP/L3rpDiB07SRJKTLO5te0p+x8DvTk Buxz/t+zJebjpoSz95fUV/i6fqid+vXfmH0kXpT8R7yi9bz/XEFoRPzgVIGfkLar xC7y7jJh8mmTDw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; s=default; bh=SDamtgxtmMS5iL1NRHearIT9jPo=; b=HV7 /JXVnTOKNlwUPnW9ehHJYPw3oSbYBfeQDmmoqd8L9aQp+ikQtex1DAIezylNORqK kka1VSXPnH1KF+IudJX/rGo43Ozqas1mS+8bzFAu49oEpn0OCwGi+giazIsi0qlB l1CH3AHAVAYTTUOuPQSJd9ktvqFUHWxRfH/MSLQk= Received: (qmail 19531 invoked by alias); 23 Sep 2014 20:41:30 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 19516 invoked by uid 89); 23 Sep 2014 20:41:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Date: Tue, 23 Sep 2014 20:41:20 +0000 From: "Joseph S. Myers" To: Subject: soft-fp: Support rsigned == 2 in _FP_TO_INT Message-ID: MIME-Version: 1.0 Continuing the addition of soft-fp features in the Linux kernel version, this patch adds _FP_TO_INT support for rsigned == 2 (reduce overflowing results modulo 2^rsize to fit in the destination, used for alpha emulation). (This patch is relative to a tree with , , , , and applied; there are actual dependencies on at least the fourth and fifth of those patches.) The kernel version is buggy; it can left shift by a negative amount when right shifting is required in an overflow case (the kernel version also has other bugs fixed long ago in glibc; at least, spurious exceptions converting to the most negative integer). This version avoids that by handling overflow (other than to 0) for rsigned == 2 along with the normal non-overflow case, which already properly determines the direction in which to shift. Tested for powerpc-nofpu. Some functions get slightly bigger and some get slightly smaller, no doubt as a result of the change to where in the macro "inexact" is raised, but I don't think those changes are significant. Also tested for powerpc-nofpu with the relevant __fix* functions changed to use rsigned == 2 (which is after all just as valid as rsigned == 1 in IEEE terms), including verifying the results and exceptions for various cases of conversions. With these seven patches, the one remaining feature to add for the soft-fp code to have all the features of the kernel version is _FP_TO_INT_ROUND. 2014-09-23 Joseph Myers * soft-fp/op-common.h (_FP_TO_INT): Handle rsigned == 2. diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h index 3deb9b1..cab6fba 100644 --- a/soft-fp/op-common.h +++ b/soft-fp/op-common.h @@ -1390,6 +1390,8 @@ 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending on the sign in such case. + 2: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, + NV is set plus the result is reduced modulo 2^rsize. -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending on the sign in such case. */ @@ -1411,10 +1413,28 @@ else \ FP_SET_EXCEPTION (FP_EX_INEXACT); \ } \ - else if (X##_e >= (_FP_EXPMAX_##fs < _FP_EXPBIAS_##fs + rsize \ - ? _FP_EXPMAX_##fs \ - : _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s)) \ - || (!rsigned && X##_s)) \ + else if (rsigned == 2 \ + && (X##_e \ + >= ((_FP_EXPMAX_##fs \ + < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + rsize - 1) \ + ? _FP_EXPMAX_##fs \ + : _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + rsize - 1))) \ + { \ + /* Overflow resulting in 0. */ \ + r = 0; \ + FP_SET_EXCEPTION (FP_EX_INVALID \ + | FP_EX_INVALID_CVI \ + | ((FP_EX_INVALID_SNAN \ + && _FP_ISSIGNAN (fs, wc, X)) \ + ? FP_EX_INVALID_SNAN \ + : 0)); \ + } \ + else if (rsigned != 2 \ + && (X##_e >= (_FP_EXPMAX_##fs < _FP_EXPBIAS_##fs + rsize \ + ? _FP_EXPMAX_##fs \ + : (_FP_EXPBIAS_##fs + rsize \ + - (rsigned > 0 || X##_s))) \ + || (!rsigned && X##_s))) \ { \ /* Overflow or converting to the most negative integer. */ \ if (rsigned) \ @@ -1461,6 +1481,7 @@ } \ else \ { \ + int _FP_TO_INT_inexact = 0; \ _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs; \ if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ { \ @@ -1469,17 +1490,27 @@ } \ else \ { \ - int _FP_TO_INT_inexact; \ _FP_FRAC_SRST_##wc (X, _FP_TO_INT_inexact, \ (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ - X##_e), \ _FP_FRACBITS_##fs); \ - if (_FP_TO_INT_inexact) \ - FP_SET_EXCEPTION (FP_EX_INEXACT); \ _FP_FRAC_ASSEMBLE_##wc (r, X, rsize); \ } \ if (rsigned && X##_s) \ r = -r; \ + if (rsigned == 2 && X##_e >= _FP_EXPBIAS_##fs + rsize - 1) \ + { \ + /* Overflow or converting to the most negative integer. */ \ + if (X##_e > _FP_EXPBIAS_##fs + rsize - 1 \ + || !X##_s \ + || r != (((typeof (r)) 1) << (rsize - 1))) \ + { \ + _FP_TO_INT_inexact = 0; \ + FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); \ + } \ + } \ + if (_FP_TO_INT_inexact) \ + FP_SET_EXCEPTION (FP_EX_INEXACT); \ } \ } \ while (0)