libgcc: Add {unsigned ,}__int128 <-> _Decimal{32,64,128} conversion support [PR65833]

Message ID ZUsw14bVvAyCni7X@tucnak
State Unresolved
Headers
Series libgcc: Add {unsigned ,}__int128 <-> _Decimal{32,64,128} conversion support [PR65833] |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Jakub Jelinek Nov. 8, 2023, 6:55 a.m. UTC
  Hi!

The following patch adds the missing
{unsigned ,}__int128 <-> _Decimal{32,64,128}
conversion support into libgcc.a on top of the _BitInt support
(doing it without that would be larger amount of code and I hope all
the targets which support __int128 will eventually support _BitInt,
after all it is a required part of C23) and because it is in libgcc.a
only, it doesn't hurt that much if it is added for some architectures
only in GCC 15.
Initially I thought about doing this on the compiler side, but doing
it on the library side seems to be easier and more -Os friendly.
The tests currently require bitint effective target, that can be
removed when all the int128 targets support bitint.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2023-11-08  Jakub Jelinek  <jakub@redhat.com>

	PR libgcc/65833
libgcc/
	* config/t-softfp (softfp_bid_list): Add
	{U,}TItype <-> _Decimal{32,64,128} conversions.
	* soft-fp/floattisd.c: New file.
	* soft-fp/floattidd.c: New file.
	* soft-fp/floattitd.c: New file.
	* soft-fp/floatuntisd.c: New file.
	* soft-fp/floatuntidd.c: New file.
	* soft-fp/floatuntitd.c: New file.
	* soft-fp/fixsdti.c: New file.
	* soft-fp/fixddti.c: New file.
	* soft-fp/fixtdti.c: New file.
	* soft-fp/fixunssdti.c: New file.
	* soft-fp/fixunsddti.c: New file.
	* soft-fp/fixunstdti.c: New file.
gcc/testsuite/
	* gcc.dg/dfp/int128-1.c: New test.
	* gcc.dg/dfp/int128-2.c: New test.
	* gcc.dg/dfp/int128-3.c: New test.
	* gcc.dg/dfp/int128-4.c: New test.


	Jakub
  

Comments

Joseph Myers Nov. 8, 2023, 6:07 p.m. UTC | #1
On Wed, 8 Nov 2023, Jakub Jelinek wrote:

> Hi!
> 
> The following patch adds the missing
> {unsigned ,}__int128 <-> _Decimal{32,64,128}
> conversion support into libgcc.a on top of the _BitInt support
> (doing it without that would be larger amount of code and I hope all
> the targets which support __int128 will eventually support _BitInt,
> after all it is a required part of C23) and because it is in libgcc.a
> only, it doesn't hurt that much if it is added for some architectures
> only in GCC 15.
> Initially I thought about doing this on the compiler side, but doing
> it on the library side seems to be easier and more -Os friendly.
> The tests currently require bitint effective target, that can be
> removed when all the int128 targets support bitint.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.
  

Patch

--- libgcc/config/t-softfp.jj	2023-09-08 11:29:20.142767499 +0200
+++ libgcc/config/t-softfp	2023-11-06 10:55:19.117642736 +0100
@@ -69,7 +69,9 @@  softfp_bid_list :=
 ifeq ($(decimal_float),yes)
 ifeq ($(enable_decimal_float),bid)
 softfp_bid_list += bitintpow10 \
-		   $(foreach m,sd dd td,fix$(m)bitint floatbitint$(m))
+		   $(foreach m,sd dd td,fix$(m)bitint floatbitint$(m) \
+					fix$(m)ti fixuns$(m)ti \
+					floatti$(m) floatunti$(m))
 endif
 endif
 
--- libgcc/soft-fp/floattisd.c.jj	2023-11-06 09:58:23.431361481 +0100
+++ libgcc/soft-fp/floattisd.c	2023-11-06 09:58:56.149904156 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert a 128bit signed integer 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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern _Decimal32 __bid_floatbitintsd (const UBILtype *, SItype);
+extern _Decimal32 __bid_floattisd (TItype);
+
+_Decimal32
+__bid_floattisd (TItype i)
+{
+  UBILtype ib[128 / BIL_TYPE_SIZE];
+#if BIL_TYPE_SIZE == 128
+  ib[0] = i;
+#elif BIL_TYPE_SIZE == 64
+  ib[BITINT_END (0, 1)] = i >> 64;
+  ib[BITINT_END (1, 0)] = i;
+#elif BIL_TYPE_SIZE == 32
+  ib[BITINT_END (0, 3)] = i >> 96;
+  ib[BITINT_END (1, 2)] = i >> 64;
+  ib[BITINT_END (2, 1)] = i >> 32;
+  ib[BITINT_END (3, 0)] = i;
+#else
+#error Unsupported UBILtype
+#endif
+  return __bid_floatbitintsd (ib, -128);
+}
+#endif
--- libgcc/soft-fp/floattidd.c.jj	2023-11-06 09:50:17.991146599 +0100
+++ libgcc/soft-fp/floattidd.c	2023-11-06 09:57:58.283712969 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert a 128bit signed integer 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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern _Decimal64 __bid_floatbitintdd (const UBILtype *, SItype);
+extern _Decimal64 __bid_floattidd (TItype);
+
+_Decimal64
+__bid_floattidd (TItype i)
+{
+  UBILtype ib[128 / BIL_TYPE_SIZE];
+#if BIL_TYPE_SIZE == 128
+  ib[0] = i;
+#elif BIL_TYPE_SIZE == 64
+  ib[BITINT_END (0, 1)] = i >> 64;
+  ib[BITINT_END (1, 0)] = i;
+#elif BIL_TYPE_SIZE == 32
+  ib[BITINT_END (0, 3)] = i >> 96;
+  ib[BITINT_END (1, 2)] = i >> 64;
+  ib[BITINT_END (2, 1)] = i >> 32;
+  ib[BITINT_END (3, 0)] = i;
+#else
+#error Unsupported UBILtype
+#endif
+  return __bid_floatbitintdd (ib, -128);
+}
+#endif
--- libgcc/soft-fp/floattitd.c.jj	2023-11-06 09:58:26.617316947 +0100
+++ libgcc/soft-fp/floattitd.c	2023-11-06 09:59:17.116611100 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert a 128bit signed integer 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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern _Decimal128 __bid_floatbitinttd (const UBILtype *, SItype);
+extern _Decimal128 __bid_floattitd (TItype);
+
+_Decimal128
+__bid_floattitd (TItype i)
+{
+  UBILtype ib[128 / BIL_TYPE_SIZE];
+#if BIL_TYPE_SIZE == 128
+  ib[0] = i;
+#elif BIL_TYPE_SIZE == 64
+  ib[BITINT_END (0, 1)] = i >> 64;
+  ib[BITINT_END (1, 0)] = i;
+#elif BIL_TYPE_SIZE == 32
+  ib[BITINT_END (0, 3)] = i >> 96;
+  ib[BITINT_END (1, 2)] = i >> 64;
+  ib[BITINT_END (2, 1)] = i >> 32;
+  ib[BITINT_END (3, 0)] = i;
+#else
+#error Unsupported UBILtype
+#endif
+  return __bid_floatbitinttd (ib, -128);
+}
+#endif
--- libgcc/soft-fp/floatuntisd.c.jj	2023-11-06 10:03:00.276491936 +0100
+++ libgcc/soft-fp/floatuntisd.c	2023-11-06 10:03:21.106200789 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert a 128bit unsigned integer 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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern _Decimal32 __bid_floatbitintsd (const UBILtype *, SItype);
+extern _Decimal32 __bid_floatunstisd (UTItype);
+
+_Decimal32
+__bid_floatunstisd (UTItype i)
+{
+  UBILtype ib[128 / BIL_TYPE_SIZE];
+#if BIL_TYPE_SIZE == 128
+  ib[0] = i;
+#elif BIL_TYPE_SIZE == 64
+  ib[BITINT_END (0, 1)] = i >> 64;
+  ib[BITINT_END (1, 0)] = i;
+#elif BIL_TYPE_SIZE == 32
+  ib[BITINT_END (0, 3)] = i >> 96;
+  ib[BITINT_END (1, 2)] = i >> 64;
+  ib[BITINT_END (2, 1)] = i >> 32;
+  ib[BITINT_END (3, 0)] = i;
+#else
+#error Unsupported UBILtype
+#endif
+  return __bid_floatbitintsd (ib, 128);
+}
+#endif
--- libgcc/soft-fp/floatuntidd.c.jj	2023-11-06 10:00:55.913230197 +0100
+++ libgcc/soft-fp/floatuntidd.c	2023-11-06 10:02:29.867916966 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert a 128bit unsigned integer 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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern _Decimal64 __bid_floatbitintdd (const UBILtype *, SItype);
+extern _Decimal64 __bid_floatunstidd (UTItype);
+
+_Decimal64
+__bid_floatunstidd (UTItype i)
+{
+  UBILtype ib[128 / BIL_TYPE_SIZE];
+#if BIL_TYPE_SIZE == 128
+  ib[0] = i;
+#elif BIL_TYPE_SIZE == 64
+  ib[BITINT_END (0, 1)] = i >> 64;
+  ib[BITINT_END (1, 0)] = i;
+#elif BIL_TYPE_SIZE == 32
+  ib[BITINT_END (0, 3)] = i >> 96;
+  ib[BITINT_END (1, 2)] = i >> 64;
+  ib[BITINT_END (2, 1)] = i >> 32;
+  ib[BITINT_END (3, 0)] = i;
+#else
+#error Unsupported UBILtype
+#endif
+  return __bid_floatbitintdd (ib, 128);
+}
+#endif
--- libgcc/soft-fp/floatuntitd.c.jj	2023-11-06 10:03:00.276491936 +0100
+++ libgcc/soft-fp/floatuntitd.c	2023-11-06 10:15:02.180379956 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert a 128bit unsigned integer 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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern _Decimal128 __bid_floatbitinttd (const UBILtype *, SItype);
+extern _Decimal128 __bid_floatunstitd (UTItype);
+
+_Decimal128
+__bid_floatunstitd (UTItype i)
+{
+  UBILtype ib[128 / BIL_TYPE_SIZE];
+#if BIL_TYPE_SIZE == 128
+  ib[0] = i;
+#elif BIL_TYPE_SIZE == 64
+  ib[BITINT_END (0, 1)] = i >> 64;
+  ib[BITINT_END (1, 0)] = i;
+#elif BIL_TYPE_SIZE == 32
+  ib[BITINT_END (0, 3)] = i >> 96;
+  ib[BITINT_END (1, 2)] = i >> 64;
+  ib[BITINT_END (2, 1)] = i >> 32;
+  ib[BITINT_END (3, 0)] = i;
+#else
+#error Unsupported UBILtype
+#endif
+  return __bid_floatbitinttd (ib, 128);
+}
+#endif
--- libgcc/soft-fp/fixsdti.c.jj	2023-11-06 10:39:50.102583634 +0100
+++ libgcc/soft-fp/fixsdti.c	2023-11-06 11:00:57.803925116 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert _Decimal32 to 128bit signed integer.
+
+   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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern void __bid_fixsdbitint (UBILtype *, SItype, _Decimal32);
+extern TItype __bid_fixsdti (_Decimal32);
+
+TItype
+__bid_fixsdti (_Decimal32 a)
+{
+  UBILtype rb[128 / BIL_TYPE_SIZE];
+  __bid_fixsdbitint (rb, -128, a);
+#if BIL_TYPE_SIZE == 128
+  return rb[0];
+#elif BIL_TYPE_SIZE == 64
+  return ((((UTItype) rb[BITINT_END (0, 1)]) << 64)
+	  | rb[BITINT_END (1, 0)]);
+#elif BIL_TYPE_SIZE == 32
+  return ((((UTItype) rb[BITINT_END (0, 3)]) << 96)
+	  | (((UTItype) rb[BITINT_END (1, 2)]) << 64)
+	  | (((UTItype) rb[BITINT_END (2, 1)]) << 32)
+	  | rb[BITINT_END (3, 0)]);
+#else
+#error Unsupported UBILtype
+#endif
+}
+#endif
--- libgcc/soft-fp/fixddti.c.jj	2023-11-06 10:18:50.331181186 +0100
+++ libgcc/soft-fp/fixddti.c	2023-11-06 11:00:45.980089838 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert _Decimal64 to 128bit signed integer.
+
+   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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern void __bid_fixddbitint (UBILtype *, SItype, _Decimal64);
+extern TItype __bid_fixddti (_Decimal64);
+
+TItype
+__bid_fixddti (_Decimal64 a)
+{
+  UBILtype rb[128 / BIL_TYPE_SIZE];
+  __bid_fixddbitint (rb, -128, a);
+#if BIL_TYPE_SIZE == 128
+  return rb[0];
+#elif BIL_TYPE_SIZE == 64
+  return ((((UTItype) rb[BITINT_END (0, 1)]) << 64)
+	  | rb[BITINT_END (1, 0)]);
+#elif BIL_TYPE_SIZE == 32
+  return ((((UTItype) rb[BITINT_END (0, 3)]) << 96)
+	  | (((UTItype) rb[BITINT_END (1, 2)]) << 64)
+	  | (((UTItype) rb[BITINT_END (2, 1)]) << 32)
+	  | rb[BITINT_END (3, 0)]);
+#else
+#error Unsupported UBILtype
+#endif
+}
+#endif
--- libgcc/soft-fp/fixtdti.c.jj	2023-11-06 10:39:50.102583634 +0100
+++ libgcc/soft-fp/fixtdti.c	2023-11-06 11:01:08.438776966 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert _Decimal128 to 128bit signed integer.
+
+   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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern void __bid_fixtdbitint (UBILtype *, SItype, _Decimal128);
+extern TItype __bid_fixtdti (_Decimal128);
+
+TItype
+__bid_fixtdti (_Decimal128 a)
+{
+  UBILtype rb[128 / BIL_TYPE_SIZE];
+  __bid_fixtdbitint (rb, -128, a);
+#if BIL_TYPE_SIZE == 128
+  return rb[0];
+#elif BIL_TYPE_SIZE == 64
+  return ((((UTItype) rb[BITINT_END (0, 1)]) << 64)
+	  | rb[BITINT_END (1, 0)]);
+#elif BIL_TYPE_SIZE == 32
+  return ((((UTItype) rb[BITINT_END (0, 3)]) << 96)
+	  | (((UTItype) rb[BITINT_END (1, 2)]) << 64)
+	  | (((UTItype) rb[BITINT_END (2, 1)]) << 32)
+	  | rb[BITINT_END (3, 0)]);
+#else
+#error Unsupported UBILtype
+#endif
+}
+#endif
--- libgcc/soft-fp/fixunssdti.c.jj	2023-11-06 10:49:12.796744749 +0100
+++ libgcc/soft-fp/fixunssdti.c	2023-11-06 11:01:40.105335821 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert _Decimal32 to 128bit unsigned integer.
+
+   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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern void __bid_fixsdbitint (UBILtype *, SItype, _Decimal32);
+extern UTItype __bid_fixunssdti (_Decimal32);
+
+UTItype
+__bid_fixunssdti (_Decimal32 a)
+{
+  UBILtype rb[128 / BIL_TYPE_SIZE];
+  __bid_fixsdbitint (rb, 128, a);
+#if BIL_TYPE_SIZE == 128
+  return rb[0];
+#elif BIL_TYPE_SIZE == 64
+  return ((((UTItype) rb[BITINT_END (0, 1)]) << 64)
+	  | rb[BITINT_END (1, 0)]);
+#elif BIL_TYPE_SIZE == 32
+  return ((((UTItype) rb[BITINT_END (0, 3)]) << 96)
+	  | (((UTItype) rb[BITINT_END (1, 2)]) << 64)
+	  | (((UTItype) rb[BITINT_END (2, 1)]) << 32)
+	  | rb[BITINT_END (3, 0)]);
+#else
+#error Unsupported UBILtype
+#endif
+}
+#endif
--- libgcc/soft-fp/fixunsddti.c.jj	2023-11-06 10:47:58.828774945 +0100
+++ libgcc/soft-fp/fixunsddti.c	2023-11-06 11:01:25.695536562 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert _Decimal64 to 128bit unsigned integer.
+
+   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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern void __bid_fixddbitint (UBILtype *, SItype, _Decimal64);
+extern UTItype __bid_fixunsddti (_Decimal64);
+
+UTItype
+__bid_fixunsddti (_Decimal64 a)
+{
+  UBILtype rb[128 / BIL_TYPE_SIZE];
+  __bid_fixddbitint (rb, 128, a);
+#if BIL_TYPE_SIZE == 128
+  return rb[0];
+#elif BIL_TYPE_SIZE == 64
+  return ((((UTItype) rb[BITINT_END (0, 1)]) << 64)
+	  | rb[BITINT_END (1, 0)]);
+#elif BIL_TYPE_SIZE == 32
+  return ((((UTItype) rb[BITINT_END (0, 3)]) << 96)
+	  | (((UTItype) rb[BITINT_END (1, 2)]) << 64)
+	  | (((UTItype) rb[BITINT_END (2, 1)]) << 32)
+	  | rb[BITINT_END (3, 0)]);
+#else
+#error Unsupported UBILtype
+#endif
+}
+#endif
--- libgcc/soft-fp/fixunstdti.c.jj	2023-11-06 10:49:44.773299387 +0100
+++ libgcc/soft-fp/fixunstdti.c	2023-11-06 11:01:53.967142709 +0100
@@ -0,0 +1,53 @@ 
+/* Software floating-point emulation.
+   Convert _Decimal128 to 128bit unsigned integer.
+
+   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
+<http://www.gnu.org/licenses/>.  */
+
+#include "soft-fp.h"
+#include "bitint.h"
+
+#if defined(__BITINT_MAXWIDTH__) && defined(__SIZEOF_INT128__)
+extern void __bid_fixtdbitint (UBILtype *, SItype, _Decimal128);
+extern UTItype __bid_fixunstdti (_Decimal128);
+
+UTItype
+__bid_fixunstdti (_Decimal128 a)
+{
+  UBILtype rb[128 / BIL_TYPE_SIZE];
+  __bid_fixtdbitint (rb, 128, a);
+#if BIL_TYPE_SIZE == 128
+  return rb[0];
+#elif BIL_TYPE_SIZE == 64
+  return ((((UTItype) rb[BITINT_END (0, 1)]) << 64)
+	  | rb[BITINT_END (1, 0)]);
+#elif BIL_TYPE_SIZE == 32
+  return ((((UTItype) rb[BITINT_END (0, 3)]) << 96)
+	  | (((UTItype) rb[BITINT_END (1, 2)]) << 64)
+	  | (((UTItype) rb[BITINT_END (2, 1)]) << 32)
+	  | rb[BITINT_END (3, 0)]);
+#else
+#error Unsupported UBILtype
+#endif
+}
+#endif
--- gcc/testsuite/gcc.dg/dfp/int128-1.c.jj	2023-11-06 15:49:46.549527075 +0100
+++ gcc/testsuite/gcc.dg/dfp/int128-1.c	2023-11-06 16:40:15.085467914 +0100
@@ -0,0 +1,150 @@ 
+/* PR libgcc/65833 */
+/* { dg-do run { target { int128 && bitint } } } */
+/* { dg-options "-O2 -std=gnu2x" } */
+
+#define INT128_MAX ((__int128) ((((unsigned __int128) 1) << 127) - 1))
+#define UINT128_MAX (~(unsigned __int128) 0)
+#define C(x, y) ((((__int128) (x##ULL)) << 64) | (y##ULL))
+#define UC(x, y) ((((unsigned __int128) (x##ULL)) << 64) | (y##ULL))
+
+__attribute__((noipa)) __int128
+tests64 (_Decimal64 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) unsigned __int128
+testu64 (_Decimal64 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) __int128
+tests32 (_Decimal32 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) unsigned __int128
+testu32 (_Decimal32 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) __int128
+tests128 (_Decimal128 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) unsigned __int128
+testu128 (_Decimal128 d)
+{
+  return d;
+}
+
+int
+main ()
+{
+  if (tests64 (0.DD) != 0
+      || tests64 (0.9999999999999999DD) != 0
+      || tests64 (7.999999999999999DD) != 7
+      || tests64 (-0.DD) != 0
+      || tests64 (-0.9999999999999999DD) != 0
+      || tests64 (-42.5DD) != -42
+      || tests64 (-34242319854.45429e+27DD) != -C (0x19c2d4b6fefc3378, 0xa349b93967400000)
+      || tests64 (-213855087769445.9e+23DD) != -C (0x1016b2fcff8f2cf6, 0xd16cf61904c00000)
+      || tests64 (1701411834604692.0e+23DD) != C (0x7ffffffffffff947, 0xd26076f482000000)
+      || tests64 (-1701411834604692.0e+23DD) != -C (0x7ffffffffffff947, 0xd26076f482000000))
+    __builtin_abort ();
+  if (tests64 (1701411834604693.0e+23DD) != INT128_MAX
+      || tests64 (9999999999999999e+369DD) != INT128_MAX
+      || tests64 (-1701411834604693.0e+23DD) != -INT128_MAX - 1
+      || tests64 (-9999999999999999e+369DD) != -INT128_MAX - 1)
+    __builtin_abort ();
+  if (testu64 (0.DD) != 0
+      || testu64 (0.9999999999999999DD) != 0
+      || testu64 (-0.9999999999999999DD) != 0
+      || testu64 (-0.0DD) != 0
+      || testu64 (-0.5DD) != 0
+      || testu64 (42.99999999999999DD) != 42
+      || testu64 (42.e+21DD) != UC (0x8e4, 0xd316827686400000)
+      || testu64 (34272319854.45429e+27DD) != C (0x19c89bd43b04cab9, 0x49f2646567400000)
+      || testu64 (3402823669209384.0e+23DD) != C (0xfffffffffffff28f, 0xa4c0ede904000000))
+    __builtin_abort ();
+  if (testu64 (-1.DD) != 0
+      || testu64 (-42.5e+15DD) != 0
+      || testu64 (-9999999999999999e+369DD) != 0
+      || testu64 (3402823669209385.0e+23DD) != UINT128_MAX
+      || testu64 (9999999999999999e+369DD) != UINT128_MAX)
+    __builtin_abort ();
+
+  if (tests32 (0.DF) != 0
+      || tests32 (0.9999999DF) != 0
+      || tests32 (7.999999DF) != 7
+      || tests32 (-0.000DF) != 0
+      || tests32 (-0.9999999DF) != 0
+      || tests32 (-1.DF) != -1
+      || tests32 (-42.5DF) != -42
+      || tests32 (-3424.231e+27DF) != -C (0x2b38497f00, 0x9c4e190b47000000)
+      || tests32 (-213855.9e+32DF) != -C (0x1016b6fe2d67e732, 0x717a483980000000)
+      || tests32 (1701411.0e+32DF) != C (0x7ffffbe294adefda, 0xd863b4a300000000)
+      || tests32 (-1701411.0e+32DF) != -C (0x7ffffbe294adefda, 0xd863b4a300000000))
+    __builtin_abort ();
+  if (tests32 (1701412.0e+32DF) != INT128_MAX
+      || tests32 (9999999e+90DF) != INT128_MAX
+      || tests32 (-1701412.0e+32DF) != -INT128_MAX - 1
+      || tests32 (-9999999e+90DF) != -INT128_MAX - 1)
+    __builtin_abort ();
+  if (testu32 (0.DF) != 0
+      || testu32 (0.9999999DF) != 0
+      || testu32 (-0.9999999DF) != 0
+      || testu32 (-0.5DF) != 0
+      || testu32 (-0.0000DF) != 0
+      || testu32 (-0.99999DF) != 0
+      || testu32 (42.99999DF) != 42
+      || testu32 (42.e+21DF) != UC (0x8e4, 0xd316827686400000)
+      || testu32 (3402.823e+35DF) != UC (0xfffffcb356c92111, 0x367458c700000000))
+    __builtin_abort ();
+  if (testu32 (-1.DF) != 0
+      || testu32 (-42.5e+15DF) != 0
+      || testu32 (-9999999e+90DF) != 0
+      || testu32 (3402.824e+35DF) != UINT128_MAX
+      || testu32 (9999999e+90DF) != UINT128_MAX)
+    __builtin_abort ();
+
+  if (tests128 (0.DL) != 0
+      || tests128 (0.9999999999999999999999999999999999DL) != 0
+      || tests128 (7.999999999999999999999999999999999DL) != 7
+      || tests128 (-0.DL) != 0
+      || tests128 (-0.9999999999999999999999999999999999DL) != 0
+      || tests128 (-1.DL) != -1
+      || tests128 (-42.5DL) != -42
+      || tests128 (-34242319854.45429439857871298745432e+27DL) != -C (0x19c2d4b6fefc3467, 0x15d47c047b56ad80)
+      || tests128 (-213855087769445.9e+23DL) != -C (0x1016b2fcff8f2cf6, 0xd16cf61904c00000)
+      || tests128 (1701411834604692317316873037158841.0e+5DL) != C (0x7fffffffffffffff, 0xffffffffffffe9a0)
+      || tests128 (-1701411834604692317316873037158841.0e+5DL) != -C (0x7fffffffffffffff, 0xffffffffffffe9a0))
+    __builtin_abort ();
+  if (tests128 (1701411834604692317316873037158842.0e+5DL) != INT128_MAX
+      || tests128 (9999999999999999999999999999999999e+6111DL) != INT128_MAX
+      || tests128 (-1701411834604692317316873037158842.0e+5DL) != -INT128_MAX - 1
+      || tests128 (-9999999999999999999999999999999999e+6111DL) != -INT128_MAX - 1)
+    __builtin_abort ();
+  if (testu128 (0.DL) != 0
+      || testu128 (0.9999999999999999999999999999999999DL) != 0
+      || testu128 (-0.9999999999999999999999999999999999DL) != 0
+      || testu128 (-0.DL) != 0
+      || testu128 (-0.9999999999999999999999DL) != 0
+      || testu128 (-0.5DL) != 0
+      || testu128 (42.99999999999999999999999999999999DL) != 42
+      || testu128 (42.e+21DL) != UC (0x8e4, 0xd316827686400000)
+      || testu128 (34242319854.45429439857871298745432e+21DL) != UC (0x1b032e71cc9, 0x24b5cd6d86a9473e)
+      || testu128 (3402823669209384634633746074317.682e+8DL) != UC (0xffffffffffffffff, 0xffffffffffffd340))
+    __builtin_abort ();
+  if (testu128 (-1.DL) != 0
+      || testu128 (-42.5e+15DL) != 0
+      || testu128 (-9999999999999999999999999999999999e+6111DL) != 0
+      || testu128 (3402823669209384634633746074317.683e+8DL) != UINT128_MAX
+      || testu128 (9999999999999999999999999999999999e+6111DL) != UINT128_MAX)
+    __builtin_abort ();
+}
--- gcc/testsuite/gcc.dg/dfp/int128-2.c.jj	2023-11-06 16:01:28.928744519 +0100
+++ gcc/testsuite/gcc.dg/dfp/int128-2.c	2023-11-06 17:52:57.167816253 +0100
@@ -0,0 +1,200 @@ 
+/* PR libgcc/65833 */
+/* { dg-do run { target { int128 && bitint } } } */
+/* { dg-options "-O2 -std=gnu2x" } */
+
+__attribute__((noipa)) _Decimal64
+tests64 (__int128 b)
+{
+  return b;
+}
+
+__attribute__((noipa)) _Decimal64
+testu64 (unsigned __int128 b)
+{
+  return b;
+}
+
+__attribute__((noipa)) _Decimal32
+tests32 (__int128 b)
+{
+  return b;
+}
+
+__attribute__((noipa)) _Decimal32
+testu32 (unsigned __int128 b)
+{
+  return b;
+}
+
+__attribute__((noipa)) _Decimal128
+tests128 (__int128 b)
+{
+  return b;
+}
+
+__attribute__((noipa)) _Decimal128
+testu128 (unsigned __int128 b)
+{
+  return b;
+}
+
+int
+main ()
+{
+  {
+    _Decimal64 a, b;
+#define CHECK(x, y) (a = (x), b = (y), a != (y) || __builtin_memcmp (&a, &b, sizeof (a)))
+#define C(x, y) ((((__int128) (x##ULL)) << 64) | (y##ULL))
+#define UC(x, y) ((((unsigned __int128) (x##ULL)) << 64) | (y##ULL))
+#define INT128_MAX ((__int128) ((((unsigned __int128) 1) << 127) - 1))
+#define UINT128_MAX (~(unsigned __int128) 0)
+    if (CHECK (tests64 (0LL), 0.DD)
+	|| CHECK (tests64 (7LL), 7.DD)
+	|| CHECK (tests64 (-42LL), -42.DD)
+	|| CHECK (tests64 (-777777777LL), -777777777.DD)
+	|| CHECK (tests64 (9999999999999000LL), 9999999999999000.DD)
+	|| CHECK (tests64 (-9999999999999999LL), -9999999999999999.DD)
+	|| CHECK (tests64 (-99999999999999994LL), -9999999999999999.e+1DD)
+	|| CHECK (tests64 (99999999999999995LL), 1000000000000000.e+2DD)
+	|| CHECK (tests64 (999999999999999900LL), 9999999999999999.e+2DD)
+	|| CHECK (tests64 (999999999999999949LL), 9999999999999999.e+2DD)
+	|| CHECK (tests64 (-(__int128) 9999999999999999000ULL), -9999999999999999.e+3DD)
+	|| CHECK (tests64 (9999999999999999499ULL), 9999999999999999.e+3DD)
+	|| CHECK (tests64 (C (0x36, 0x35c9adc5de9e7960)), 9999999999999999.e+5DD)
+	|| CHECK (tests64 (C (0x36, 0x35c9adc5de9f3caf)), 9999999999999999.e+5DD)
+	|| CHECK (tests64 (-C (0x21e, 0x19e0c9bab230bdc0)), -9999999999999999.e+6DD)
+	|| CHECK (tests64 (-C (0x21e, 0x19e0c9bab2385edf)), -9999999999999999.e+6DD)
+	|| CHECK (tests64 (C (0x1a24, 0x9b1f10a067e2c000)), 1234567890123456.e+8DD)
+	|| CHECK (tests64 (C (0x2937babe64c6b8c, 0x10542c1f57200000)), 3424231985445429e+21DD)
+	|| CHECK (tests64 (C (0x4b3b4ca85a86c25b, 0xefa958854dc00000)), 9999999999999999.e+22DD)
+	|| CHECK (tests64 (C (0x4b3b4ca85a86c36a, 0xfc99bd62a6dfffff)), 9999999999999999.e+22DD)
+	|| CHECK (tests64 (-C (0x4b3b4ca85a86c25b, 0xefa958854dc00000)), -9999999999999999.e+22DD)
+	|| CHECK (tests64 (-C (0x1016b2fcff8f2cf6, 0xd16cf61904c00000)), -2138550877694459e+22DD)
+	|| CHECK (tests64 (-C (0x1016b2fcff8f2e05, 0xde5d5af65de00000)), -2138550877694460e+22DD)
+	|| CHECK (tests64 (-C (0x1016b2fcff8f2e05, 0xde5d5af65ddfffff)), -2138550877694459e+22DD)
+	|| CHECK (tests64 (-C (0x1016b2fcff8f2f14, 0xeb4dbfd3b6ffffff)), -2138550877694460e+22DD)
+	|| CHECK (tests64 (-C (0x1016b2fcff8f2ad8, 0xb78c2c5e52800000)), -2138550877694458e+22DD)
+	|| CHECK (tests64 (-C (0x1016b2fcff8f2be7, 0xc47c913baba00000)), -2138550877694458e+22DD)
+	|| CHECK (tests64 (-C (0x1016b2fcff8f2be7, 0xc47c913baba00001)), -2138550877694459e+22DD)
+	|| CHECK (tests64 (C (0x7ffffffffffff947, 0xd26076f482000000)), 1701411834604692e+23DD)
+	|| CHECK (tests64 (INT128_MAX), 1701411834604692e+23DD)
+	|| CHECK (tests64 (-C (0x7ffffffffffff947, 0xd26076f482000000)), -1701411834604692e+23DD)
+	|| CHECK (tests64 (-INT128_MAX - 1), -1701411834604692e+23DD))
+      __builtin_abort ();
+    if (CHECK (testu64 (0ULL), 0.DD)
+	|| CHECK (testu64 (7ULL), 7.DD)
+	|| CHECK (testu64 (42ULL), 42.DD)
+	|| CHECK (testu64 (777777777ULL), 777777777.DD)
+	|| CHECK (testu64 (9999999999999000ULL), 9999999999999000.DD)
+	|| CHECK (testu64 (999999999999999900ULL), 9999999999999999.e+2DD)
+	|| CHECK (testu64 (9999999999999999000ULL), 9999999999999999.e+3DD)
+	|| CHECK (testu64 (UC (0x5, 0x6bc75e2d630fec77)), 9999999999999999.e+4DD)
+	|| CHECK (testu64 (UC (0x36, 0x35c9adc5de9e7960)), 9999999999999999.e+5DD)
+	|| CHECK (testu64 (UC (0x21e, 0x19e0c9bab230bdc0)), 9999999999999999.e+6DD)
+	|| CHECK (testu64 (UC (0x1a24, 0x9b1f10a067e2c000)), 1234567890123456.e+8DD)
+	|| CHECK (testu64 (UC (0x19c2d4b6fefc3378, 0xa349b93967400000)), 3424231985445429e+22DD)
+	|| CHECK (testu64 (UC (0x2e90434dfef46d45, 0x1f6d190ddcc00000)), 6189354365465179e+22DD)
+	|| CHECK (testu64 (UC (0x2e90434dfef46e54, 0x2c5d7deb35e00000)), 6189354365465180e+22DD)
+	|| CHECK (testu64 (UC (0x2e90434dfef46e54, 0x2c5d7deb35dfffff)), 6189354365465179e+22DD)
+	|| CHECK (testu64 (UC (0x2e90434dfef46f63, 0x394de2c88effffff)), 6189354365465180e+22DD)
+	|| CHECK (testu64 (UC (0x2e90434dfef46b27, 0x058c4f532a800000)), 6189354365465178e+22DD)
+	|| CHECK (testu64 (UC (0x2e90434dfef46c36, 0x127cb43083a00000)), 6189354365465178e+22DD)
+	|| CHECK (testu64 (UC (0x2e90434dfef46c36, 0x127cb43083a00001)), 6189354365465179e+22DD)
+	|| CHECK (testu64 (UC (0x4b3b4ca85a86c25b, 0xefa958854dc00000)), 9999999999999999.e+22DD)
+	|| CHECK (testu64 (UC (0xfffffffffffff28f, 0xa4c0ede904000000)), 340282366920938.4e+24DD)
+	|| CHECK (testu64 (UC (0xfffffffffffffd26, 0x2624de8e7f3fffff)), 340282366920938.4e+24DD)
+	|| CHECK (testu64 (UC (0xfffffffffffffd26, 0x2624de8e7f400000)), 340282366920938.4e+24DD)
+	|| CHECK (testu64 (UC (0xfffffffffffffd26, 0x2624de8e7f400001)), 340282366920938.5e+24DD)
+	|| CHECK (testu64 (UC (0xfffffffffffffd26, 0x2624de90d34be400)), 340282366920938.5e+24DD)
+	|| CHECK (testu64 (UINT128_MAX), 340282366920938.5e+24DD))
+      __builtin_abort ();
+  }
+  {
+    _Decimal32 a, b;
+    if (CHECK (tests32 (0LL), 0.DF)
+	|| CHECK (tests32 (7LL), 7.DF)
+	|| CHECK (tests32 (-42LL), -42.DF)
+	|| CHECK (tests32 (-777777LL), -777777.DF)
+	|| CHECK (tests32 (9999000LL), 9999000.DF)
+	|| CHECK (tests32 (-9999999LL), -9999999.DF)
+	|| CHECK (tests32 (99999994LL), 9999999.e+1DF)
+	|| CHECK (tests32 (99999995LL), 1000000.e+2DF)
+	|| CHECK (tests32 (999999900LL), 9999999.e+2DF)
+	|| CHECK (tests32 (-9999999000LL), -9999999.e+3DF)
+	|| CHECK (tests32 (999999900000LL), 9999999.e+5DF)
+	|| CHECK (tests32 (-9999999000000LL), -9999999.e+6DF)
+	|| CHECK (tests32 (123456700000000000LL), 1234567.e+11DF)
+	|| CHECK (tests32 (C (0x6ea49330, 0xa5672e5497c00000)), 3424231e+22DF)
+	|| CHECK (tests32 (C (0x4b3b4c2a22c8a457, 0x48f8d71980000000)), 9999999.e+31DF)
+	|| CHECK (tests32 (-C (0x4b3b4c2a22c8a457, 0x48f8d71980000000)), -9999999.e+31DF)
+	|| CHECK (tests32 (-C (0x1016b30c6f76e61c, 0x6cefef0580000000)), -2138551e+31DF)
+	|| CHECK (tests32 (-C (0x1016b34b8b55f62d, 0xcd389498c0000000)), -2138552e+31DF)
+	|| CHECK (tests32 (-C (0x1016b34b8b55f62d, 0xcd389498bfffffff)), -2138551e+31DF)
+	|| CHECK (tests32 (-C (0x1016b38aa735063f, 0x2d813a2bffffffff)), -2138552e+31DF)
+	|| CHECK (tests32 (-C (0x1016b38aa735063f, 0x2d813a2c00000000)), -2138552e+31DF)
+	|| CHECK (tests32 (-C (0x1016b3c9c3141650, 0x8dc9dfbf40000000)), -2138552e+31DF)
+	|| CHECK (tests32 (-C (0x1016b3c9c3141650, 0x8dc9dfbf40000001)), -2138553e+31DF)
+	|| CHECK (tests32 (C (0x7ffffbe294adefda, 0xd863b4a300000000)), 1701411e+32DF)
+	|| CHECK (tests32 (INT128_MAX), 1701412e+32DF)
+	|| CHECK (tests32 (-C (0x7ffffbe294adefda, 0xd863b4a300000000)), -1701411e+32DF)
+	|| CHECK (tests32 (-INT128_MAX - 1LL), -1701412e+32DF))
+      __builtin_abort ();
+    if (CHECK (testu32 (0ULL), 0.DF)
+	|| CHECK (testu32 (7ULL), 7.DF)
+	|| CHECK (testu32 (42ULL), 42.DF)
+	|| CHECK (testu32 (77777ULL), 77777.DF)
+	|| CHECK (testu32 (9999000ULL), 9999000.DF)
+	|| CHECK (testu32 (999999900ULL), 9999999.e+2DF)
+	|| CHECK (testu32 (999999949ULL), 9999999.e+2DF)
+	|| CHECK (testu32 (9999999000ULL), 9999999.e+3DF)
+	|| CHECK (testu32 (9999999499ULL), 9999999.e+3DF)
+	|| CHECK (testu32 (999999900000ULL), 9999999.e+5DF)
+	|| CHECK (testu32 (9999999000000ULL), 9999999.e+6DF)
+	|| CHECK (testu32 (123456700000000ULL), 1234567.e+8DF)
+	|| CHECK (testu32 (UC (0x6ea49330, 0xa5672e5497c00000)), 3424231e+22DF)
+	|| CHECK (testu32 (UC (0x785ee0436adaa08, 0xba7f48b5c0000000)), 9999999.e+30DF)
+	|| CHECK (testu32 (UC (0x2e904596f4d9f2bb, 0x14fbca9180000000)), 6189359e+31DF)
+	|| CHECK (testu32 (UC (0x2e9045d610b902cc, 0x75447024c0000000)), 6189360e+31DF)
+	|| CHECK (testu32 (UC (0x2e9045d610b902cc, 0x75447024bfffffff)), 6189359e+31DF)
+	|| CHECK (testu32 (UC (0x2e9046152c9812dd, 0xd58d15b7ffffffff)), 6189360e+31DF)
+	|| CHECK (testu32 (UC (0x2e904518bd1bd298, 0x546a7f6b00000000)), 6189358e+31DF)
+	|| CHECK (testu32 (UC (0x2e904557d8fae2a9, 0xb4b324fe40000000)), 6189358e+31DF)
+	|| CHECK (testu32 (UC (0x2e904557d8fae2a9, 0xb4b324fe40000001)), 6189359e+31DF)
+	|| CHECK (testu32 (UC (0xfffffcb356c92111, 0x367458c700000000)), 3402823e+32DF)
+	|| CHECK (testu32 (UINT128_MAX), 3402824e+32DF))
+      __builtin_abort ();
+  }
+  {
+    _Decimal128 a, b;
+    if (CHECK (tests128 (0LL), 0.DL)
+	|| CHECK (tests128 (7LL), 7.DL)
+	|| CHECK (tests128 (-42LL), -42.DL)
+	|| CHECK (tests128 (-777777777LL), -777777777.DL)
+	|| CHECK (tests128 (-12345678912345LL), -12345678912345.DL)
+	|| CHECK (tests128 (123456789123456789LL), 123456789123456789.DL)
+	|| CHECK (tests128 (C (0x2835cd9, 0xd1a22ada09c71c71)), 777777777777777777777777777.DL)
+	|| CHECK (tests128 (C (0x1ed09bead87c0, 0x378d8e63fa0a1f00)), 9999999999999999999999999900000000.DL)
+	|| CHECK (tests128 (-C (0x1ed09bead87c0, 0x378d8e63ffffffff)), -9999999999999999999999999999999999.DL)
+	|| CHECK (tests128 (-C (0x13426172c74d82, 0x2b878fe7fffffffa)), -9999999999999999999999999999999999.e+1DL)
+	|| CHECK (tests128 (C (0x13426172c74d82, 0x2b878fe7fffffffb)), 1000000000000000000000000000000000.e+2DL)
+	|| CHECK (tests128 (C (0xc097ce7bc90715, 0xb34b9f0fffffff9c)), 9999999999999999999999999999999999.e+2DL)
+	|| CHECK (tests128 (C (0xc097ce7bc90715, 0xb34b9f0fffffffcd)), 9999999999999999999999999999999999.e+2DL)
+	|| CHECK (tests128 (-C (0x785ee10d5da46d9, 0x00f4369ffffffc18)), -9999999999999999999999999999999999.e+3DL)
+	|| CHECK (tests128 (C (0x785ee10d5da46d9, 0x00f4369ffffffe0b)), 9999999999999999999999999999999999.e+3DL)
+	|| CHECK (tests128 (C (0x7fffffffffffffff, 0xffffffffffffe9a0)), 1701411834604692317316873037158841.e+5DL)
+	|| CHECK (tests128 (INT128_MAX), 1701411834604692317316873037158841.e+5DL)
+	|| CHECK (tests128 (-INT128_MAX - 1), -1701411834604692317316873037158841.e+5DL))
+      __builtin_abort ();
+    if (CHECK (testu128 (0ULL), 0.DL)
+	|| CHECK (testu128 (7ULL), 7.DL)
+	|| CHECK (testu128 (42ULL), 42.DL)
+	|| CHECK (testu128 (777777777ULL), 777777777.DL)
+	|| CHECK (testu128 (UC (0x1431e0fae, 0x6d7217ca9ffffc18)), 99999999999999999999999999000.DL)
+	|| CHECK (testu128 (UC (0xc097ce7bc90715, 0xb34b9f0fffffff9c)), 9999999999999999999999999999999999.e+2DL)
+	|| CHECK (testu128 (UC (0x785ee10d5da46d9, 0x00f4369ffffffc18)), 9999999999999999999999999999999999.e+3DL)
+	|| CHECK (testu128 (UC (0x4b3b4ca85a86c47a, 0x098a223fffffec77)), 9999999999999999999999999999999999.e+4DL)
+	|| CHECK (testu128 (UC (0xffffffffffffffff, 0xffffffffffffd340)), 3402823669209384634633746074317682.e+5DL)
+	|| CHECK (testu128 (UINT128_MAX), 3402823669209384634633746074317682.e+5DL))
+      __builtin_abort ();
+  }
+}
--- gcc/testsuite/gcc.dg/dfp/int128-3.c.jj	2023-11-06 17:55:50.156411782 +0100
+++ gcc/testsuite/gcc.dg/dfp/int128-3.c	2023-11-06 17:55:44.339492632 +0100
@@ -0,0 +1,81 @@ 
+/* PR libgcc/65833 */
+/* Test non-canonical BID significands.  */
+/* { dg-do run { target { int128 && bitint } } } */
+/* { dg-options "-O2 -std=gnu2x" } */
+/* { dg-require-effective-target dfp_bid } */
+
+union U32
+{
+  _Decimal32 d;
+  unsigned int u;
+};
+
+union U64
+{
+  _Decimal64 d;
+  unsigned long long int u;
+};
+
+union U128
+{
+  _Decimal128 d;
+  unsigned long long int u[2];
+};
+
+int
+main ()
+{
+  volatile union U32 u32;
+  u32.d = 0.9999999e+27DF;
+  u32.u++;
+  volatile union U64 u64;
+  u64.d = 0.9999999999999999e+90DD;
+  u64.u++;
+  volatile union U128 u128;
+  u128.d = 0.9999999999999999999999999999999999e+39DL;
+  if (u128.u[0] == 0x378d8e63ffffffffULL)
+    u128.u[0]++;
+  else if (u128.u[1] == 0x378d8e63ffffffffULL)
+    u128.u[1]++;
+  else
+    u128.d = 0.DL;
+  if ((__int128) u32.d != 0
+      || (unsigned __int128) u32.d != 0U
+      || (__int128) u64.d != 0
+      || (unsigned __int128) u64.d != 0U
+      || (__int128) u128.d != 0
+      || (unsigned __int128) u128.d != 0U)
+    __builtin_abort ();
+  u32.u = 0xe59fffffU;
+  u64.u = 0xe3ffffffffffffffULL;
+  if (u128.u[0] == 0x378d8e6400000000ULL)
+    {
+      u128.u[0] = -1ULL;
+      u128.u[1] = 0xe1be7fffffffffffULL;
+    }
+  else if (u128.u[1] == 0x378d8e6400000000ULL)
+    {
+      u128.u[1] = -1ULL;
+      u128.u[0] = 0xe1be7fffffffffffULL;
+    }
+  if ((__int128) u32.d != 0
+      || (unsigned __int128) u32.d != 0U
+      || (__int128) u64.d != 0
+      || (unsigned __int128) u64.d != 0U
+      || (__int128) u128.d != 0
+      || (unsigned __int128) u128.d != 0U)
+    __builtin_abort ();
+  if (u128.u[0] == -1ULL)
+    {
+      u128.u[0] = 0;
+      u128.u[1] = 0xe629800000000000ULL;
+    }
+  else if (u128.u[1] == -1ULL)
+    {
+      u128.u[1] = 0;
+      u128.u[0] = 0xe629800000000000ULL;
+    }
+  if ((__int128) u128.d != 0
+      || (unsigned __int128) u128.d != 0U)
+    __builtin_abort ();
+}
--- gcc/testsuite/gcc.dg/dfp/int128-4.c.jj	2023-11-06 17:56:16.871040460 +0100
+++ gcc/testsuite/gcc.dg/dfp/int128-4.c	2023-11-06 19:09:05.597144909 +0100
@@ -0,0 +1,104 @@ 
+/* PR libgcc/65833 */
+/* { dg-do run { target { int128 && bitint } } } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "-std=c2x" } */
+
+#include <fenv.h>
+
+#define INT128_MAX ((__int128) ((((unsigned __int128) 1) << 127) - 1))
+#define UINT128_MAX (~(unsigned __int128) 0)
+#define C(x, y) ((((__int128) (x##ULL)) << 64) | (y##ULL))
+#define UC(x, y) ((((unsigned __int128) (x##ULL)) << 64) | (y##ULL))
+
+__attribute__((noipa)) __int128
+tests_32 (_Decimal32 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) unsigned __int128
+testu_32 (_Decimal32 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) __int128
+tests_64 (_Decimal64 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) unsigned __int128
+testu_64 (_Decimal64 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) __int128
+tests_128 (_Decimal128 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) unsigned __int128
+testu_128 (_Decimal128 d)
+{
+  return d;
+}
+
+__attribute__((noipa)) void
+check_invalid (int test, int inv)
+{
+  if (!test)
+    __builtin_abort ();
+  if ((!fetestexcept (FE_INVALID)) != (!inv))
+    __builtin_abort ();
+  feclearexcept (FE_INVALID);
+}
+
+int
+main ()
+{
+  check_invalid (tests_32 (__builtin_infd32 ()) == INT128_MAX, 1);
+  check_invalid (tests_32 (-__builtin_infd32 ()) == -INT128_MAX - 1, 1);
+  check_invalid (tests_32 (__builtin_nand32 ("")) == INT128_MAX, 1);
+  check_invalid (tests_32 (-1701411.0e+32DF) == -C (0x7ffffbe294adefda, 0xd863b4a300000000), 0);
+  check_invalid (tests_32 (-1701412.0e+32DF) == -INT128_MAX - 1, 1);
+  check_invalid (tests_32 (1701411.0e+32DF) == C (0x7ffffbe294adefda, 0xd863b4a300000000), 0);
+  check_invalid (tests_32 (1701412.0e+32DF) == INT128_MAX, 1);
+  check_invalid (testu_32 (__builtin_infd32 ()) == UINT128_MAX, 1);
+  check_invalid (testu_32 (-__builtin_infd32 ()) == 0U, 1);
+  check_invalid (testu_32 (__builtin_nand32 ("")) == UINT128_MAX, 1);
+  check_invalid (testu_32 (-0.9999999DF) == 0U, 0);
+  check_invalid (testu_32 (-1.0DF) == 0U, 1);
+  check_invalid (testu_32 (3402823.0e+32DF) == UC (0xfffffcb356c92111, 0x367458c700000000), 0);
+  check_invalid (testu_32 (3402824.0e+32DF) == UINT128_MAX, 1);
+  check_invalid (tests_64 (__builtin_infd64 ()) == INT128_MAX, 1);
+  check_invalid (tests_64 (-__builtin_infd64 ()) == -INT128_MAX - 1, 1);
+  check_invalid (tests_64 (__builtin_nand64 ("")) == INT128_MAX, 1);
+  check_invalid (tests_64 (-170141183460469.2e+24DD) == -C (0x7ffffffffffff947, 0xd26076f482000000), 0);
+  check_invalid (tests_64 (-170141183460469.3e+24DD) == -INT128_MAX - 1, 1);
+  check_invalid (tests_64 (170141183460469.2e+24DD) == C (0x7ffffffffffff947, 0xd26076f482000000), 0);
+  check_invalid (tests_64 (170141183460469.3e+24DD) == INT128_MAX, 1);
+  check_invalid (testu_64 (__builtin_infd64 ()) == UINT128_MAX, 1);
+  check_invalid (testu_64 (-__builtin_infd64 ()) == 0, 1);
+  check_invalid (testu_64 (__builtin_nand64 ("")) == UINT128_MAX, 1);
+  check_invalid (testu_64 (-0.9999999999999999DD) == 0U, 0);
+  check_invalid (testu_64 (-1.0DD) == 0U, 1);
+  check_invalid (testu_64 (340282366920938.4e+24DD) == UC (0xfffffffffffff28f, 0xa4c0ede904000000), 0);
+  check_invalid (testu_64 (340282366920938.5e+24DD) == UINT128_MAX, 1);
+  check_invalid (tests_128 (__builtin_infd128 ()) == INT128_MAX, 1);
+  check_invalid (tests_128 (-__builtin_infd128 ()) == -INT128_MAX - 1, 1);
+  check_invalid (tests_128 (__builtin_nand128 ("")) == INT128_MAX, 1);
+  check_invalid (tests_128 (-1701411834604692317316873037158841.0e+5DL) == -C (0x7fffffffffffffff, 0xffffffffffffe9a0), 0);
+  check_invalid (tests_128 (-1701411834604692317316873037158842.0e+5DL) == -INT128_MAX - 1, 1);
+  check_invalid (tests_128 (1701411834604692317316873037158841.0e+5DL) == C (0x7fffffffffffffff, 0xffffffffffffe9a0), 0);
+  check_invalid (tests_128 (1701411834604692317316873037158842.0e+5DL) == INT128_MAX, 1);
+  check_invalid (testu_128 (__builtin_infd128 ()) == UINT128_MAX, 1);
+  check_invalid (testu_128 (-__builtin_infd128 ()) == 0, 1);
+  check_invalid (testu_128 (__builtin_nand128 ("")) == UINT128_MAX, 1);
+  check_invalid (testu_128 (-0.9999999999999999999999999999999999DL) == 0U, 0);
+  check_invalid (testu_128 (-1.0DL) == 0U, 1);
+  check_invalid (testu_128 (3402823669209384634633746074317682.0e+5DL) == UC (0xffffffffffffffff, 0xffffffffffffd340), 0);
+  check_invalid (testu_128 (3402823669209384634633746074317683.0e+5DL) == UINT128_MAX, 1);
+}