From patchwork Tue Sep 16 01:53:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konstantin Serebryany X-Patchwork-Id: 389917 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 4860B140142 for ; Tue, 16 Sep 2014 11:55:32 +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:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; q=dns; s=default; b=mpPb EXVpLKtNJvkttZ7EAy3hECTryaIad9CSBfjeqevrfB5+UXAQ7fOHRSXUVui2K6tN djF/DF6WZzORObOhuqVgB1zzwT83NFHYVuf5fzFkeqOYAINoz/cMK0gQldXM8mSo 9jxUfl8CmTKpBDEBKmOzRg7mjWs7H0jo/OA74Mc= 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:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; s=default; bh=O0s6hUU2SA wvYmJ8TJHY4pZDl+s=; b=XI0q+4pmtc4EUc1mOHqctiqpQzWsSk/uGM98Dp6qOG 7Bj75XTKB1hntw+YjqhFSdKenqFRtztAGWvZk+xQ7EHMIvulAhhQemCbPHv+rxNv WhBuPCnh2XJg8jMZ7TeWAjSuAMDbZnYaVMuycuccKWuUAzOiGEx0k9Gq0y1yJIcs E= Received: (qmail 13695 invoked by alias); 16 Sep 2014 01:55:08 -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 12609 invoked by uid 89); 16 Sep 2014 01:53:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-vc0-f182.google.com X-Received: by 10.220.59.138 with SMTP id l10mr5285864vch.59.1410832430831; Mon, 15 Sep 2014 18:53:50 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <87a960l9ze.fsf@igel.home> References: <87a960l9ze.fsf@igel.home> From: Konstantin Serebryany Date: Mon, 15 Sep 2014 18:53:30 -0700 Message-ID: Subject: Re: [PATCH] remove nested function hack_digit To: Andreas Schwab Cc: Roland McGrath , GNU C Library Yep. I've realized that I've interpreted the test results incorrectly (missed the failing tests). The following patch passes tests. On Mon, Sep 15, 2014 at 4:50 PM, Andreas Schwab wrote: > Konstantin Serebryany writes: > >> + if (expsign != 0 && type == 'f' && exponent-- > 0) > >> + fracsize = scalesize; > >> + --fracsize; > >> + fracsize = 1; > >> + frac[fracsize++] = _cy; > > All these side effects won't work any more. > > Andreas. > > -- > Andreas Schwab, schwab@linux-m68k.org > GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 > "And now for something completely different." diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c index 9cd4b4b..679cb70 100644 --- a/stdio-common/printf_fp.c +++ b/stdio-common/printf_fp.c @@ -148,6 +148,49 @@ static wchar_t *group_number (wchar_t *buf, wchar_t *bufend, wchar_t thousands_sep, int ngroups) internal_function; +static wchar_t hack_digit (int expsign, int type, int *exponent, + mp_limb_t *frac, mp_size_t *fracsize, + mp_limb_t *scale, mp_size_t scalesize, + mp_limb_t *tmp) +{ + mp_limb_t hi; + + if (expsign != 0 && type == 'f' && (*exponent)-- > 0) + hi = 0; + else if (scalesize == 0) + { + hi = frac[*fracsize - 1]; + frac[*fracsize - 1] = __mpn_mul_1 (frac, frac, *fracsize - 1, 10); + } + else + { + if (*fracsize < scalesize) + hi = 0; + else + { + hi = mpn_divmod (tmp, frac, *fracsize, scale, scalesize); + tmp[*fracsize - scalesize] = hi; + hi = tmp[0]; + + *fracsize = scalesize; + while (*fracsize != 0 && frac[*fracsize - 1] == 0) + --(*fracsize); + if (*fracsize == 0) + { + /* We're not prepared for an mpn variable with zero + limbs. */ + *fracsize = 1; + return L'0' + hi; + } + } + + mp_limb_t _cy = __mpn_mul_1 (frac, frac, *fracsize, 10); + if (_cy != 0) + frac[(*fracsize)++] = _cy; + } + + return L'0' + hi; +} int ___printf_fp (FILE *fp, @@ -213,50 +256,6 @@ ___printf_fp (FILE *fp, /* Flag whether wbuffer is malloc'ed or not. */ int buffer_malloced = 0; - auto wchar_t hack_digit (void); - - wchar_t hack_digit (void) - { - mp_limb_t hi; - - if (expsign != 0 && type == 'f' && exponent-- > 0) - hi = 0; - else if (scalesize == 0) - { - hi = frac[fracsize - 1]; - frac[fracsize - 1] = __mpn_mul_1 (frac, frac, fracsize - 1, 10); - } - else - { - if (fracsize < scalesize) - hi = 0; - else - { - hi = mpn_divmod (tmp, frac, fracsize, scale, scalesize); - tmp[fracsize - scalesize] = hi; - hi = tmp[0]; - - fracsize = scalesize; - while (fracsize != 0 && frac[fracsize - 1] == 0) - --fracsize; - if (fracsize == 0) - { - /* We're not prepared for an mpn variable with zero - limbs. */ - fracsize = 1; - return L'0' + hi; - } - } - - mp_limb_t _cy = __mpn_mul_1 (frac, frac, fracsize, 10); - if (_cy != 0) - frac[fracsize++] = _cy; - } - - return L'0' + hi; - } - - /* Figure out the decimal point character. */ if (info->extra == 0) { @@ -914,7 +913,8 @@ ___printf_fp (FILE *fp, while (intdig_no < intdig_max) { ++intdig_no; - *wcp++ = hack_digit (); + *wcp++ = hack_digit (expsign, type, &exponent, frac, &fracsize, + scale, scalesize, tmp); } significant = 1; if (info->alt @@ -938,7 +938,8 @@ ___printf_fp (FILE *fp, || (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0))) { ++fracdig_no; - *wcp = hack_digit (); + *wcp = hack_digit (expsign, type, &exponent, frac, &fracsize, + scale, scalesize, tmp); if (*wcp++ != L'0') significant = 1; else if (significant == 0) @@ -951,7 +952,8 @@ ___printf_fp (FILE *fp, /* Do rounding. */ wchar_t last_digit = wcp[-1] != decimalwc ? wcp[-1] : wcp[-2]; - wchar_t next_digit = hack_digit (); + wchar_t next_digit = hack_digit (expsign, type, &exponent, frac, &fracsize, + scale, scalesize, tmp); bool more_bits; if (next_digit != L'0' && next_digit != L'5') more_bits = true;