From patchwork Fri Aug 4 18:13:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 131295 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp17245vqr; Fri, 4 Aug 2023 11:14:22 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEkWUKgEFBALjIdKBIQLVc2ZLxXlKyRcEOaLTefwkFxxx9XoallfVrcavcApDAGQgipzZdq X-Received: by 2002:a17:906:8470:b0:99c:6825:ca06 with SMTP id hx16-20020a170906847000b0099c6825ca06mr1924846ejc.12.1691172862498; Fri, 04 Aug 2023 11:14:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691172862; cv=none; d=google.com; s=arc-20160816; b=W8ACwRUj1EFnAxwgOjbA0/ym0rMLyYD/uTJhN2gm2B8WJp7lKndXXCHWpt0psnJT3a X2BgxQRZ3E3bB1yNLBV2SPnMN4aNX7YsvrtLJmahr4lEKA8DvusIjU91pQ4VFVSoA4JB 5A88oYOhlvatUuZd8b9UxsaZ5wRQ7NcKlHp7jB9/xoH3ZfpHp/NuWF2zAOMbnpP1uQTh rJBRVoxis4Rc2MibswsEvv4pSYAN0daK655Rj4Igzjj0O/c/inK0VNpVy5dkoIN7y0Dp rfqTbMP3K4EAY+CQEMW2kont6nsodsK27++Dd+yhl+EsarzyDFKXh58795NbnmEwsabZ +wWg== 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=J8yLdx9Ruz8t99vNVFndixScmDz0Tl6SzC5Iv6AOzv4=; fh=iJKxuLOC785N45OfHYehmKhc2L5lYLWzgOCcw+koEGQ=; b=Wqr0kgrm2ooKg3IhUDRxvPOBh2IB3vQjH9wgqQpYXzD0hkmtsDsCC7p0xDUCX6P/t6 JmPcuXtS2/zzDNKOZuKesZoQ92DPcl02+H0mVW5LVqDxuHIfYxrnxUXKfyOMYCTQBGRI m+27N1nchOq3icWepwgcPt37SRhhN6s1c7WpHvMwwy0P2qowiDYvafdLQ4+t2S54gG5S IZzCF/HD148EgiHrfe5pEIY22xS6r34UAiItag58RuzkE01wj60xHeA37EEXtpjdlh7W rwOukAJnh90YOGOcr6hc2Tgb41SadZwtC08eegNaOSTxk4+8RHvG6SZLui4fW3TTPlnq qQ6w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=rqHoJOtY; 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 gq1-20020a170906e24100b0099bcd1f229asi1650813ejb.370.2023.08.04.11.14.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Aug 2023 11:14:22 -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=rqHoJOtY; 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 BC113385734B for ; Fri, 4 Aug 2023 18:14:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BC113385734B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1691172860; bh=J8yLdx9Ruz8t99vNVFndixScmDz0Tl6SzC5Iv6AOzv4=; h=Date:To:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=rqHoJOtYf2laIm3uj/pQgKNkFT7Vlcr19/bdO8enrF+TSpxMylvg31HTYDamRCv2F UUg73iMhj7jrtxSzFcWSkZTpOE22hzIFRhNm98dn6IGfzO58o7PRk5IY72xb7u9ROO srDWv/8RpukhtazDng9NoQ7iRQtEgCXKYmFpbuQs= 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 87B1E3858C5F for ; Fri, 4 Aug 2023 18:13:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 87B1E3858C5F 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-36-IjqHXPtONleaQRNMOdTEfQ-1; Fri, 04 Aug 2023 14:13:11 -0400 X-MC-Unique: IjqHXPtONleaQRNMOdTEfQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 0C206185A791; Fri, 4 Aug 2023 18:13:11 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.224.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 72CD640C1258; Fri, 4 Aug 2023 18:13:10 +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 374ID7xT3611943 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 4 Aug 2023 20:13:08 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 374ID62R3611940; Fri, 4 Aug 2023 20:13:06 +0200 Date: Fri, 4 Aug 2023 20:13:06 +0200 To: Joseph Myers Cc: gcc-patches@gcc.gnu.org, Richard Biener Subject: [PATCH] _Decimal* to _BitInt conversion support [PR102989] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.0 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: 1773323275844286234 X-GMAIL-MSGID: 1773323275844286234 Hi! Repost because the patch was too large. On Fri, Jul 28, 2023 at 06:03:33PM +0000, Joseph Myers wrote: > Note that representations with too-large significand are defined to be > noncanonical representations of zero, so you need to take care of that in > decoding BID. Done. > You could e.g. have a table up to 10^(N-1) for some N, and 10^N, 10^2N > etc. up to 10^6144 (or rather up to 10^6111, which can then be multiplied > by a 34-digit integer significand), so that only one multiplication is > needed to get the power of 10 and then a second multiplication by the > significand. (Or split into three parts at the cost of an extra > multiplication, or multiply the significand by 1, 10, 100, 1000 or 10000 > as a multiplication within 128 bits and so only need to compute 10^k for k > a multiple of 5, or any number of variations on those themes.) So, I've used N 256 and applied a little further space optimization, omitting least significant whole limbs full of just zeros (for 32-bit limbs actually pairs of those limbs, otherwise it would be a nightmare). With that I got down to 32KiB or so (32128 bytes the limb array and 560 bytes the offset array), tables generated such that they can be used with both 32-bit and 64-bit limbs and both little and big endian ordering of them. The following patch implements for now just the _Decimal -> _BitInt conversions and uses the soft-fp infrastructure to raise exceptions (not heavily tight to that, if the bitint.h header from soft-fp is copied/tweaked and a few typedefs are provided it could be also in libbid if it grows usable exception support). I'll work on _BitInt -> _Decimal next and hope to use the __bid_pow10bitint function in there as well (guess some safe lower power of 10 divisor, use __divmodbitint4 to divide by that power of 10 including computing remainder, analyze that remainder (check if it is 0, exact half of the power of 10, or something smaller or larger than that) and if guessed too low, divide the usually much smaller quotient again to get exact answer (+ again check remainder). The bitintpow10.c patch is included compressed, as the single source file is 408KiB. 2023-08-04 Jakub Jelinek PR c/102989 gcc/ * gimple-lower-bitint.cc (bitint_large_huge::lower_float_conv_stmt): Handle _Decimal* to _BitInt conversions. * internal-fn.cc (expand_FLOATTOBITINT): Likewise. gcc/testsuite/ * gcc.dg/dfp/bitint-1.c: New test. * gcc.dg/dfp/bitint-2.c: New test. * gcc.dg/dfp/bitint-3.c: New test. libgcc/ * config/t-softfp (softfp_bid_list, softfp_bid_file_list): New variables. (LIB2ADD_ST): Add $(softfp_bid_file_list). * soft-fp/fixsdbitint.c: New file. * soft-fp/fixddbitint.c: New file. * soft-fp/fixtdbitint.c: New file. * soft-fp/bitint.h (bitint_negate): New static inline function. (__mulbitint3, __divmodbitint4, __bid_pow10bitint): Declare. * soft-fp/bitintpow10.c: New file. Jakub --- gcc/gimple-lower-bitint.cc.jj 2023-08-02 17:36:15.439915237 +0200 +++ gcc/gimple-lower-bitint.cc 2023-08-04 09:40:14.271005211 +0200 @@ -3363,8 +3363,7 @@ 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 (rhs1))) - || DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (lhs)))) + if (DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (lhs)))) { sorry_at (gimple_location (stmt), "unsupported conversion between %<_BitInt(%d)%> and %qT", --- gcc/internal-fn.cc.jj 2023-07-26 10:06:29.233849044 +0200 +++ gcc/internal-fn.cc 2023-08-04 09:47:58.368480546 +0200 @@ -4846,11 +4846,25 @@ expand_FLOATTOBITINT (internal_fn, gcall const char *mname = GET_MODE_NAME (mode); unsigned mname_len = strlen (mname); int len = 12 + 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, "__fix", 5); - p += 5; + if (DECIMAL_FLOAT_MODE_P (mode)) + { +#if ENABLE_DECIMAL_BID_FORMAT + memcpy (p, "__bid_fix", 9); +#else + memcpy (p, "__dpd_fix", 9); +#endif + p += 9; + } + else + { + memcpy (p, "__fix", 5); + p += 5; + } for (q = mname; *q; q++) *p++ = TOLOWER (*q); memcpy (p, "bitint", 7); --- gcc/testsuite/gcc.dg/dfp/bitint-1.c.jj 2023-08-04 14:30:24.615100334 +0200 +++ gcc/testsuite/gcc.dg/dfp/bitint-1.c 2023-08-04 19:37:26.834790279 +0200 @@ -0,0 +1,98 @@ +/* PR c/102989 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2 -std=c2x -pedantic-errors" } */ + +#if __BITINT_MAXWIDTH__ >= 192 +__attribute__((noipa)) _BitInt(192) +tests192 (_Decimal64 d) +{ + return d; +} + +__attribute__((noipa)) unsigned _BitInt(192) +testu192 (_Decimal64 d) +{ + return d; +} +#endif + +#if __BITINT_MAXWIDTH__ >= 575 +__attribute__((noipa)) _BitInt(575) +tests575 (_Decimal64 d) +{ + return d; +} + +__attribute__((noipa)) unsigned _BitInt(575) +testu575 (_Decimal64 d) +{ + return d; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 192 + if (tests192 (0.DD) != 0wb + || tests192 (0.9999999999999999DD) != 0wb + || tests192 (7.999999999999999DD) != 7wb + || tests192 (-42.5DD) != -42wb + || tests192 (-34242319854.45429e+27DD) != -34242319854454290000000000000000000000wb + || tests192 (-213855087769445.9e+43DD) != -2138550877694459000000000000000000000000000000000000000000wb + || tests192 (313855086769334.0e+43DD) != 3138550867693340000000000000000000000000000000000000000000wb + || tests192 (-313855086769334.0e+43DD) != -3138550867693340000000000000000000000000000000000000000000wb) + __builtin_abort (); + if (tests192 (313855086769334.1e+43DD) != 3138550867693340381917894711603833208051177722232017256447wb + || tests192 (9999999999999999e+369DD) != 3138550867693340381917894711603833208051177722232017256447wb + || tests192 (-313855086769334.1e+43DD) != -3138550867693340381917894711603833208051177722232017256447wb - 1wb + || tests192 (-9999999999999999e+369DD) != -3138550867693340381917894711603833208051177722232017256447wb - 1wb) + __builtin_abort (); + if (testu192 (0.DD) != 0uwb + || testu192 (0.9999999999999999DD) != 0uwb + || testu192 (-0.9999999999999999DD) != 0uwb + || testu192 (-0.5DD) != 0uwb + || testu192 (42.99999999999999DD) != 42uwb + || testu192 (42.e+21DD) != 42000000000000000000000uwb + || testu192 (34272319854.45429e+27DD) != 34272319854454290000000000000000000000uwb + || testu192 (627710173538668.0e+43DD) != 6277101735386680000000000000000000000000000000000000000000uwb) + __builtin_abort (); + if (testu192 (-1.DD) != 0uwb + || testu192 (-42.5e+15DD) != 0uwb + || testu192 (-9999999999999999e+369DD) != 0uwb + || testu192 (627710173538668.1e+43DD) != 6277101735386680763835789423207666416102355444464034512895uwb + || testu192 (9999999999999999e+369DD) != 6277101735386680763835789423207666416102355444464034512895uwb) + __builtin_abort (); +#endif +#if __BITINT_MAXWIDTH__ >= 575 + if (tests575 (0.DD) != 0wb + || tests575 (0.999999DD) != 0wb + || tests575 (12.9999999999999DD) != 12wb + || tests575 (-89.5DD) != -89wb + || tests575 (-34242319854.45429e+37DD) != -342423198544542900000000000000000000000000000000wb + || tests575 (-518326003682761.2e+158DD) != -51832600368276120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb + || tests575 (6183260036827613.0e+157DD) != 61832600368276130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb + || tests575 (-6183260036827613.0e+157DD) != -61832600368276130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb) + __builtin_abort (); + if (tests575 (6183260036827614.0e+157DD) != 61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb + || tests575 (9999999999999999e+369DD) != 61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb + || tests575 (-6183260036827614.0e+157DD) != -61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb - 1wb + || tests575 (-9999999999999999e+369DD) != -61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb - 1wb) + __builtin_abort (); + if (testu575 (0.DD) != 0uwb + || testu575 (0.5555555555555555DD) != 0uwb + || testu575 (-0.7777777777777777DD) != 0uwb + || testu575 (-0.99DD) != 0uwb + || testu575 (42.99999999999999DD) != 42uwb + || testu575 (42.e+21DD) != 42000000000000000000000uwb + || testu575 (94272319854.45429e+27DD) != 94272319854454290000000000000000000000uwb + || testu575 (1236652007365522.0e+158DD) != 123665200736552200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb) + __builtin_abort (); + if (testu575 (-1.DD) != 0uwb + || testu575 (-42.5e+15DD) != 0uwb + || testu575 (-9999999999999999e+369DD) != 0uwb + || testu575 (1236652007365523.0e+158DD) != 123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb + || testu575 (9999999999999999e+369DD) != 123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb) + __builtin_abort (); +#endif +} --- gcc/testsuite/gcc.dg/dfp/bitint-2.c.jj 2023-08-04 15:11:01.831381336 +0200 +++ gcc/testsuite/gcc.dg/dfp/bitint-2.c 2023-08-04 19:37:36.703654308 +0200 @@ -0,0 +1,91 @@ +/* PR c/102989 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2 -std=c2x -pedantic-errors" } */ + +#if __BITINT_MAXWIDTH__ >= 192 +__attribute__((noipa)) _BitInt(192) +tests192 (_Decimal32 d) +{ + return d; +} + +__attribute__((noipa)) unsigned _BitInt(192) +testu192 (_Decimal32 d) +{ + return d; +} +#endif + +#if __BITINT_MAXWIDTH__ >= 575 +__attribute__((noipa)) _BitInt(575) +tests575 (_Decimal32 d) +{ + return d; +} + +__attribute__((noipa)) unsigned _BitInt(575) +testu575 (_Decimal32 d) +{ + return d; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 192 + if (tests192 (0.DF) != 0wb + || tests192 (0.9999999DF) != 0wb + || tests192 (7.999999DF) != 7wb + || tests192 (-42.5DF) != -42wb + || tests192 (-3424.231e+27DF) != -3424231000000000000000000000000wb + || tests192 (-213855.9e+43DF) != -2138559000000000000000000000000000000000000000000wb + || tests192 (313855.0e+52DF) != 3138550000000000000000000000000000000000000000000000000000wb + || tests192 (-3138550.e+51DF) != -3138550000000000000000000000000000000000000000000000000000wb) + __builtin_abort (); + if (tests192 (313855.1e+52DF) != 3138550867693340381917894711603833208051177722232017256447wb + || tests192 (9999999e+90DF) != 3138550867693340381917894711603833208051177722232017256447wb + || tests192 (-3138551e+51DF) != -3138550867693340381917894711603833208051177722232017256447wb - 1wb + || tests192 (-9999999e+90DF) != -3138550867693340381917894711603833208051177722232017256447wb - 1wb) + __builtin_abort (); + if (testu192 (0.DF) != 0uwb + || testu192 (0.9999999DF) != 0uwb + || testu192 (-0.9999999DF) != 0uwb + || testu192 (-0.5DF) != 0uwb + || testu192 (42.99999DF) != 42uwb + || testu192 (42.e+21DF) != 42000000000000000000000uwb + || testu192 (3427.231e+29DF) != 342723100000000000000000000000000uwb + || testu192 (6277101.0e+51DF) != 6277101000000000000000000000000000000000000000000000000000uwb) + __builtin_abort (); + if (testu192 (-1.DF) != 0uwb + || testu192 (-42.5e+15DF) != 0uwb + || testu192 (-9999999e+90DF) != 0uwb + || testu192 (6277102.0e+51DF) != 6277101735386680763835789423207666416102355444464034512895uwb + || testu192 (9999999e+90DF) != 6277101735386680763835789423207666416102355444464034512895uwb) + __builtin_abort (); +#endif +#if __BITINT_MAXWIDTH__ >= 575 + if (tests575 (0.DF) != 0wb + || tests575 (0.999999DF) != 0wb + || tests575 (12.9999DF) != 12wb + || tests575 (-89.5DF) != -89wb + || tests575 (-34242.31e+37DF) != -342423100000000000000000000000000000000000wb + || tests575 (-518326.2e+88DF) != -5183262000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb + || tests575 (9999999e+90DF) != 9999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb + || tests575 (-9999999e+90DF) != -9999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb) + __builtin_abort (); + if (testu575 (0.DF) != 0uwb + || testu575 (0.5555555DF) != 0uwb + || testu575 (-0.7777777DF) != 0uwb + || testu575 (-0.99DF) != 0uwb + || testu575 (42.99999DF) != 42uwb + || testu575 (42.e+21DF) != 42000000000000000000000uwb + || testu575 (9427.231e+27DF) != 9427231000000000000000000000000uwb + || testu575 (9999999e+90DF) != 9999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb) + __builtin_abort (); + if (testu575 (-1.DF) != 0uwb + || testu575 (-42.5e+15DF) != 0uwb + || testu575 (-9999999e+90DF) != 0uwb) + __builtin_abort (); +#endif +} --- gcc/testsuite/gcc.dg/dfp/bitint-3.c.jj 2023-08-04 19:35:27.738431329 +0200 +++ gcc/testsuite/gcc.dg/dfp/bitint-3.c 2023-08-04 19:37:45.922527271 +0200 @@ -0,0 +1,98 @@ +/* PR c/102989 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2 -std=c2x -pedantic-errors" } */ + +#if __BITINT_MAXWIDTH__ >= 192 +__attribute__((noipa)) _BitInt(192) +tests192 (_Decimal128 d) +{ + return d; +} + +__attribute__((noipa)) unsigned _BitInt(192) +testu192 (_Decimal128 d) +{ + return d; +} +#endif + +#if __BITINT_MAXWIDTH__ >= 575 +__attribute__((noipa)) _BitInt(575) +tests575 (_Decimal128 d) +{ + return d; +} + +__attribute__((noipa)) unsigned _BitInt(575) +testu575 (_Decimal128 d) +{ + return d; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 192 + if (tests192 (0.DL) != 0wb + || tests192 (0.9999999999999999999999999999999999DL) != 0wb + || tests192 (7.999999999999999999999999999999999DL) != 7wb + || tests192 (-42.5DL) != -42wb + || tests192 (-34242319854.45429439857871298745432e+27DL) != -34242319854454294398578712987454320000wb + || tests192 (-213855087769445.9e+43DL) != -2138550877694459000000000000000000000000000000000000000000wb + || tests192 (3138550867693340381917894711603833.0e+24DL) != 3138550867693340381917894711603833000000000000000000000000wb + || tests192 (-3138550867693340381917894711603833.0e+24DL) != -3138550867693340381917894711603833000000000000000000000000wb) + __builtin_abort (); + if (tests192 (3138550867693340381917894711603834.0e+24DL) != 3138550867693340381917894711603833208051177722232017256447wb + || tests192 (9999999999999999999999999999999999e+6111DL) != 3138550867693340381917894711603833208051177722232017256447wb + || tests192 (-3138550867693340381917894711603834.0e+24DL) != -3138550867693340381917894711603833208051177722232017256447wb - 1wb + || tests192 (-9999999999999999999999999999999999e+6111DL) != -3138550867693340381917894711603833208051177722232017256447wb - 1wb) + __builtin_abort (); + if (testu192 (0.DL) != 0uwb + || testu192 (0.9999999999999999999999999999999999DL) != 0uwb + || testu192 (-0.9999999999999999999999999999999999DL) != 0uwb + || testu192 (-0.5DL) != 0uwb + || testu192 (42.99999999999999999999999999999999DL) != 42uwb + || testu192 (42.e+21DL) != 42000000000000000000000uwb + || testu192 (34242319854.45429439857871298745432e+21DL) != 34242319854454294398578712987454uwb + || testu192 (6277101735386680763835789423207666.0e+24DL) != 6277101735386680763835789423207666000000000000000000000000uwb) + __builtin_abort (); + if (testu192 (-1.DL) != 0uwb + || testu192 (-42.5e+15DL) != 0uwb + || testu192 (-9999999999999999999999999999999999e+6111DL) != 0uwb + || testu192 (6277101735386680763835789423207667.0e+24DL) != 6277101735386680763835789423207666416102355444464034512895uwb + || testu192 (9999999999999999999999999999999999e+6111DL) != 6277101735386680763835789423207666416102355444464034512895uwb) + __builtin_abort (); +#endif +#if __BITINT_MAXWIDTH__ >= 575 + if (tests575 (0.DL) != 0wb + || tests575 (0.999999999999999999999DL) != 0wb + || tests575 (12.99999999999999999999999999999DL) != 12wb + || tests575 (-89.5DL) != -89wb + || tests575 (-34242319854.45429986754986758972345e+37DL) != -342423198544542998675498675897234500000000000000wb + || tests575 (-518326003682761.2e+158DL) != -51832600368276120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb + || tests575 (6183260036827613351512563025491179.0e+139DL) != 61832600368276133515125630254911790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb + || tests575 (-6183260036827613351512563025491179.0e+139DL) != -61832600368276133515125630254911790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000wb) + __builtin_abort (); + if (tests575 (618326003682761335151256302549118.0e+140DL) != 61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb + || tests575 (9999999999999999999999999999999999e+6111DL) != 61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb + || tests575 (-6183260036827613351512563025491180.0e+139DL) != -61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb - 1wb + || tests575 (-9999999999999999999999999999999999e+6111DL) != -61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb - 1wb) + __builtin_abort (); + if (testu575 (0.DL) != 0uwb + || testu575 (0.5555555555555555555555555555555555DL) != 0uwb + || testu575 (-0.7777777777777777777777777777777777DL) != 0uwb + || testu575 (-0.99DL) != 0uwb + || testu575 (42.99999999999999999999999999999999DL) != 42uwb + || testu575 (42.e+21DL) != 42000000000000000000000uwb + || testu575 (94272319854.45429e+27DL) != 94272319854454290000000000000000000000uwb + || testu575 (1236652007365522670302512605098235.0e+140DL) != 123665200736552267030251260509823500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb) + __builtin_abort (); + if (testu575 (-1.DL) != 0uwb + || testu575 (-42.5e+15DL) != 0uwb + || testu575 (-9999999999999999999999999999999999e+6111DL) != 0uwb + || testu575 (1236652007365522670302512605098236.0e+140DL) != 123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb + || testu575 (9999999999999999999999999999999999e+6111DL) != 123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb) + __builtin_abort (); +#endif +} --- libgcc/config/t-softfp.jj 2023-07-17 09:35:07.802912565 +0200 +++ libgcc/config/t-softfp 2023-08-04 19:12:27.067454432 +0200 @@ -65,6 +65,12 @@ softfp_float_funcs = add$(m)3 div$(m)3 e softfp_floatint_funcs = fix$(m)$(i) fixuns$(m)$(i) \ float$(i)$(m) floatun$(i)$(m) softfp_floatbitint_funcs = fix$(m)bitint floatbitint$(m) +softfp_bid_list := +ifeq ($(decimal_float),yes) +ifeq ($(enable_decimal_float),bid) +softfp_bid_list += bitintpow10 $(foreach m,sd dd td,fix$(m)bitint) +endif +endif softfp_func_list := \ $(foreach m,$(softfp_float_modes), \ @@ -118,6 +124,8 @@ softfp_file_list := \ $(addsuffix .c,$(addprefix $(srcdir)/soft-fp/,$(softfp_func_list))) endif endif +softfp_bid_file_list := \ + $(addsuffix .c,$(addprefix $(srcdir)/soft-fp/,$(softfp_bid_list))) # Disable missing prototype and type limit warnings. The prototypes # for the functions in the soft-fp files have not been brought across @@ -131,6 +139,7 @@ soft-fp-objects = $(addsuffix $(objext), $(soft-fp-objects) : INTERNAL_CFLAGS += -Wno-missing-prototypes -Wno-type-limits LIB2ADD += $(softfp_file_list) +LIB2ADD_ST += $(softfp_bid_file_list) ifneq ($(softfp_exclude_libgcc2),y) # Functions in libgcc2.c are excluded for each soft-float mode (a --- libgcc/soft-fp/fixsdbitint.c.jj 2023-08-04 14:34:26.613747923 +0200 +++ libgcc/soft-fp/fixsdbitint.c 2023-08-04 14:43:18.104385171 +0200 @@ -0,0 +1,187 @@ +/* Software floating-point emulation. + Convert _Decimal32 to signed or unsigned _BitInt. + + 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 void __bid_fixsdbitint (UBILtype *, SItype, _Decimal32); + +void +__bid_fixsdbitint (UBILtype *r, SItype rprec, _Decimal32 a) +{ + FP_DECL_EX; + USItype arprec = rprec < 0 ? -rprec : rprec; + USItype rn = (arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + union { _Decimal32 d; USItype u; } u; + USItype mantissa, t; + SItype sgn; + SItype exponent; + USItype exp_bits, mant_bits; + UBILtype *pow10v, *resv; + USItype pow10_limbs, res_limbs, min_limbs, mant_limbs, low_zeros; + + FP_INIT_EXCEPTIONS; + u.d = a; + t = u.u >> 21; + sgn = (SItype) u.u < 0; + if ((t & (3 << 8)) != (3 << 8)) + { + mantissa = u.u & ((((USItype) 1) << 23) - 1); + exponent = (t >> 2) & 0xff; + } + else if ((t & (3 << 6)) != (3 << 6)) + { + mantissa = u.u & ((((USItype) 1) << 21) - 1); + mantissa |= ((USItype) 1) << 23; + exponent = t & 0xff; + if (mantissa > (USItype) 9999999) + mantissa = 0; + } + else + { + FP_SET_EXCEPTION (FP_EX_INVALID + | FP_EX_INVALID_CVI + | ((FP_EX_INVALID_SNAN + && ((t & 0x20)) != 0) + ? FP_EX_INVALID_SNAN : 0)); + ovf: + if (!sgn) + __builtin_memset (r, -1, rn * sizeof (UBILtype)); + else + __builtin_memset (r, 0, rn * sizeof (UBILtype)); + if (sgn ^ (rprec >= 0)) + r[BITINT_END (0, rn - 1)] + |= (UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE); + else + r[BITINT_END (0, rn - 1)] + &= ~((UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE)); + goto done; + } + exponent -= 101; + + if (mantissa == 0) + { + /* Zero (with any exponent). */ + zero: + __builtin_memset (r, 0, rn * sizeof (UBILtype)); + goto done; + } + if (exponent <= -7) + { + FP_SET_EXCEPTION (FP_EX_INEXACT); + goto zero; + } + else if (exponent < 0) + { + extern UDItype __bid_ten2k64[]; + UDItype d = __bid_ten2k64[-exponent]; + USItype rem = mantissa % (USItype) d; + mantissa /= (USItype) d; + if (rem) + FP_SET_EXCEPTION (FP_EX_INEXACT); + if (mantissa == 0) + goto zero; + exponent = 0; + } + + if (rprec >= 0 && sgn) + { + ovf_ex: + FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); + goto ovf; + } + + /* Lower estimate for number of bits needed for pow10 (exponent). */ + exp_bits = exponent / 3; + exp_bits = exp_bits * 10 - exp_bits / 29; + mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissa); + if (exp_bits + mant_bits > arprec + 1) + goto ovf_ex; + /* Upper estimate for number of bits needed for pow10 (exponent). */ + exp_bits = (exponent + 2) / 3; + exp_bits = exp_bits * 10 - exp_bits / 30; + if (exp_bits == 0) + exp_bits = 1; + pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + pow10v = __builtin_alloca (pow10_limbs * sizeof (UBILtype)); + low_zeros = __bid_pow10bitint (pow10v, exp_bits, exponent); + + res_limbs = ((exp_bits + mant_bits + BIL_TYPE_SIZE - 1) + / BIL_TYPE_SIZE) - low_zeros; + mant_limbs = 1; + resv = __builtin_alloca ((res_limbs + mant_limbs) * sizeof (UBILtype)); + resv[res_limbs] = mantissa; + __mulbitint3 (resv, exp_bits + mant_bits - low_zeros * BIL_TYPE_SIZE, + resv + res_limbs, mant_bits, + pow10v + BITINT_END (0, low_zeros), + exp_bits - low_zeros * BIL_TYPE_SIZE); + if (res_limbs + low_zeros >= rn) + { + if (res_limbs + low_zeros > rn && resv[BITINT_END (0, res_limbs - 1)]) + goto ovf_ex; + if ((arprec % BIL_TYPE_SIZE) != 0 + && (resv[BITINT_END (rn - res_limbs, rn - 1) - low_zeros] + & ((UBILtype) -1 << (arprec % BIL_TYPE_SIZE))) != 0) + goto ovf_ex; + min_limbs = rn - low_zeros; + } + else + min_limbs = res_limbs; + if (low_zeros) + __builtin_memset (r + BITINT_END (rn - low_zeros, 0), '\0', + low_zeros * sizeof (UBILtype)); + if (sgn) + bitint_negate (r + BITINT_END (rn - low_zeros - 1, low_zeros), + resv + BITINT_END (res_limbs - 1, 0), min_limbs); + else + __builtin_memcpy (r + BITINT_END (rn - low_zeros - min_limbs, low_zeros), + resv + BITINT_END (res_limbs - min_limbs, 0), + min_limbs * sizeof (UBILtype)); + if (res_limbs + low_zeros < rn) + { + if (sgn) + __builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), -1, + (rn - res_limbs - low_zeros) * sizeof (UBILtype)); + else + __builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), '\0', + (rn - res_limbs - low_zeros) * sizeof (UBILtype)); + } + else if (sgn) + { + if ((r[BITINT_END (0, rn - 1)] + & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) == 0) + goto ovf_ex; + } + else if (rprec < 0 + && (r[BITINT_END (0, rn - 1)] + & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) != 0) + goto ovf_ex; + +done: + FP_HANDLE_EXCEPTIONS; +} +#endif --- libgcc/soft-fp/fixddbitint.c.jj 2023-08-03 18:53:40.456511156 +0200 +++ libgcc/soft-fp/fixddbitint.c 2023-08-04 14:22:34.543612036 +0200 @@ -0,0 +1,197 @@ +/* Software floating-point emulation. + Convert _Decimal64 to signed or unsigned _BitInt. + + 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 void __bid_fixddbitint (UBILtype *, SItype, _Decimal64); + +void +__bid_fixddbitint (UBILtype *r, SItype rprec, _Decimal64 a) +{ + FP_DECL_EX; + USItype arprec = rprec < 0 ? -rprec : rprec; + USItype rn = (arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + union { _Decimal64 d; UDItype u; } u; + UDItype mantissa, t; + SItype sgn; + SItype exponent; + USItype exp_bits, mant_bits; + UBILtype *pow10v, *resv; + USItype pow10_limbs, res_limbs, min_limbs, mant_limbs, low_zeros; + + FP_INIT_EXCEPTIONS; + u.d = a; + t = u.u >> 51; + sgn = (DItype) u.u < 0; + if ((t & (3 << 10)) != (3 << 10)) + { + mantissa = u.u & ((((UDItype) 1) << 53) - 1); + exponent = (t >> 2) & 0x3ff; + } + else if ((t & (3 << 8)) != (3 << 8)) + { + mantissa = u.u & ((((UDItype) 1) << 51) - 1); + mantissa |= ((UDItype) 1) << 53; + exponent = t & 0x3ff; + if (mantissa > (UDItype) 9999999999999999) + mantissa = 0; + } + else + { + FP_SET_EXCEPTION (FP_EX_INVALID + | FP_EX_INVALID_CVI + | ((FP_EX_INVALID_SNAN + && ((t & 0x80)) != 0) + ? FP_EX_INVALID_SNAN : 0)); + ovf: + if (!sgn) + __builtin_memset (r, -1, rn * sizeof (UBILtype)); + else + __builtin_memset (r, 0, rn * sizeof (UBILtype)); + if (sgn ^ (rprec >= 0)) + r[BITINT_END (0, rn - 1)] + |= (UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE); + else + r[BITINT_END (0, rn - 1)] + &= ~((UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE)); + goto done; + } + exponent -= 398; + + if (mantissa == 0) + { + /* Zero (with any exponent). */ + zero: + __builtin_memset (r, 0, rn * sizeof (UBILtype)); + goto done; + } + if (exponent <= -16) + { + FP_SET_EXCEPTION (FP_EX_INEXACT); + goto zero; + } + else if (exponent < 0) + { + extern UDItype __bid_ten2k64[]; + UDItype d = __bid_ten2k64[-exponent]; + UDItype rem = mantissa % d; + mantissa /= d; + if (rem) + FP_SET_EXCEPTION (FP_EX_INEXACT); + if (mantissa == 0) + goto zero; + exponent = 0; + } + + if (rprec >= 0 && sgn) + { + ovf_ex: + FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); + goto ovf; + } + + /* Lower estimate for number of bits needed for pow10 (exponent). */ + exp_bits = exponent / 3; + exp_bits = exp_bits * 10 - exp_bits / 29; + mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissa); + if (exp_bits + mant_bits > arprec + 1) + goto ovf_ex; + /* Upper estimate for number of bits needed for pow10 (exponent). */ + exp_bits = (exponent + 2) / 3; + exp_bits = exp_bits * 10 - exp_bits / 30; + if (exp_bits == 0) + exp_bits = 1; + pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + pow10v = __builtin_alloca (pow10_limbs * sizeof (UBILtype)); + low_zeros = __bid_pow10bitint (pow10v, exp_bits, exponent); + + res_limbs = ((exp_bits + mant_bits + BIL_TYPE_SIZE - 1) + / BIL_TYPE_SIZE) - low_zeros; + mant_limbs = (mant_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + resv = __builtin_alloca ((res_limbs + mant_limbs) * sizeof (UBILtype)); +#if BIL_TYPE_SIZE >= 64 + resv[res_limbs] = mantissa; +#else + if (mant_limbs == 1) + resv[res_limbs] = mantissa; + else + { + resv[res_limbs + BITINT_END (1, 0)] = mantissa; + resv[res_limbs + BITINT_END (0, 1)] = mantissa >> 32; + } +#endif + __mulbitint3 (resv, exp_bits + mant_bits - low_zeros * BIL_TYPE_SIZE, + resv + res_limbs, mant_bits, + pow10v + BITINT_END (0, low_zeros), + exp_bits - low_zeros * BIL_TYPE_SIZE); + if (res_limbs + low_zeros >= rn) + { + if (res_limbs + low_zeros > rn && resv[BITINT_END (0, res_limbs - 1)]) + goto ovf_ex; + if ((arprec % BIL_TYPE_SIZE) != 0 + && (resv[BITINT_END (rn - res_limbs, rn - 1) - low_zeros] + & ((UBILtype) -1 << (arprec % BIL_TYPE_SIZE))) != 0) + goto ovf_ex; + min_limbs = rn - low_zeros; + } + else + min_limbs = res_limbs; + if (low_zeros) + __builtin_memset (r + BITINT_END (rn - low_zeros, 0), '\0', + low_zeros * sizeof (UBILtype)); + if (sgn) + bitint_negate (r + BITINT_END (rn - low_zeros - 1, low_zeros), + resv + BITINT_END (res_limbs - 1, 0), min_limbs); + else + __builtin_memcpy (r + BITINT_END (rn - low_zeros - min_limbs, low_zeros), + resv + BITINT_END (res_limbs - min_limbs, 0), + min_limbs * sizeof (UBILtype)); + if (res_limbs + low_zeros < rn) + { + if (sgn) + __builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), -1, + (rn - res_limbs - low_zeros) * sizeof (UBILtype)); + else + __builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), '\0', + (rn - res_limbs - low_zeros) * sizeof (UBILtype)); + } + else if (sgn) + { + if ((r[BITINT_END (0, rn - 1)] + & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) == 0) + goto ovf_ex; + } + else if (rprec < 0 + && (r[BITINT_END (0, rn - 1)] + & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) != 0) + goto ovf_ex; + +done: + FP_HANDLE_EXCEPTIONS; +} +#endif --- libgcc/soft-fp/fixtdbitint.c.jj 2023-08-04 18:19:17.986391454 +0200 +++ libgcc/soft-fp/fixtdbitint.c 2023-08-04 19:11:20.053377659 +0200 @@ -0,0 +1,264 @@ +/* Software floating-point emulation. + Convert _Decimal128 to signed or unsigned _BitInt. + + 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 void __bid_fixtdbitint (UBILtype *, SItype, _Decimal128); + +void +__bid_fixtdbitint (UBILtype *r, SItype rprec, _Decimal128 a) +{ + FP_DECL_EX; + USItype arprec = rprec < 0 ? -rprec : rprec; + USItype rn = (arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + union { _Decimal128 d; UDItype u[2]; } u; + UDItype mantissahi, mantissalo, t; + SItype sgn; + SItype exponent; + USItype exp_bits, mant_bits; + UBILtype *pow10v, *resv; + USItype pow10_limbs, res_limbs, min_limbs, mant_limbs, low_zeros; + + FP_INIT_EXCEPTIONS; + u.d = a; + mantissahi = u.u[__FLOAT_WORD_ORDER__ != __ORDER_BIG_ENDIAN__]; + mantissalo = u.u[__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__]; + t = mantissahi >> 47; + sgn = (DItype) mantissahi < 0; + if ((t & (3 << 14)) != (3 << 14)) + { + mantissahi &= ((((UDItype) 1) << 49) - 1); + exponent = (t >> 2) & 0x3fff; + } + else if ((t & (3 << 12)) != (3 << 12)) + { + mantissahi &= ((((UDItype) 1) << 47) - 1); + mantissahi |= ((UDItype) 1) << 49; + exponent = t & 0x3fff; + if (mantissahi > (UDItype) 0x1ed09bead87c0 + || (mantissahi == (UDItype) 0x1ed09bead87c0 + && mantissalo > 0x378d8e63ffffffff)) + { + mantissahi = 0; + mantissalo = 0; + } + } + else + { + FP_SET_EXCEPTION (FP_EX_INVALID + | FP_EX_INVALID_CVI + | ((FP_EX_INVALID_SNAN + && ((t & 0x800)) != 0) + ? FP_EX_INVALID_SNAN : 0)); + ovf: + if (!sgn) + __builtin_memset (r, -1, rn * sizeof (UBILtype)); + else + __builtin_memset (r, 0, rn * sizeof (UBILtype)); + if (sgn ^ (rprec >= 0)) + r[BITINT_END (0, rn - 1)] + |= (UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE); + else + r[BITINT_END (0, rn - 1)] + &= ~((UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE)); + goto done; + } + exponent -= 6176; + + if (mantissahi == 0 && mantissalo == 0) + { + /* Zero (with any exponent). */ + zero: + __builtin_memset (r, 0, rn * sizeof (UBILtype)); + goto done; + } + if (exponent <= -34) + { + FP_SET_EXCEPTION (FP_EX_INEXACT); + goto zero; + } + if (exponent < 0) + { + extern UDItype __bid_ten2k64[]; + typedef __attribute__ ((aligned(16))) struct { UDItype w[2]; } UINT128; + extern UINT128 __bid_ten2k128[]; + UBILtype limbs[4 * 128 / BIL_TYPE_SIZE]; +#if BIL_TYPE_SIZE == 64 + limbs[BITINT_END (0, 1)] = mantissahi; + limbs[BITINT_END (1, 0)] = mantissalo; + if (exponent >= -19) + limbs[2] = __bid_ten2k64[-exponent]; + else + { + limbs[BITINT_END (2, 3)] = __bid_ten2k128[-20 - exponent].w[1]; + limbs[BITINT_END (3, 2)] = __bid_ten2k128[-20 - exponent].w[0]; + } +#elif BIL_TYPE_SIZE == 32 + limbs[BITINT_END (0, 3)] = mantissahi >> 32; + limbs[BITINT_END (1, 2)] = mantissahi; + limbs[BITINT_END (2, 1)] = mantissalo >> 32; + limbs[BITINT_END (3, 0)] = mantissalo; + if (exponent >= -19) + { + limbs[BITINT_END (4, 5)] = __bid_ten2k64[-exponent] >> 32; + limbs[BITINT_END (5, 4)] = __bid_ten2k64[-exponent]; + } + else + { + limbs[BITINT_END (4, 7)] = __bid_ten2k128[-20 - exponent].w[1] >> 32; + limbs[BITINT_END (5, 6)] = __bid_ten2k128[-20 - exponent].w[1]; + limbs[BITINT_END (6, 5)] = __bid_ten2k128[-20 - exponent].w[0] >> 32; + limbs[BITINT_END (7, 4)] = __bid_ten2k128[-20 - exponent].w[0]; + } +#elif +# error Unhandled BIL_TYPE_SIZE +#endif + __divmodbitint4 (&limbs[2 * 128 / BIL_TYPE_SIZE], 128, + &limbs[3 * 128 / BIL_TYPE_SIZE], 128, + &limbs[0], 128, &limbs[128 / BIL_TYPE_SIZE], + exponent >= -19 ? 64 : 128); + UDItype rem; +#if BIL_TYPE_SIZE == 64 + mantissahi = limbs[BITINT_END (4, 5)]; + mantissalo = limbs[BITINT_END (5, 4)]; + rem = limbs[6] | limbs[7]; +#elif BIL_TYPE_SIZE == 32 + mantissahi = limbs[BITINT_END (8, 11)] << 32; + mantissahi |= limbs[BITINT_END (9, 10)]; + mantissalo = limbs[BITINT_END (10, 9)] << 32; + mantissalo |= limbs[BITINT_END (11, 8)]; + rem = limbs[12] | limbs[13] | limbs[14] | limbs[15]; +#endif + if (rem) + FP_SET_EXCEPTION (FP_EX_INEXACT); + if (mantissahi == 0 && mantissalo == 0) + goto zero; + exponent = 0; + } + + if (rprec >= 0 && sgn) + { + ovf_ex: + FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); + goto ovf; + } + + /* Lower estimate for number of bits needed for pow10 (exponent). */ + exp_bits = exponent / 3; + exp_bits = exp_bits * 10 - exp_bits / 29; + if (mantissahi) + mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissahi) + + 64; + else + mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissalo); + if (exp_bits + mant_bits > arprec + 1) + goto ovf_ex; + /* Upper estimate for number of bits needed for pow10 (exponent). */ + exp_bits = (exponent + 2) / 3; + exp_bits = exp_bits * 10 - exp_bits / 30; + if (exp_bits == 0) + exp_bits = 1; + pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + pow10v = __builtin_alloca (pow10_limbs * sizeof (UBILtype)); + low_zeros = __bid_pow10bitint (pow10v, exp_bits, exponent); + + res_limbs = ((exp_bits + mant_bits + BIL_TYPE_SIZE - 1) + / BIL_TYPE_SIZE) - low_zeros; + mant_limbs = (mant_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + resv = __builtin_alloca ((res_limbs + mant_limbs) * sizeof (UBILtype)); +#if BIL_TYPE_SIZE >= 64 + if (mant_limbs == 1) + resv[res_limbs] = mantissalo; + else + { + resv[res_limbs + BITINT_END (1, 0)] = mantissalo; + resv[res_limbs + BITINT_END (0, 1)] = mantissahi; + } +#else + resv[res_limbs + BITINT_END (mant_limbs - 1, 0)] = mantissalo; + if (mant_limbs >= 2) + { + resv[res_limbs + BITINT_END (mant_limbs - 2, 1)] = mantissalo >> 32; + if (mant_limbs >= 3) + { + resv[res_limbs + BITINT_END (mant_limbs - 3, 2)] = mantissahi; + if (mant_limbs == 4) + resv[res_limbs + BITINT_END (0, 3)] = mantissahi >> 32; + } + } +#endif + __mulbitint3 (resv, exp_bits + mant_bits - low_zeros * BIL_TYPE_SIZE, + resv + res_limbs, mant_bits, + pow10v + BITINT_END (0, low_zeros), + exp_bits - low_zeros * BIL_TYPE_SIZE); + if (res_limbs + low_zeros >= rn) + { + if (res_limbs + low_zeros > rn && resv[BITINT_END (0, res_limbs - 1)]) + goto ovf_ex; + if ((arprec % BIL_TYPE_SIZE) != 0 + && (resv[BITINT_END (rn - res_limbs, rn - 1) - low_zeros] + & ((UBILtype) -1 << (arprec % BIL_TYPE_SIZE))) != 0) + goto ovf_ex; + min_limbs = rn - low_zeros; + } + else + min_limbs = res_limbs; + if (low_zeros) + __builtin_memset (r + BITINT_END (rn - low_zeros, 0), '\0', + low_zeros * sizeof (UBILtype)); + if (sgn) + bitint_negate (r + BITINT_END (rn - low_zeros - 1, low_zeros), + resv + BITINT_END (res_limbs - 1, 0), min_limbs); + else + __builtin_memcpy (r + BITINT_END (rn - low_zeros - min_limbs, low_zeros), + resv + BITINT_END (res_limbs - min_limbs, 0), + min_limbs * sizeof (UBILtype)); + if (res_limbs + low_zeros < rn) + { + if (sgn) + __builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), -1, + (rn - res_limbs - low_zeros) * sizeof (UBILtype)); + else + __builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), '\0', + (rn - res_limbs - low_zeros) * sizeof (UBILtype)); + } + else if (sgn) + { + if ((r[BITINT_END (0, rn - 1)] + & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) == 0) + goto ovf_ex; + } + else if (rprec < 0 + && (r[BITINT_END (0, rn - 1)] + & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) != 0) + goto ovf_ex; + +done: + FP_HANDLE_EXCEPTIONS; +} +#endif --- libgcc/soft-fp/bitint.h.jj 2023-07-14 23:35:51.539466644 +0200 +++ libgcc/soft-fp/bitint.h 2023-08-04 18:47:43.753878151 +0200 @@ -160,6 +160,21 @@ bitint_reduce_prec (const UBILtype **p, # define BITINT_END(be, le) (le) #endif +static inline __attribute__((__always_inline__)) void +bitint_negate (UBILtype *d, const UBILtype *s, SItype n) +{ + UBILtype c = 1; + do + { + UBILtype sv = *s, lo; + s += BITINT_INC; + c = __builtin_add_overflow (~sv, c, &lo); + *d = lo; + d += BITINT_INC; + } + while (--n); +} + #define FP_TO_BITINT(r, rn, arprec, shift, rv, rsize, rsigned, ovf, DI) \ if (ovf) \ { \ @@ -301,6 +316,14 @@ bitint_reduce_prec (const UBILtype **p, } \ while (0) +extern void __mulbitint3 (UBILtype *, SItype, const UBILtype *, SItype, + const UBILtype *, SItype); +extern void __divmodbitint4 (UBILtype *, SItype, UBILtype *, SItype, + const UBILtype *, SItype, + const UBILtype *, SItype); + +extern USItype __bid_pow10bitint (UBILtype *, SItype, USItype); + #endif /* __BITINT_MAXWIDTH__ */ #endif /* GCC_SOFT_FP_BITINT_H */