From patchwork Mon Aug 7 18:47:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 132318 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1642255vqr; Mon, 7 Aug 2023 11:48:50 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF7Z56qGeGtV4AVi1wrYYxwxIzK8GuewFGGaWLtCiy8IwphHek1JvTMcdNKHlR5KQyt7L4i X-Received: by 2002:a17:907:2cce:b0:99c:6312:73ca with SMTP id hg14-20020a1709072cce00b0099c631273camr8476072ejc.71.1691434130187; Mon, 07 Aug 2023 11:48:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691434130; cv=none; d=google.com; s=arc-20160816; b=GfQb0twBGvk1+CuPVF+2KxxmwIq4ws6WR0xfTp9kbWI8q58n3zM+PjrnQeFhBVg5sz 9r0/5m523YDkc6rWlwVeGNhbhQGoFKpVYq2wy1CnAiZ0qi4sa7nKmZK7rvFTPWpsLQDL OfZZXUa5qj7rj/uL3cRVX4xiVFsGzoUmBkHl/RWOXNpYOp3XbgUBsAFTHnAp5Z/6Hf5B 4jn9X5r8sghOKeFTMSNIpR9ZJtq7qLEIYerDUhTJHvNoF1khYOylA7RbXJC5MlGW2Vxe k7ENKzUHpZby/+TG6PhBztHUoUnhZ3J3YwTDJjEP7zSMTEOZI5KRbl+6Wl6cWOOXxZNf gs0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-disposition:mime-version:message-id:subject:cc:to:date :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=HgrQEanS/1nU18tyBYCjaJt5plFiDYokjlTVN7O/vBw=; fh=aeZHQn/lA9+KGzRlDhL1qO9SE/pAMSdkbwH21Dg0FsA=; b=jCvENCJrYNCvOuZC/7qfcIbWyTcunepVfkLPUYkwChxbtw36mcat+oYBEAWAia81Wt 5v3/uoZCqTrS5BFirgJKo6Qbyt33rIHPmoPdGyvpnkO3cim7EDGgiwCg7tvLIpia4wVJ SCFdzT16a/Ga8+ilrZYhOFr4t//7it7jczjf+66+hu7/WxbEZpdqFMBf1UGu0Y4bfDBy BxgpVQP6fnSsZ6aAKGVu/ffnHt739jnK1CxMDckZkjEh+zIGSC00l9A+7jO4zhq0ZVY0 2gwUA6topgIs9EHlCGgcaQheYznYnh6QjBq8n77/XKQozc5JOj/m5BiZod0q+MS3mvoF rSzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=l5zKTVbc; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id ke10-20020a17090798ea00b00986432cf57csi576898ejc.942.2023.08.07.11.48.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Aug 2023 11:48:50 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=l5zKTVbc; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9C8FD3858434 for ; Mon, 7 Aug 2023 18:48:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9C8FD3858434 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1691434128; bh=HgrQEanS/1nU18tyBYCjaJt5plFiDYokjlTVN7O/vBw=; h=Date:To:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=l5zKTVbcZ0/qDryx1P+laerzzz/55Cy/sZmuAQiCBUPqgL91mS3sSTop/wVdWjL1A tXBL6KO9ClwFWOntsFhv9f5MfFuc/wmFEoNNRuEPIgkBCG0LaBgRntYRbM91yKkRz6 wNJXjrJPYuDg4BfRixROadwyEgFDfrH7fcGflNHU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id B696C3858D37 for ; Mon, 7 Aug 2023 18:47:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B696C3858D37 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-308-iC9PlGemPtKLmqHCjDbeEA-1; Mon, 07 Aug 2023 14:47:53 -0400 X-MC-Unique: iC9PlGemPtKLmqHCjDbeEA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C62D31021E14; Mon, 7 Aug 2023 18:47:52 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.224.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 51FADC15BAE; Mon, 7 Aug 2023 18:47:49 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 377IliYB3655298 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 7 Aug 2023 20:47:45 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 377Ilc1w3655293; Mon, 7 Aug 2023 20:47:38 +0200 Date: Mon, 7 Aug 2023 20:47:37 +0200 To: "Joseph S. Myers" Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] _BitInt to _Decimal* conversion support [PR102989] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_LOTSOFHASH, KAM_SHORT, PDS_BTC_ID, PDS_BTC_MSGID, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773597234544855421 X-GMAIL-MSGID: 1773597234544855421 Hi! The following patch on top of the _Decimal* to _BitInt conversion support patch (and obviously the _BitInt patch series) implements the _BitInt to _Decimal{32,64,128} conversions. These functions do at most two divisions, one possibly by very large power of 10 for which the code just checks if the remainder is 0 or non-zero and where the exponent is just guessed from the input actual minumum bit precision (with a guarantee that if we do the first large division, there will be second one), and then one final on by 10^1 to 10^6 (perhaps smaller for _Decimal{32,128}) which ensures the result is in between 10^{6,15,33} and (10^{7,16,34})-1. For this division we then incorporate the inexact flag from the first division if any and check if with that the remainder is 0, half of the second divisor, smaller than that or larger than that. To make the code independent between libbid in libgcc and the __bid_* support in libdfp and not having to figure out how to get at the rounding mode, the code actually if the result isn't exact performs an addition of the non-rounded value, XXXXXXXXXe+expD{F,D,L} + {4,5,6}e+(exp-1)D{F,D,L}. Similarly, for overflow to infinity it performs addition of two very large (same) numbers (but with single non-0 digit in mantissa such that inexact isn't the case). Will work tomorrow on the runtime gcc.dg/atomic/ testcase and then try to rework the series based on Richi's review. 2023-08-07 Jakub Jelinek PR c/102989 gcc/ * gimple-lower-bitint.cc (bitint_large_huge::lower_float_conv_stmt): Handle _BitInt to _Decimal* conversions. * internal-fn.cc (expand_BITINTTOFLOAT): Likewise. gcc/testsuite/ * gcc.dg/dfp/bitint-4.c: New test. * gcc.dg/dfp/bitint-5.c: New test. * gcc.dg/dfp/bitint-6.c: New test. libgcc/ * config/t-softfp (softfp_bid_list): Add floatbitint{s,d,t}d. * soft-fp/floatbitintsd.c: New file. * soft-fp/floatbitintdd.c: New file. * soft-fp/floatbitinttd.c: New file. Jakub --- gcc/gimple-lower-bitint.cc.jj 2023-08-04 09:40:14.271005211 +0200 +++ gcc/gimple-lower-bitint.cc 2023-08-05 19:14:04.125034849 +0200 @@ -3363,23 +3363,6 @@ bitint_large_huge::lower_float_conv_stmt tree rhs1 = gimple_assign_rhs1 (stmt); tree lhs = gimple_assign_lhs (stmt); tree_code rhs_code = gimple_assign_rhs_code (stmt); - if (DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (lhs)))) - { - sorry_at (gimple_location (stmt), - "unsupported conversion between %<_BitInt(%d)%> and %qT", - rhs_code == FIX_TRUNC_EXPR - ? TYPE_PRECISION (TREE_TYPE (lhs)) - : TYPE_PRECISION (TREE_TYPE (rhs1)), - rhs_code == FIX_TRUNC_EXPR - ? TREE_TYPE (rhs1) : TREE_TYPE (lhs)); - if (rhs_code == FLOAT_EXPR) - { - gimple *g - = gimple_build_assign (lhs, build_zero_cst (TREE_TYPE (lhs))); - gsi_replace (&m_gsi, g, true); - } - return; - } tree sitype = lang_hooks.types.type_for_mode (SImode, 0); gimple *g; if (rhs_code == FIX_TRUNC_EXPR) --- gcc/internal-fn.cc.jj 2023-08-04 09:47:58.368480546 +0200 +++ gcc/internal-fn.cc 2023-08-05 19:15:24.477915179 +0200 @@ -4885,11 +4885,25 @@ expand_BITINTTOFLOAT (internal_fn, gcall const char *mname = GET_MODE_NAME (mode); unsigned mname_len = strlen (mname); int len = 14 + mname_len; + if (DECIMAL_FLOAT_MODE_P (mode)) + len += 4; char *libfunc_name = XALLOCAVEC (char, len); char *p = libfunc_name; const char *q; - memcpy (p, "__floatbitint", 13); - p += 13; + if (DECIMAL_FLOAT_MODE_P (mode)) + { +#if ENABLE_DECIMAL_BID_FORMAT + memcpy (p, "__bid_floatbitint", 17); +#else + memcpy (p, "__dpd_floatbitint", 17); +#endif + p += 17; + } + else + { + memcpy (p, "__floatbitint", 13); + p += 13; + } for (q = mname; *q; q++) *p++ = TOLOWER (*q); *p = '\0'; --- gcc/testsuite/gcc.dg/dfp/bitint-4.c.jj 2023-08-05 20:08:13.819721742 +0200 +++ gcc/testsuite/gcc.dg/dfp/bitint-4.c 2023-08-07 12:02:12.530386424 +0200 @@ -0,0 +1,156 @@ +/* PR c/102989 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2 -std=c2x -pedantic-errors" } */ + +#if __BITINT_MAXWIDTH__ >= 192 +__attribute__((noipa)) _Decimal64 +tests192 (_BitInt(192) b) +{ + return b; +} + +__attribute__((noipa)) _Decimal64 +testu192 (unsigned _BitInt(192) b) +{ + return b; +} +#endif + +#if __BITINT_MAXWIDTH__ >= 575 +__attribute__((noipa)) _Decimal64 +tests575 (_BitInt(575) b) +{ + return b; +} + +__attribute__((noipa)) _Decimal64 +testu575 (unsigned _BitInt(575) b) +{ + return b; +} +#endif + +int +main () +{ + _Decimal64 a, b; +#define CHECK(x, y) (a = (x), b = (y), a != (y) || __builtin_memcmp (&a, &b, sizeof (a))) +#if __BITINT_MAXWIDTH__ >= 192 + if (CHECK (tests192 (0wb), 0.DD) + || CHECK (tests192 (7wb), 7.DD) + || CHECK (tests192 (-42wb), -42.DD) + || CHECK (tests192 (-777777777wb), -777777777.DD) + || CHECK (tests192 (9999999999999000wb), 9999999999999000.DD) + || CHECK (tests192 (-9999999999999999wb), -9999999999999999.DD) + || CHECK (tests192 (-99999999999999994wb), -9999999999999999.e+1DD) + || CHECK (tests192 (99999999999999995wb), 1000000000000000.e+2DD) + || CHECK (tests192 (999999999999999900wb), 9999999999999999.e+2DD) + || CHECK (tests192 (999999999999999949wb), 9999999999999999.e+2DD) + || CHECK (tests192 (-9999999999999999000wb), -9999999999999999.e+3DD) + || CHECK (tests192 (9999999999999999499wb), 9999999999999999.e+3DD) + || CHECK (tests192 (999999999999999900000wb), 9999999999999999.e+5DD) + || CHECK (tests192 (999999999999999949999wb), 9999999999999999.e+5DD) + || CHECK (tests192 (-9999999999999999000000wb), -9999999999999999.e+6DD) + || CHECK (tests192 (-9999999999999999499999wb), -9999999999999999.e+6DD) + || CHECK (tests192 (123456789012345600000000wb), 1234567890123456.e+8DD) + || CHECK (tests192 (34242319854454290000000000000000000000wb), 3424231985445429e+22DD) + || CHECK (tests192 (999999999999999900000000000000000000000000000000wb), 9999999999999999.e+32DD) + || CHECK (tests192 (999999999999999949999999999999999999999999999999wb), 9999999999999999.e+32DD) + || CHECK (tests192 (-999999999999999900000000000000000000000000000000000000000wb), -9999999999999999.e+41DD) + || CHECK (tests192 (-2138550877694459000000000000000000000000000000000000000000wb), -2138550877694459e+42DD) + || CHECK (tests192 (-2138550877694459500000000000000000000000000000000000000000wb), -2138550877694460e+42DD) + || CHECK (tests192 (-2138550877694459499999999999999999999999999999999999999999wb), -2138550877694459e+42DD) + || CHECK (tests192 (-2138550877694459999999999999999999999999999999999999999999wb), -2138550877694460e+42DD) + || CHECK (tests192 (-2138550877694458000000000000000000000000000000000000000000wb), -2138550877694458e+42DD) + || CHECK (tests192 (-2138550877694458500000000000000000000000000000000000000000wb), -2138550877694458e+42DD) + || CHECK (tests192 (-2138550877694458500000000000000000000000000000000000000001wb), -2138550877694459e+42DD) + || CHECK (tests192 (3138550867693340000000000000000000000000000000000000000000wb), 3138550867693340e+42DD) + || CHECK (tests192 (3138550867693340381917894711603833208051177722232017256447wb), 3138550867693340e+42DD) + || CHECK (tests192 (-3138550867693340000000000000000000000000000000000000000000wb), -3138550867693340e+42DD) + || CHECK (tests192 (-3138550867693340381917894711603833208051177722232017256447wb - 1wb), -3138550867693340e+42DD)) + __builtin_abort (); + if (CHECK (testu192 (0uwb), 0.DD) + || CHECK (testu192 (7uwb), 7.DD) + || CHECK (testu192 (42uwb), 42.DD) + || CHECK (testu192 (777777777uwb), 777777777.DD) + || CHECK (testu192 (9999999999999000uwb), 9999999999999000.DD) + || CHECK (testu192 (999999999999999900uwb), 9999999999999999.e+2DD) + || CHECK (testu192 (9999999999999999000uwb), 9999999999999999.e+3DD) + || CHECK (testu192 (99999999999999994999uwb), 9999999999999999.e+4DD) + || CHECK (testu192 (999999999999999900000uwb), 9999999999999999.e+5DD) + || CHECK (testu192 (9999999999999999000000uwb), 9999999999999999.e+6DD) + || CHECK (testu192 (123456789012345600000000uwb), 1234567890123456.e+8DD) + || CHECK (testu192 (34242319854454290000000000000000000000uwb), 3424231985445429e+22DD) + || CHECK (testu192 (9999999999999999000000000000000000000000000000000uwb), 9999999999999999.e+33DD) + || CHECK (testu192 (618935436546517900000000000000000000000000000000000000uwb), 6189354365465179e+38DD) + || CHECK (testu192 (618935436546517950000000000000000000000000000000000000uwb), 6189354365465180e+38DD) + || CHECK (testu192 (618935436546517949999999999999999999999999999999999999uwb), 6189354365465179e+38DD) + || CHECK (testu192 (618935436546517999999999999999999999999999999999999999uwb), 6189354365465180e+38DD) + || CHECK (testu192 (618935436546517800000000000000000000000000000000000000uwb), 6189354365465178e+38DD) + || CHECK (testu192 (618935436546517850000000000000000000000000000000000000uwb), 6189354365465178e+38DD) + || CHECK (testu192 (618935436546517850000000000000000000000000000000000001uwb), 6189354365465179e+38DD) + || CHECK (testu192 (99999999999999990000000000000000000000000000000000000000uwb), 9999999999999999.e+40DD) + || CHECK (testu192 (6277101735386680000000000000000000000000000000000000000000uwb), 6277101735386680e+42DD) + || CHECK (testu192 (6277101735386680499999999999999999999999999999999999999999uwb), 6277101735386680e+42DD) + || CHECK (testu192 (6277101735386680500000000000000000000000000000000000000000uwb), 6277101735386680e+42DD) + || CHECK (testu192 (6277101735386680500000000000000000000000000000000000000001uwb), 6277101735386681e+42DD) + || CHECK (testu192 (6277101735386680500000000000000000000010000000000000000000uwb), 6277101735386681e+42DD) + || CHECK (testu192 (6277101735386680763835789423207666416102355444464034512895uwb), 6277101735386681e+42DD)) + __builtin_abort (); +#endif +#if __BITINT_MAXWIDTH__ >= 575 + if (CHECK (tests575 (0wb), 0.DD) + || CHECK (tests575 (7wb), 7.DD) + || CHECK (tests575 (-42wb), -42.DD) + || CHECK (tests575 (-444444444wb), -444444444.DD) + || CHECK (tests575 (9999999999999000wb), 9999999999999000.DD) + || CHECK (tests575 (-9999999999999999wb), -9999999999999999.DD) + || CHECK (tests575 (999999999999999900wb), 9999999999999999.e+2DD) + || CHECK (tests575 (-9999999999999999000wb), -9999999999999999.e+3DD) + || CHECK (tests575 (999999999999999900000wb), 9999999999999999.e+5DD) + || CHECK (tests575 (-99999999999999990000000wb), -9999999999999999.e+7DD) + || CHECK (tests575 (1234567890123456000000000wb), 1234567890123456.e+9DD) + || CHECK (tests575 (3424231985445429000000000000000000000000wb), 3424231985445429e+24DD) + || CHECK (tests575 (99999999999999990000000000000000000000000000000000000000wb), 9999999999999999.e+40DD) + || CHECK (tests575 (-9999999999999999000000000000000000000000000000000000000000000000000000000000000wb), -9999999999999999.e+63DD) + || CHECK (tests575 (-213855087769445900000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138550877694459e+86DD) + || CHECK (tests575 (-213855087769445950000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138550877694460e+86DD) + || CHECK (tests575 (-213855087769445949999999999999999999999999999999999999999999999999999999999999999999999999999999999999wb), -2138550877694459e+86DD) + || CHECK (tests575 (-213855087769445999999999999999999999999999999999999999999999999999999999999999999999999999999999999999wb), -2138550877694460e+86DD) + || CHECK (tests575 (-213855087769445800000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138550877694458e+86DD) + || CHECK (tests575 (-213855087769445850000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138550877694458e+86DD) + || CHECK (tests575 (-213855087769445850000000000000000000000000000000000000000000000000000000000000000000000000000000000001wb), -2138550877694459e+86DD) + || CHECK (tests575 (61832600368276130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), 6183260036827613e+157DD) + || CHECK (tests575 (61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb), 6183260036827613e+157DD) + || CHECK (tests575 (-61832600368276130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -6183260036827613e+157DD) + || CHECK (tests575 (-61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb - 1wb), -6183260036827613e+157DD)) + __builtin_abort (); + if (CHECK (testu575 (0uwb), 0.DD) + || CHECK (testu575 (17uwb), 17.DD) + || CHECK (testu575 (420uwb), 420.DD) + || CHECK (testu575 (888888888uwb), 888888888.DD) + || CHECK (testu575 (9999999999999000uwb), 9999999999999000.DD) + || CHECK (testu575 (99999999999999990000000uwb), 9999999999999999.e+7DD) + || CHECK (testu575 (9999999999999999000000000uwb), 9999999999999999.e+9DD) + || CHECK (testu575 (99999999999999990000000000000uwb), 9999999999999999.e+13DD) + || CHECK (testu575 (9999999999999999000000000000000uwb), 9999999999999999.e+15DD) + || CHECK (testu575 (1234567890123456000000000000000000uwb), 1234567890123456.e+18DD) + || CHECK (testu575 (34242319854454290000000000000000000000uwb), 3424231985445429e+22DD) + || CHECK (testu575 (9999999999999999000000000000000000000000000000000uwb), 9999999999999999.e+33DD) + || CHECK (testu575 (618935436546517900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189354365465179e+104DD) + || CHECK (testu575 (618935436546517950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189354365465180e+104DD) + || CHECK (testu575 (618935436546517949999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999uwb), 6189354365465179e+104DD) + || CHECK (testu575 (618935436546517999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999uwb), 6189354365465180e+104DD) + || CHECK (testu575 (618935436546517800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189354365465178e+104DD) + || CHECK (testu575 (618935436546517850000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189354365465178e+104DD) + || CHECK (testu575 (618935436546517850000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001uwb), 6189354365465179e+104DD) + || CHECK (testu575 (99999999999999990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 9999999999999999.e+139DD) + || CHECK (testu575 (123665200736552200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 1236652007365522e+158DD) + || CHECK (testu575 (123665200736552249999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999uwb), 1236652007365522e+158DD) + || CHECK (testu575 (123665200736552250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 1236652007365522e+158DD) + || CHECK (testu575 (123665200736552250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001uwb), 1236652007365523e+158DD) + || CHECK (testu575 (123665200736552250000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 1236652007365523e+158DD) + || CHECK (testu575 (123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb), 1236652007365523e+158DD)) + __builtin_abort (); +#endif +} --- gcc/testsuite/gcc.dg/dfp/bitint-5.c.jj 2023-08-07 11:58:06.746843874 +0200 +++ gcc/testsuite/gcc.dg/dfp/bitint-5.c 2023-08-07 11:58:29.703520940 +0200 @@ -0,0 +1,159 @@ +/* PR c/102989 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2 -std=c2x -pedantic-errors" } */ + +#if __BITINT_MAXWIDTH__ >= 192 +__attribute__((noipa)) _Decimal32 +tests192 (_BitInt(192) b) +{ + return b; +} + +__attribute__((noipa)) _Decimal32 +testu192 (unsigned _BitInt(192) b) +{ + return b; +} +#endif + +#if __BITINT_MAXWIDTH__ >= 575 +__attribute__((noipa)) _Decimal32 +tests575 (_BitInt(575) b) +{ + return b; +} + +__attribute__((noipa)) _Decimal32 +testu575 (unsigned _BitInt(575) b) +{ + return b; +} +#endif + +int +main () +{ + _Decimal32 a, b; +#define CHECK(x, y) (a = (x), b = (y), a != (y) || __builtin_memcmp (&a, &b, sizeof (a))) +#if __BITINT_MAXWIDTH__ >= 192 + if (CHECK (tests192 (0wb), 0.DF) + || CHECK (tests192 (7wb), 7.DF) + || CHECK (tests192 (-42wb), -42.DF) + || CHECK (tests192 (-777777wb), -777777.DF) + || CHECK (tests192 (9999000wb), 9999000.DF) + || CHECK (tests192 (-9999999wb), -9999999.DF) + || CHECK (tests192 (99999994wb), 9999999.e+1DF) + || CHECK (tests192 (99999995wb), 1000000.e+2DF) + || CHECK (tests192 (999999900wb), 9999999.e+2DF) + || CHECK (tests192 (-9999999000wb), -9999999.e+3DF) + || CHECK (tests192 (999999900000wb), 9999999.e+5DF) + || CHECK (tests192 (-9999999000000wb), -9999999.e+6DF) + || CHECK (tests192 (123456700000000000wb), 1234567.e+11DF) + || CHECK (tests192 (34242310000000000000000000000wb), 3424231e+22DF) + || CHECK (tests192 (999999900000000000000000000000000000000wb), 9999999.e+32DF) + || CHECK (tests192 (-999999900000000000000000000000000000000000000000wb), -9999999.e+41DF) + || CHECK (tests192 (-2138551000000000000000000000000000000000000000000000000000wb), -2138551e+51DF) + || CHECK (tests192 (-2138551500000000000000000000000000000000000000000000000000wb), -2138552e+51DF) + || CHECK (tests192 (-2138551499999999999999999999999999999999999999999999999999wb), -2138551e+51DF) + || CHECK (tests192 (-2138551999999999999999999999999999999999999999999999999999wb), -2138552e+51DF) + || CHECK (tests192 (-2138552000000000000000000000000000000000000000000000000000wb), -2138552e+51DF) + || CHECK (tests192 (-2138552500000000000000000000000000000000000000000000000000wb), -2138552e+51DF) + || CHECK (tests192 (-2138552500000000000000000000000000000000000000000000000001wb), -2138553e+51DF) + || CHECK (tests192 (3138550000000000000000000000000000000000000000000000000000wb), 3138550e+51DF) + || CHECK (tests192 (3138550867693340381917894711603833208051177722232017256447wb), 3138551e+51DF) + || CHECK (tests192 (-3138550000000000000000000000000000000000000000000000000000wb), -3138550e+51DF) + || CHECK (tests192 (-3138550867693340381917894711603833208051177722232017256447wb - 1wb), -3138551e+51DF)) + __builtin_abort (); + if (CHECK (testu192 (0uwb), 0.DF) + || CHECK (testu192 (7uwb), 7.DF) + || CHECK (testu192 (42uwb), 42.DF) + || CHECK (testu192 (77777uwb), 77777.DF) + || CHECK (testu192 (9999000uwb), 9999000.DF) + || CHECK (testu192 (999999900uwb), 9999999.e+2DF) + || CHECK (testu192 (999999949uwb), 9999999.e+2DF) + || CHECK (testu192 (9999999000uwb), 9999999.e+3DF) + || CHECK (testu192 (9999999499uwb), 9999999.e+3DF) + || CHECK (testu192 (999999900000uwb), 9999999.e+5DF) + || CHECK (testu192 (9999999000000uwb), 9999999.e+6DF) + || CHECK (testu192 (123456700000000uwb), 1234567.e+8DF) + || CHECK (testu192 (34242310000000000000000000000uwb), 3424231e+22DF) + || CHECK (testu192 (9999999000000000000000000000000000000000uwb), 9999999.e+33DF) + || CHECK (testu192 (61893590000000000000000000000000000000000000000000000uwb), 6189359e+46DF) + || CHECK (testu192 (61893595000000000000000000000000000000000000000000000uwb), 6189360e+46DF) + || CHECK (testu192 (61893594999999999999999999999999999999999999999999999uwb), 6189359e+46DF) + || CHECK (testu192 (61893599999999999999999999999999999999999999999999999uwb), 6189360e+46DF) + || CHECK (testu192 (61893580000000000000000000000000000000000000000000000uwb), 6189358e+46DF) + || CHECK (testu192 (61893585000000000000000000000000000000000000000000000uwb), 6189358e+46DF) + || CHECK (testu192 (61893585000000000000000000000000000000000000000000001uwb), 6189359e+46DF) + || CHECK (testu192 (999999900000000000000000000000000000000000000000000000uwb), 9999999.e+47DF) + || CHECK (testu192 (6277100500000000000000000000000000000000000000000000000000uwb), 6277100e+51DF) + || CHECK (testu192 (6277100500000000000000000000000000000000000000000000000001uwb), 6277101e+51DF) + || CHECK (testu192 (6277100500000000000000000000000000000010000000000000000000uwb), 6277101e+51DF) + || CHECK (testu192 (6277101000000000000000000000000000000000000000000000000000uwb), 6277101e+51DF) + || CHECK (testu192 (6277101499999999999999999999999999999999999999999999999999uwb), 6277101e+51DF) + || CHECK (testu192 (6277101500000000000000000000000000000000000000000000000000uwb), 6277102e+51DF) + || CHECK (testu192 (6277101735386680763835789423207666416102355444464034512895uwb), 6277102e+51DF)) + __builtin_abort (); +#endif +#if __BITINT_MAXWIDTH__ >= 575 + if (CHECK (tests575 (0wb), 0.DF) + || CHECK (tests575 (7wb), 7.DF) + || CHECK (tests575 (-42wb), -42.DF) + || CHECK (tests575 (-44444wb), -44444.DF) + || CHECK (tests575 (9999000wb), 9999000.DF) + || CHECK (tests575 (-9999999wb), -9999999.DF) + || CHECK (tests575 (999999900wb), 9999999.e+2DF) + || CHECK (tests575 (-9999999000wb), -9999999.e+3DF) + || CHECK (tests575 (999999900000wb), 9999999.e+5DF) + || CHECK (tests575 (999999949999wb), 9999999.e+5DF) + || CHECK (tests575 (-99999990000000wb), -9999999.e+7DF) + || CHECK (tests575 (1234567000000000000000000wb), 1234567.e+18DF) + || CHECK (tests575 (3424231000000000000000000000000000000000wb), 3424231e+33DF) + || CHECK (tests575 (99999990000000000000000000000000000000000000000wb), 9999999.e+40DF) + || CHECK (tests575 (-9999999000000000000000000000000000000000000000000000000000000000000000wb), -9999999.e+63DF) + || CHECK (tests575 (-2138559000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138559e+90DF) + || CHECK (tests575 (-2138559500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138560e+90DF) + || CHECK (tests575 (-2138559499999999999999999999999999999999999999999999999999999999999999999999999999999999999999999wb), -2138559e+90DF) + || CHECK (tests575 (-2138559999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999wb), -2138560e+90DF) + || CHECK (tests575 (-2138558000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138558e+90DF) + || CHECK (tests575 (-2138558500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138558e+90DF) + || CHECK (tests575 (-2138558500000000000000000000000000000000000000000000000000000000000000000000000000000000000000001wb), -2138559e+90DF) + || CHECK (tests575 (9999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), 9999999e+90DF) + || CHECK (tests575 (9999999499999999999999999999999999999999999999999999999999999999999999999999999999999999999999999wb), 9999999e+90DF) + || CHECK (tests575 (9999999500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), __builtin_infd32 ()) + || CHECK (tests575 (-9999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -9999999e+90DF) + || CHECK (tests575 (-9999999499999999999999999999999999999999999999999999999999999999999999999999999999999999999999999wb), -9999999e+90DF) + || CHECK (tests575 (-9999999500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -__builtin_infd32 ()) + || CHECK (tests575 (61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb), __builtin_infd32 ()) + || CHECK (tests575 (-61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb - 1wb), -__builtin_infd32 ())) + __builtin_abort (); + if (CHECK (testu575 (0uwb), 0.DF) + || CHECK (testu575 (17uwb), 17.DF) + || CHECK (testu575 (420uwb), 420.DF) + || CHECK (testu575 (888uwb), 888.DF) + || CHECK (testu575 (9999000uwb), 9999000.DF) + || CHECK (testu575 (99999990000000uwb), 9999999.e+7DF) + || CHECK (testu575 (99999994999999uwb), 9999999.e+7DF) + || CHECK (testu575 (9999999000000000uwb), 9999999.e+9DF) + || CHECK (testu575 (9999999499999999uwb), 9999999.e+9DF) + || CHECK (testu575 (99999990000000000000uwb), 9999999.e+13DF) + || CHECK (testu575 (99999994999999999999uwb), 9999999.e+13DF) + || CHECK (testu575 (9999999000000000000000uwb), 9999999.e+15DF) + || CHECK (testu575 (9999999499999999999999uwb), 9999999.e+15DF) + || CHECK (testu575 (1234567000000000000000000uwb), 1234567.e+18DF) + || CHECK (testu575 (34242310000000000000000000000uwb), 3424231e+22DF) + || CHECK (testu575 (9999999000000000000000000000000000000000uwb), 9999999.e+33DF) + || CHECK (testu575 (61893590000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189359e+88DF) + || CHECK (testu575 (61893595000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189360e+88DF) + || CHECK (testu575 (61893594999999999999999999999999999999999999999999999999999999999999999999999999999999999999999uwb), 6189359e+88DF) + || CHECK (testu575 (61893599999999999999999999999999999999999999999999999999999999999999999999999999999999999999999uwb), 6189360e+88DF) + || CHECK (testu575 (61893580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189358e+88DF) + || CHECK (testu575 (61893585000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189358e+88DF) + || CHECK (testu575 (61893585000000000000000000000000000000000000000000000000000000000000000000000000000000000000001uwb), 6189359e+88DF) + || CHECK (testu575 (9999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 9999999.e+90DF) + || CHECK (tests575 (9999999499999999999999999999999999999999999999999999999999999999999999999999999999999999999999999uwb), 9999999e+90DF) + || CHECK (tests575 (9999999500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), __builtin_infd32 ()) + || CHECK (testu575 (123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb), __builtin_infd32 ())) + __builtin_abort (); +#endif +} --- gcc/testsuite/gcc.dg/dfp/bitint-6.c.jj 2023-08-07 17:58:14.588521246 +0200 +++ gcc/testsuite/gcc.dg/dfp/bitint-6.c 2023-08-07 17:57:32.271115340 +0200 @@ -0,0 +1,156 @@ +/* PR c/102989 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2 -std=c2x -pedantic-errors" } */ + +#if __BITINT_MAXWIDTH__ >= 192 +__attribute__((noipa)) _Decimal128 +tests192 (_BitInt(192) b) +{ + return b; +} + +__attribute__((noipa)) _Decimal128 +testu192 (unsigned _BitInt(192) b) +{ + return b; +} +#endif + +#if __BITINT_MAXWIDTH__ >= 575 +__attribute__((noipa)) _Decimal128 +tests575 (_BitInt(575) b) +{ + return b; +} + +__attribute__((noipa)) _Decimal128 +testu575 (unsigned _BitInt(575) b) +{ + return b; +} +#endif + +int +main () +{ + _Decimal128 a, b; +#define CHECK(x, y) (a = (x), b = (y), a != (y) || __builtin_memcmp (&a, &b, sizeof (a))) +#if __BITINT_MAXWIDTH__ >= 192 + if (CHECK (tests192 (0wb), 0.DL) + || CHECK (tests192 (7wb), 7.DL) + || CHECK (tests192 (-42wb), -42.DL) + || CHECK (tests192 (-777777777wb), -777777777.DL) + || CHECK (tests192 (-12345678912345wb), -12345678912345.DL) + || CHECK (tests192 (123456789123456789wb), 123456789123456789.DL) + || CHECK (tests192 (777777777777777777777777777wb), 777777777777777777777777777.DL) + || CHECK (tests192 (9999999999999999999999999900000000wb), 9999999999999999999999999900000000.DL) + || CHECK (tests192 (-9999999999999999999999999999999999wb), -9999999999999999999999999999999999.DL) + || CHECK (tests192 (-99999999999999999999999999999999994wb), -9999999999999999999999999999999999.e+1DL) + || CHECK (tests192 (99999999999999999999999999999999995wb), 1000000000000000000000000000000000.e+2DL) + || CHECK (tests192 (999999999999999999999999999999999900wb), 9999999999999999999999999999999999.e+2DL) + || CHECK (tests192 (999999999999999999999999999999999949wb), 9999999999999999999999999999999999.e+2DL) + || CHECK (tests192 (-9999999999999999999999999999999999000wb), -9999999999999999999999999999999999.e+3DL) + || CHECK (tests192 (9999999999999999999999999999999999499wb), 9999999999999999999999999999999999.e+3DL) + || CHECK (tests192 (34242319854454290000000000000000000000wb), 3424231985445429000000000000000000e+4DL) + || CHECK (tests192 (34242319854454294983573424983275760000wb), 3424231985445429498357342498327576e+4DL) + || CHECK (tests192 (999999999999999999999999999999999900000wb), 9999999999999999999999999999999999.e+5DL) + || CHECK (tests192 (999999999999999999999999999999999949999wb), 9999999999999999999999999999999999.e+5DL) + || CHECK (tests192 (-9999999999999999999999999999999999000000wb), -9999999999999999999999999999999999.e+6DL) + || CHECK (tests192 (-9999999999999999999999999999999999499999wb), -9999999999999999999999999999999999.e+6DL) + || CHECK (tests192 (123456789012345678901234567890123400000000wb), 1234567890123456789012345678901234.e+8DL) + || CHECK (tests192 (999999999999999999999999999999999900000000000000000000000wb), 9999999999999999999999999999999999.e+23DL) + || CHECK (tests192 (999999999999999999999999999999999949999999999999999999999wb), 9999999999999999999999999999999999.e+23DL) + || CHECK (tests192 (-999999999999999999999999999999999900000000000000000000000wb), -9999999999999999999999999999999999.e+23DL) + || CHECK (tests192 (-2138550877694459381917894711603833000000000000000000000000wb), -2138550877694459381917894711603833e+24DL) + || CHECK (tests192 (-2138550877694459381917894711603833500000000000000000000000wb), -2138550877694459381917894711603834e+24DL) + || CHECK (tests192 (-2138550877694459381917894711603833499999999999999999999999wb), -2138550877694459381917894711603833e+24DL) + || CHECK (tests192 (-2138550877694459381917894711603833999999999999999999999999wb), -2138550877694459381917894711603834e+24DL) + || CHECK (tests192 (-2138550877694459381917894711603832000000000000000000000000wb), -2138550877694459381917894711603832e+24DL) + || CHECK (tests192 (-2138550877694459381917894711603832500000000000000000000000wb), -2138550877694459381917894711603832e+24DL) + || CHECK (tests192 (-2138550877694459381917894711603832500000000000000000000001wb), -2138550877694459381917894711603833e+24DL) + || CHECK (tests192 (3138550867693340381917894711603833000000000000000000000000wb), 3138550867693340381917894711603833e+24DL) + || CHECK (tests192 (3138550867693340381917894711603833208051177722232017256447wb), 3138550867693340381917894711603833e+24DL) + || CHECK (tests192 (-3138550867693340381917894711603833000000000000000000000000wb), -3138550867693340381917894711603833e+24DL) + || CHECK (tests192 (-3138550867693340381917894711603833208051177722232017256447wb - 1wb), -3138550867693340381917894711603833e+24DL)) + __builtin_abort (); + if (CHECK (testu192 (0uwb), 0.DL) + || CHECK (testu192 (7uwb), 7.DL) + || CHECK (testu192 (42uwb), 42.DL) + || CHECK (testu192 (777777777uwb), 777777777.DL) + || CHECK (testu192 (99999999999999999999999999000uwb), 99999999999999999999999999000.DL) + || CHECK (testu192 (999999999999999999999999999999999900uwb), 9999999999999999999999999999999999.e+2DL) + || CHECK (testu192 (9999999999999999999999999999999999000uwb), 9999999999999999999999999999999999.e+3DL) + || CHECK (testu192 (99999999999999999999999999999999994999uwb), 9999999999999999999999999999999999.e+4DL) + || CHECK (testu192 (999999999999999999999999999999999900000uwb), 9999999999999999999999999999999999.e+5DL) + || CHECK (testu192 (9999999999999999999999999999999999000000uwb), 9999999999999999999999999999999999.e+6DL) + || CHECK (testu192 (123456789012345600000000uwb), 123456789012345600000000.DL) + || CHECK (testu192 (34242319854454290000000000000000000000uwb), 3424231985445429000000000000000000e+4DL) + || CHECK (testu192 (999999999999999999999999999999999900000000000000000000000uwb), 9999999999999999999999999999999999.e+23DL) + || CHECK (testu192 (6189354365465174593875438957438959000000000000000000000000uwb), 6189354365465174593875438957438959e+24DL) + || CHECK (testu192 (6189354365465174593875438957438959500000000000000000000000uwb), 6189354365465174593875438957438960e+24DL) + || CHECK (testu192 (6189354365465174593875438957438959499999999999999999999999uwb), 6189354365465174593875438957438959e+24DL) + || CHECK (testu192 (6189354365465174593875438957438959999999999999999999999999uwb), 6189354365465174593875438957438960e+24DL) + || CHECK (testu192 (6189354365465174593875438957438958000000000000000000000000uwb), 6189354365465174593875438957438958e+24DL) + || CHECK (testu192 (6189354365465174593875438957438958500000000000000000000000uwb), 6189354365465174593875438957438958e+24DL) + || CHECK (testu192 (6189354365465174593875438957438958500000000000000000000001uwb), 6189354365465174593875438957438959e+24DL) + || CHECK (testu192 (6277101735386680763835789423207666000000000000000000000000uwb), 6277101735386680763835789423207666e+24DL) + || CHECK (testu192 (6277101735386680763835789423207666416102355444464034512895uwb), 6277101735386680763835789423207666e+24DL)) + __builtin_abort (); +#endif +#if __BITINT_MAXWIDTH__ >= 575 + if (CHECK (tests575 (0wb), 0.DL) + || CHECK (tests575 (7wb), 7.DL) + || CHECK (tests575 (-42wb), -42.DL) + || CHECK (tests575 (-444444444wb), -444444444.DL) + || CHECK (tests575 (-3333333333333333wb), -3333333333333333.DL) + || CHECK (tests575 (99999999999999999999999999000wb), 99999999999999999999999999000.DL) + || CHECK (tests575 (-9999999999999999999999999999999999wb), -9999999999999999999999999999999999.DL) + || CHECK (tests575 (999999999999999999999999999999999900wb), 9999999999999999999999999999999999.e+2DL) + || CHECK (tests575 (-9999999999999999999999999999999999000wb), -9999999999999999999999999999999999.e+3DL) + || CHECK (tests575 (999999999999999999999999999999999900000wb), 9999999999999999999999999999999999.e+5DL) + || CHECK (tests575 (-99999999999999999999999999999999990000000wb), -9999999999999999999999999999999999.e+7DL) + || CHECK (tests575 (1234567890123456000000000wb), 1234567890123456000000000.DL) + || CHECK (tests575 (3424231985445429000000000000000000000000wb), 3424231985445429000000000000000000e+6DL) + || CHECK (tests575 (99999999999999999999999999999999990000000000000000000000000000000000000000wb), 9999999999999999999999999999999999.e+40DL) + || CHECK (tests575 (-9999999999999999999999999999999999000000000000000000000000000000000000000000000000000000000000000wb), -9999999999999999999999999999999999.e+63DL) + || CHECK (tests575 (-213855087769441389758947543987475900000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138550877694413897589475439874759e+86DL) + || CHECK (tests575 (-213855087769441389758947543987475950000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138550877694413897589475439874760e+86DL) + || CHECK (tests575 (-213855087769441389758947543987475949999999999999999999999999999999999999999999999999999999999999999999999999999999999999wb), -2138550877694413897589475439874759e+86DL) + || CHECK (tests575 (-213855087769441389758947543987475999999999999999999999999999999999999999999999999999999999999999999999999999999999999999wb), -2138550877694413897589475439874760e+86DL) + || CHECK (tests575 (-213855087769441389758947543987475800000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138550877694413897589475439874758e+86DL) + || CHECK (tests575 (-213855087769441389758947543987475850000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -2138550877694413897589475439874758e+86DL) + || CHECK (tests575 (-213855087769441389758947543987475850000000000000000000000000000000000000000000000000000000000000000000000000000000000001wb), -2138550877694413897589475439874759e+86DL) + || CHECK (tests575 (61832600368276133515125630254911790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), 6183260036827613351512563025491179e+139DL) + || CHECK (tests575 (61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb), 6183260036827613351512563025491180e+139DL) + || CHECK (tests575 (-61832600368276133515125630254911790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb), -6183260036827613351512563025491179e+139DL) + || CHECK (tests575 (-61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb - 1wb), -6183260036827613351512563025491180e+139DL)) + __builtin_abort (); + if (CHECK (testu575 (0uwb), 0.DL) + || CHECK (testu575 (17uwb), 17.DL) + || CHECK (testu575 (420uwb), 420.DL) + || CHECK (testu575 (888888888uwb), 888888888.DL) + || CHECK (testu575 (9999999999999000uwb), 9999999999999000.DL) + || CHECK (testu575 (99999999999999999999999999999999990000000uwb), 9999999999999999999999999999999999.e+7DL) + || CHECK (testu575 (9999999999999999999999999999999999000000000uwb), 9999999999999999999999999999999999.e+9DL) + || CHECK (testu575 (99999999999999999999999999999999990000000000000uwb), 9999999999999999999999999999999999.e+13DL) + || CHECK (testu575 (9999999999999999999999999999999999000000000000000uwb), 9999999999999999999999999999999999.e+15DL) + || CHECK (testu575 (1234567890123456000000000000000000uwb), 1234567890123456000000000000000000.DL) + || CHECK (testu575 (34242319854454290000000000000000000000uwb), 3424231985445429000000000000000000e+4DL) + || CHECK (testu575 (9999999999999999999999999999999999000000000000000000000000000000000uwb), 9999999999999999999999999999999999.e+33DL) + || CHECK (testu575 (618935436546517949837539847534981700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189354365465179498375398475349817e+104DL) + || CHECK (testu575 (618935436546517949837539847534981750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189354365465179498375398475349818e+104DL) + || CHECK (testu575 (618935436546517949837539847534981749999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999uwb), 6189354365465179498375398475349817e+104DL) + || CHECK (testu575 (618935436546517949837539847534981799999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999uwb), 6189354365465179498375398475349818e+104DL) + || CHECK (testu575 (618935436546517949837539847534981800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189354365465179498375398475349818e+104DL) + || CHECK (testu575 (618935436546517949837539847534981850000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 6189354365465179498375398475349818e+104DL) + || CHECK (testu575 (618935436546517949837539847534981850000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001uwb), 6189354365465179498375398475349819e+104DL) + || CHECK (testu575 (99999999999999999999999999999999990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 9999999999999999999999999999999999.e+139DL) + || CHECK (testu575 (123665200736552267030251260509823500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 1236652007365522670302512605098235e+140DL) + || CHECK (testu575 (123665200736552267030251260509823549999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999uwb), 1236652007365522670302512605098235e+140DL) + || CHECK (testu575 (123665200736552267030251260509823550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 1236652007365522670302512605098236e+140DL) + || CHECK (testu575 (123665200736552267030251260509823550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001uwb), 1236652007365522670302512605098236e+140DL) + || CHECK (testu575 (123665200736552267030251260509823550000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb), 1236652007365522670302512605098236e+140DL) + || CHECK (testu575 (123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb), 1236652007365522670302512605098236e+140DL)) + __builtin_abort (); +#endif +} --- libgcc/config/t-softfp.jj 2023-08-04 19:12:27.067454432 +0200 +++ libgcc/config/t-softfp 2023-08-07 15:29:03.244372189 +0200 @@ -68,7 +68,8 @@ softfp_floatbitint_funcs = fix$(m)bitint softfp_bid_list := ifeq ($(decimal_float),yes) ifeq ($(enable_decimal_float),bid) -softfp_bid_list += bitintpow10 $(foreach m,sd dd td,fix$(m)bitint) +softfp_bid_list += bitintpow10 \ + $(foreach m,sd dd td,fix$(m)bitint floatbitint$(m)) endif endif --- libgcc/soft-fp/floatbitintsd.c.jj 2023-08-05 20:18:36.028033893 +0200 +++ libgcc/soft-fp/floatbitintsd.c 2023-08-07 17:28:35.780452933 +0200 @@ -0,0 +1,235 @@ +/* Software floating-point emulation. + Convert a _BitInt to _Decimal32. + + Copyright (C) 2023 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#include "soft-fp.h" +#include "bitint.h" + +#ifdef __BITINT_MAXWIDTH__ +extern _Decimal32 __bid_floatbitintsd (const UBILtype *, SItype); + +_Decimal32 +__bid_floatbitintsd (const UBILtype *i, SItype iprec) +{ + iprec = bitint_reduce_prec (&i, iprec); + USItype aiprec = iprec < 0 ? -iprec : iprec; + USItype in = (aiprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + USItype idx = BITINT_END (0, in - 1); + UBILtype msb = i[idx]; + USItype mantissa; + SItype exponent = 0; + UBILtype inexact = 0; + union { _Decimal32 d; USItype u; } u, ui; + if (aiprec % BIL_TYPE_SIZE) + { + if (iprec > 0) + msb &= ((UBILtype) 1 << (aiprec % BIL_TYPE_SIZE)) - 1; + else + msb |= (UBILtype) -1 << (aiprec % BIL_TYPE_SIZE); + } + if (iprec < 0) + { + SItype n = sizeof (0ULL) * __CHAR_BIT__ + 1 - __builtin_clzll (~msb); + aiprec = (in - 1) * BIL_TYPE_SIZE + n; + } + else if (msb == 0) + aiprec = 1; + else + { + SItype n = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (msb); + aiprec = (in - 1) * BIL_TYPE_SIZE + n; + } + /* Number of bits in (_BitInt(2048)) 9999999e+90DF. */ + if (aiprec > 323 + (iprec < 0)) + { + ovf: + if (iprec < 0) + u.d = -9000000e+90DF; + else + u.d = 9000000e+90DF; + __asm ("" : "+g" (u.d)); + u.d += u.d; + __asm ("" : "+g" (u.d)); + goto done; + } + /* Bit precision of 9999999uwb. */ + if (aiprec >= 24) + { + USItype pow10_limbs, q_limbs, q2_limbs, j; + USItype exp_bits = 0, e; + UDItype m; + UBILtype *buf; + /* First do a possibly large divide smaller enough such that + we only need to check remainder for 0 or non-0 and then + we'll do further division. */ + if (aiprec >= 24 + 4 + 10) + { + exp_bits = (aiprec - 24 - 4) / 10; + exponent = exp_bits * 3; + /* Upper estimate for pow10 (exponent) bits. */ + exp_bits = exp_bits * 10 - exp_bits / 30; + } + pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + /* 38 is the highest number of quotient bits needed on + aiprec range of [38, 323]. E.g. if aiprec is 317, + exponent will be 84 and exp_bits 280. 317 - 280 + 1 + is 38. */ + q_limbs = (38 + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + q2_limbs = (32 + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + buf = __builtin_alloca ((q_limbs + pow10_limbs * 2 + q2_limbs + 2) + * sizeof (UBILtype)); + if (exponent) + { + __bid_pow10bitint (buf + q_limbs, exp_bits, exponent); + __divmodbitint4 (buf, q_limbs * BIL_TYPE_SIZE, + buf + q_limbs + pow10_limbs, + pow10_limbs * BIL_TYPE_SIZE, + i, iprec < 0 ? -aiprec : aiprec, + buf + q_limbs, exp_bits); + if (iprec < 0) + bitint_negate (buf + BITINT_END (q_limbs - 1, 0), + buf + BITINT_END (q_limbs - 1, 0), q_limbs); + inexact = buf[q_limbs + pow10_limbs]; + for (j = 1; j < pow10_limbs; ++j) + inexact |= buf[q_limbs + pow10_limbs + 1]; + } + else + { + __builtin_memcpy (buf + BITINT_END (q_limbs - in + 1, 0), i, + (in - 1) * sizeof (UBILtype)); + buf[BITINT_END (q_limbs - in, in - 1)] = msb; + if (iprec < 0) + bitint_negate (buf + BITINT_END (q_limbs - 1, 0), + buf + BITINT_END (q_limbs - 1, 0), in); + if (q_limbs > in) + __builtin_memset (buf + BITINT_END (0, in), '\0', + (q_limbs - in) * sizeof (UBILtype)); + } + e = 0; +#if BIL_TYPE_SIZE == 64 + m = buf[0]; +#elif BIL_TYPE_SIZE == 32 + m = ((UDItype) buf[BITINT_END (0, 1)] << 32) | buf[BITINT_END (1, 0)]; +#else +# error Unsupported BIL_TYPE_SIZE +#endif + if (m >= (UDItype) 10000000000) + { + if (m >= (UDItype) 100000000000) + e = 5; + else + e = 4; + } + else if (m >= (UDItype) 100000000) + { + if (m >= (UDItype) 1000000000) + e = 3; + else + e = 2; + } + else if (m >= (UDItype) 10000000) + e = 1; + exponent += e; + if (exponent > 90) + goto ovf; + if (e) + { + UBILtype rem, half; + __bid_pow10bitint (buf + q_limbs + pow10_limbs * 2, + BIL_TYPE_SIZE, e); + __divmodbitint4 (buf + q_limbs + pow10_limbs * 2 + 1, + q2_limbs * BIL_TYPE_SIZE, + buf + q_limbs + pow10_limbs * 2 + 1 + q2_limbs, + BIL_TYPE_SIZE, + buf, q_limbs * BIL_TYPE_SIZE, + buf + q_limbs + pow10_limbs * 2, BIL_TYPE_SIZE); + half = buf[q_limbs + pow10_limbs * 2] / 2; + rem = buf[q_limbs + pow10_limbs * 2 + 1 + q2_limbs]; + if (inexact) + { + /* If first division discovered some non-0 digits + and this second division is by 10, e.g. + for XXXXXX5499999999999 or XXXXXX5000000000001 + if first division is by 10^12 and second by 10^1, + doing rem |= 1 wouldn't change the 5. Similarly + for rem 4 doing rem |= 1 would change it to 5, + but we don't want to change it in that case. */ + if (e == 1) + { + if (rem == 5) + rem = 6; + else if (rem != 4) + rem |= 1; + } + else + rem |= 1; + } + /* Set inexact to 0, 1, 2, 3 depending on if remainder + of the divisions is exact 0, smaller than 10^exponent / 2, + exactly 10^exponent / 2 or greater than that. */ + if (rem >= half) + inexact = 2 + (rem > half); + else + inexact = (rem != 0); + mantissa = buf[q_limbs + pow10_limbs * 2 + 1]; + } + else +#if BIL_TYPE_SIZE == 64 + mantissa = buf[0]; +#else + mantissa = buf[BITINT_END (1, 0)]; +#endif + } + else + { + mantissa = msb; + if (iprec < 0) + mantissa = -mantissa; + } + + exponent += 101; + if (mantissa >= (USItype) 0x800000) + u.u = (((((iprec < 0) << 2) | (USItype) 3) << 29) + | (((USItype) exponent) << 21) + | (mantissa ^ (USItype) 0x800000)); + else + u.u = ((((USItype) (iprec < 0)) << 31) + | (((USItype) exponent) << 23) + | mantissa); + if (inexact) + { + ui.u = ((((USItype) (iprec < 0)) << 31) + | (((USItype) (exponent - 1)) << 23) + | (inexact + 3)); + __asm ("" : "+g" (u.d)); + __asm ("" : "+g" (ui.d)); + u.d += ui.d; + __asm ("" : "+g" (u.d)); + } + +done: + return u.d; +} +#endif --- libgcc/soft-fp/floatbitintdd.c.jj 2023-08-05 12:20:37.504414281 +0200 +++ libgcc/soft-fp/floatbitintdd.c 2023-08-07 17:27:10.526647391 +0200 @@ -0,0 +1,264 @@ +/* Software floating-point emulation. + Convert a _BitInt to _Decimal64. + + Copyright (C) 2023 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#include "soft-fp.h" +#include "bitint.h" + +#ifdef __BITINT_MAXWIDTH__ +extern _Decimal64 __bid_floatbitintdd (const UBILtype *, SItype); + +_Decimal64 +__bid_floatbitintdd (const UBILtype *i, SItype iprec) +{ + iprec = bitint_reduce_prec (&i, iprec); + USItype aiprec = iprec < 0 ? -iprec : iprec; + USItype in = (aiprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + USItype idx = BITINT_END (0, in - 1); + UBILtype msb = i[idx]; + UDItype mantissa; + SItype exponent = 0; + UBILtype inexact = 0; + union { _Decimal64 d; UDItype u; } u, ui; + if (aiprec % BIL_TYPE_SIZE) + { + if (iprec > 0) + msb &= ((UBILtype) 1 << (aiprec % BIL_TYPE_SIZE)) - 1; + else + msb |= (UBILtype) -1 << (aiprec % BIL_TYPE_SIZE); + } + if (iprec < 0) + { + SItype n = sizeof (0ULL) * __CHAR_BIT__ + 1 - __builtin_clzll (~msb); + aiprec = (in - 1) * BIL_TYPE_SIZE + n; + } + else if (msb == 0) + aiprec = 1; + else + { + SItype n = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (msb); + aiprec = (in - 1) * BIL_TYPE_SIZE + n; + } + /* Number of bits in (_BitInt(2048)) 9999999999999999e+369DD. */ + if (aiprec > 1279 + (iprec < 0)) + { + ovf: + if (iprec < 0) + u.d = -9000000000000000e+369DD; + else + u.d = 9000000000000000e+369DD; + __asm ("" : "+g" (u.d)); + u.d += u.d; + __asm ("" : "+g" (u.d)); + goto done; + } + /* Bit precision of 9999999999999999uwb. */ + if (aiprec >= 54) + { + USItype pow10_limbs, q_limbs, q2_limbs, j; + USItype exp_bits = 0, e; + UDItype m; + UBILtype *buf; + /* First do a possibly large divide smaller enough such that + we only need to check remainder for 0 or non-0 and then + we'll do further division. */ + if (aiprec >= 54 + 4 + 10) + { + exp_bits = (aiprec - 54 - 4) / 10; + exponent = exp_bits * 3; + /* Upper estimate for pow10 (exponent) bits. */ + exp_bits = exp_bits * 10 - exp_bits / 30; + } + pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + /* 72 is the highest number of quotient bits needed on + aiprec range of [68, 1279]. E.g. if aiprec is 1277, + exponent will be 363 and exp_bits 1206. 1277 - 1206 + 1 + is 72. Unfortunately that means the result doesn't fit into + UDItype... */ + q_limbs = (72 + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + q2_limbs = 64 / BIL_TYPE_SIZE; + buf = __builtin_alloca ((q_limbs + pow10_limbs * 2 + q2_limbs + 2) + * sizeof (UBILtype)); + if (exponent) + { + __bid_pow10bitint (buf + q_limbs, exp_bits, exponent); + __divmodbitint4 (buf, q_limbs * BIL_TYPE_SIZE, + buf + q_limbs + pow10_limbs, + pow10_limbs * BIL_TYPE_SIZE, + i, iprec < 0 ? -aiprec : aiprec, + buf + q_limbs, exp_bits); + if (iprec < 0) + bitint_negate (buf + BITINT_END (q_limbs - 1, 0), + buf + BITINT_END (q_limbs - 1, 0), q_limbs); + inexact = buf[q_limbs + pow10_limbs]; + for (j = 1; j < pow10_limbs; ++j) + inexact |= buf[q_limbs + pow10_limbs + 1]; + } + else + { + __builtin_memcpy (buf + BITINT_END (q_limbs - in + 1, 0), i, + (in - 1) * sizeof (UBILtype)); + buf[BITINT_END (q_limbs - in, in - 1)] = msb; + if (iprec < 0) + bitint_negate (buf + BITINT_END (q_limbs - 1, 0), + buf + BITINT_END (q_limbs - 1, 0), in); + if (q_limbs > in) + __builtin_memset (buf + BITINT_END (0, in), '\0', + (q_limbs - in) * sizeof (UBILtype)); + } + e = 0; +#if BIL_TYPE_SIZE == 64 + m = buf[BITINT_END (1, 0)]; +#elif BIL_TYPE_SIZE == 32 + m = ((UDItype) buf[1] << 32) | buf[BITINT_END (2, 0)]; +#else +# error Unsupported BIL_TYPE_SIZE +#endif + if (buf[BITINT_END (0, q_limbs - 1)]) + { + if (buf[BITINT_END (0, q_limbs - 1)] > 0x5) + { + /* 1000000000000000000000wb */ + if (buf[BITINT_END (0, q_limbs - 1)] > 0x36 + || (buf[BITINT_END (0, q_limbs - 1)] == 0x36 + && m >= (UDItype) 0x35c9adc5dea00000)) + e = 6; + else + e = 5; + } + /* 100000000000000000000wb */ + else if (buf[BITINT_END (0, q_limbs - 1)] == 0x5 + && m >= (UDItype) 0x6bc75e2d63100000) + e = 5; + else + e = 4; + } + else if (m >= (UDItype) 1000000000000000000) + { + if (m >= (UDItype) 10000000000000000000ULL) + e = 4; + else + e = 3; + } + else if (m >= (UDItype) 100000000000000000) + e = 2; + else if (m >= (UDItype) 10000000000000000) + e = 1; + exponent += e; + if (exponent > 369) + goto ovf; + if (e) + { + UBILtype rem, half; + __bid_pow10bitint (buf + q_limbs + pow10_limbs * 2, + BIL_TYPE_SIZE, e); + __divmodbitint4 (buf + q_limbs + pow10_limbs * 2 + 1, + q2_limbs * BIL_TYPE_SIZE, + buf + q_limbs + pow10_limbs * 2 + 1 + q2_limbs, + BIL_TYPE_SIZE, + buf, q_limbs * BIL_TYPE_SIZE, + buf + q_limbs + pow10_limbs * 2, BIL_TYPE_SIZE); + half = buf[q_limbs + pow10_limbs * 2] / 2; + rem = buf[q_limbs + pow10_limbs * 2 + 1 + q2_limbs]; + if (inexact) + { + /* If first division discovered some non-0 digits + and this second division is by 10, e.g. + for XXXXXX5499999999999 or XXXXXX5000000000001 + if first division is by 10^12 and second by 10^1, + doing rem |= 1 wouldn't change the 5. Similarly + for rem 4 doing rem |= 1 would change it to 5, + but we don't want to change it in that case. */ + if (e == 1) + { + if (rem == 5) + rem = 6; + else if (rem != 4) + rem |= 1; + } + else + rem |= 1; + } + /* Set inexact to 0, 1, 2, 3 depending on if remainder + of the divisions is exact 0, smaller than 10^exponent / 2, + exactly 10^exponent / 2 or greater than that. */ + if (rem >= half) + inexact = 2 + (rem > half); + else + inexact = (rem != 0); +#if BIL_TYPE_SIZE == 64 + mantissa = buf[q_limbs + pow10_limbs * 2 + 1]; +#else + mantissa + = ((buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (0, 1)] << 32) + | buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (1, 0)]); +#endif + } + else +#if BIL_TYPE_SIZE == 64 + mantissa = buf[BITINT_END (1, 0)]; +#else + mantissa + = ((buf[1] << 32) | buf[BITINT_END (2, 0)]); +#endif + } + else + { +#if BIL_TYPE_SIZE == 64 + mantissa = msb; +#else + if (in == 1) + mantissa = iprec < 0 ? (UDItype) (BILtype) msb : (UDItype) msb; + else + mantissa = ((msb << 32) | i[BITINT_END (1, 0)]); +#endif + if (iprec < 0) + mantissa = -mantissa; + } + + exponent += 398; + if (mantissa >= (UDItype) 0x20000000000000) + u.u = (((((iprec < 0) << 2) | (UDItype) 3) << 61) + | (((UDItype) exponent) << 51) + | (mantissa ^ (UDItype) 0x20000000000000)); + else + u.u = ((((UDItype) (iprec < 0)) << 63) + | (((UDItype) exponent) << 53) + | mantissa); + if (inexact) + { + ui.u = ((((UDItype) (iprec < 0)) << 63) + | (((UDItype) (exponent - 1)) << 53) + | (inexact + 3)); + __asm ("" : "+g" (u.d)); + __asm ("" : "+g" (ui.d)); + u.d += ui.d; + __asm ("" : "+g" (u.d)); + } + +done: + return u.d; +} +#endif --- libgcc/soft-fp/floatbitinttd.c.jj 2023-08-07 12:12:56.784323214 +0200 +++ libgcc/soft-fp/floatbitinttd.c 2023-08-07 17:26:44.194016328 +0200 @@ -0,0 +1,271 @@ +/* Software floating-point emulation. + Convert a _BitInt to _Decimal128. + + Copyright (C) 2023 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#include "soft-fp.h" +#include "bitint.h" + +#ifdef __BITINT_MAXWIDTH__ +extern _Decimal128 __bid_floatbitinttd (const UBILtype *, SItype); + +_Decimal128 +__bid_floatbitinttd (const UBILtype *i, SItype iprec) +{ + iprec = bitint_reduce_prec (&i, iprec); + USItype aiprec = iprec < 0 ? -iprec : iprec; + USItype in = (aiprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + USItype idx = BITINT_END (0, in - 1); + UBILtype msb = i[idx]; + UDItype mantissahi, mantissalo; + SItype exponent = 0; + UBILtype inexact = 0; + union { _Decimal128 d; UDItype u[2]; } u, ui; + if (aiprec % BIL_TYPE_SIZE) + { + if (iprec > 0) + msb &= ((UBILtype) 1 << (aiprec % BIL_TYPE_SIZE)) - 1; + else + msb |= (UBILtype) -1 << (aiprec % BIL_TYPE_SIZE); + } + if (iprec < 0) + { + SItype n = sizeof (0ULL) * __CHAR_BIT__ + 1 - __builtin_clzll (~msb); + aiprec = (in - 1) * BIL_TYPE_SIZE + n; + } + else if (msb == 0) + aiprec = 1; + else + { + SItype n = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (msb); + aiprec = (in - 1) * BIL_TYPE_SIZE + n; + } + /* Number of bits in + (_BitInt(32768)) 9999999999999999999999999999999999e+6111DL. */ + if (aiprec > 20414 + (iprec < 0)) + { + ovf: + if (iprec < 0) + u.d = -9000000000000000000000000000000000e+6111DL; + else + u.d = 9000000000000000000000000000000000e+6111DL; + __asm ("" : "+g" (u.d)); + u.d += u.d; + __asm ("" : "+g" (u.d)); + goto done; + } + /* Bit precision of 9999999999999999999999999999999999uwb. */ + if (aiprec >= 113) + { + USItype pow10_limbs, q_limbs, q2_limbs, j, k; + USItype exp_bits = 0, e; + UBILtype *buf; + /* First do a possibly large divide smaller enough such that + we only need to check remainder for 0 or non-0 and then + we'll do further division. */ + if (aiprec >= 113 + 4 + 10) + { + exp_bits = ((aiprec - 113 - 4) * (UDItype) 30) / 299; + exponent = exp_bits * 3; + /* Upper estimate for pow10 (exponent) bits. */ + exp_bits = exp_bits * 10 - exp_bits / 30; + } + pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + /* 127 is the highest number of quotient bits needed on + aiprec range of [127, 20414]. E.g. if aiprec is 20409, + exponent will be 6105 and exp_bits 20283. 20409 - 20283 + 1 + is 127. */ + q_limbs = (127 + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + q2_limbs = 128 / BIL_TYPE_SIZE; + buf = __builtin_alloca ((q_limbs + pow10_limbs * 2 + q2_limbs + 2) + * sizeof (UBILtype)); + if (exponent) + { + __bid_pow10bitint (buf + q_limbs, exp_bits, exponent); + __divmodbitint4 (buf, q_limbs * BIL_TYPE_SIZE, + buf + q_limbs + pow10_limbs, + pow10_limbs * BIL_TYPE_SIZE, + i, iprec < 0 ? -aiprec : aiprec, + buf + q_limbs, exp_bits); + if (iprec < 0) + bitint_negate (buf + BITINT_END (q_limbs - 1, 0), + buf + BITINT_END (q_limbs - 1, 0), q_limbs); + inexact = buf[q_limbs + pow10_limbs]; + for (j = 1; j < pow10_limbs; ++j) + inexact |= buf[q_limbs + pow10_limbs + 1]; + } + else + { + __builtin_memcpy (buf + BITINT_END (q_limbs - in + 1, 0), i, + (in - 1) * sizeof (UBILtype)); + buf[BITINT_END (q_limbs - in, in - 1)] = msb; + if (iprec < 0) + bitint_negate (buf + BITINT_END (q_limbs - 1, 0), + buf + BITINT_END (q_limbs - 1, 0), in); + if (q_limbs > in) + __builtin_memset (buf + BITINT_END (0, in), '\0', + (q_limbs - in) * sizeof (UBILtype)); + } + e = 0; + for (j = 3; j; ) + { + USItype eprev = e; + __bid_pow10bitint (buf + q_limbs + pow10_limbs * 2 + 1, + 128, 33 + e + j); + for (k = BITINT_END (0, q_limbs - 1); + k != BITINT_END (q_limbs, (USItype) -1); k -= BITINT_INC) + if (buf[k] > buf[q_limbs + pow10_limbs * 2 + 1 + k]) + { + e += j; + break; + } + else if (buf[k] < buf[q_limbs + pow10_limbs * 2 + 1 + k]) + break; + if (k == BITINT_END (q_limbs, (USItype) -1)) + e += j; + if (j == 2 && e != eprev) + break; + else + --j; + } + exponent += e; + if (exponent > 6111) + goto ovf; + if (e) + { + UBILtype rem, half; + __bid_pow10bitint (buf + q_limbs + pow10_limbs * 2, + BIL_TYPE_SIZE, e); + __divmodbitint4 (buf + q_limbs + pow10_limbs * 2 + 1, + q2_limbs * BIL_TYPE_SIZE, + buf + q_limbs + pow10_limbs * 2 + 1 + q2_limbs, + BIL_TYPE_SIZE, + buf, q_limbs * BIL_TYPE_SIZE, + buf + q_limbs + pow10_limbs * 2, BIL_TYPE_SIZE); + half = buf[q_limbs + pow10_limbs * 2] / 2; + rem = buf[q_limbs + pow10_limbs * 2 + 1 + q2_limbs]; + if (inexact) + { + /* If first division discovered some non-0 digits + and this second division is by 10, e.g. + for XXXXXX5499999999999 or XXXXXX5000000000001 + if first division is by 10^12 and second by 10^1, + doing rem |= 1 wouldn't change the 5. Similarly + for rem 4 doing rem |= 1 would change it to 5, + but we don't want to change it in that case. */ + if (e == 1) + { + if (rem == 5) + rem = 6; + else if (rem != 4) + rem |= 1; + } + else + rem |= 1; + } + /* Set inexact to 0, 1, 2, 3 depending on if remainder + of the divisions is exact 0, smaller than 10^exponent / 2, + exactly 10^exponent / 2 or greater than that. */ + if (rem >= half) + inexact = 2 + (rem > half); + else + inexact = (rem != 0); +#if BIL_TYPE_SIZE == 64 + mantissahi = buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (0, 1)]; + mantissalo = buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (1, 0)]; +#else + mantissahi + = ((buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (0, 3)] << 32) + | buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (1, 2)]); + mantissalo + = ((buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (2, 1)] << 32) + | buf[q_limbs + pow10_limbs * 2 + 1 + BITINT_END (3, 0)]); +#endif + } + else + { +#if BIL_TYPE_SIZE == 64 + mantissahi = buf[BITINT_END (0, 1)]; + mantissalo = buf[BITINT_END (1, 0)]; +#else + mantissahi = (buf[BITINT_END (0, 3)] << 32) | buf[BITINT_END (1, 2)]; + mantissalo = (buf[BITINT_END (2, 1)] << 32) | buf[BITINT_END (3, 0)]; +#endif + } + } + else + { + mantissahi = iprec < 0 ? -1 : 0; +#if BIL_TYPE_SIZE == 64 + if (in == 1) + mantissalo = msb; + else + { + mantissahi = msb; + mantissalo = i[BITINT_END (1, 0)]; + } +#else + if (in <= 2) + { + if (in == 1) + mantissalo = iprec < 0 ? (UDItype) (BILtype) msb : (UDItype) msb; + else + mantissalo = (msb << 32) | i[BITINT_END (1, 0)]; + } + else + { + if (in == 3) + mantissahi = iprec < 0 ? (UDItype) (BILtype) msb : (UDItype) msb; + else + mantissahi = (msb << 32) | i[BITINT_END (1, 2)]; + mantissalo = ((i[BITINT_END (in - 2, 1)] << 32) + | i[BITINT_END (in - 1, 0)]); + } +#endif + if (iprec < 0) + mantissahi + = ~mantissahi + __builtin_add_overflow (~mantissalo, 1, &mantissalo); + } + + exponent += 6176; + u.u[__FLOAT_WORD_ORDER__ != __ORDER_BIG_ENDIAN__] + = ((((UDItype) (iprec < 0)) << 63) + | (((UDItype) exponent) << 49) + | mantissahi); + u.u[__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__] = mantissalo; + if (inexact) + { + ui.u[__FLOAT_WORD_ORDER__ != __ORDER_BIG_ENDIAN__] + = (((UDItype) (iprec < 0)) << 63) | (((UDItype) exponent - 1) << 49); + ui.u[__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__] = inexact + 3; + __asm ("" : "+g" (u.d)); + __asm ("" : "+g" (ui.d)); + u.d += ui.d; + __asm ("" : "+g" (u.d)); + } + +done: + return u.d; +} +#endif