https://gcc.gnu.org/g:48787c734ee647cb99abb1e95d937f1ba66e78d0

commit r16-3058-g48787c734ee647cb99abb1e95d937f1ba66e78d0
Author: Stefan Schulze Frielinghaus <stefa...@gcc.gnu.org>
Date:   Thu Aug 7 08:39:11 2025 +0200

    s390: Add _BitInt support
    
    gcc/ChangeLog:
    
            * config/s390/s390.cc (print_operand): Allow arbitrary wide_int
            constants for _BitInt.
            (s390_bitint_type_info): Implement target hook
            TARGET_C_BITINT_TYPE_INFO.
    
    libgcc/ChangeLog:
    
            * config/s390/libgcc-glibc.ver: Export _BitInt support
            functions.
            * config/s390/t-softfp (softfp_extras): Add fixtfbitint
            floatbitinttf.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/s390/bitint-1.c: New test.
            * gcc.target/s390/bitint-2.c: New test.
            * gcc.target/s390/bitint-3.c: New test.
            * gcc.target/s390/bitint-4.c: New test.

Diff:
---
 gcc/config/s390/s390.cc                  | 37 +++++++++++---
 gcc/testsuite/gcc.target/s390/bitint-1.c | 83 ++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/s390/bitint-2.c | 32 ++++++++++++
 gcc/testsuite/gcc.target/s390/bitint-3.c | 28 +++++++++++
 gcc/testsuite/gcc.target/s390/bitint-4.c | 71 +++++++++++++++++++++++++++
 libgcc/config/s390/libgcc-glibc.ver      | 14 ++++++
 libgcc/config/s390/t-softfp              |  1 +
 7 files changed, 258 insertions(+), 8 deletions(-)

diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 012b6dbb6e00..d044f9a010ca 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -9239,15 +9239,12 @@ print_operand (FILE *file, rtx x, int code)
       else if (code == 'h')
        fprintf (file, HOST_WIDE_INT_PRINT_DEC,
                 ((CONST_WIDE_INT_ELT (x, 0) & 0xffff) ^ 0x8000) - 0x8000);
+      /* Support arbitrary _BitInt constants in asm statements.  */
+      else if (code == 0)
+       output_addr_const (file, x);
       else
-       {
-         if (code == 0)
-           output_operand_lossage ("invalid constant - try using "
-                                   "an output modifier");
-         else
-           output_operand_lossage ("invalid constant for output modifier '%c'",
-                                   code);
-       }
+       output_operand_lossage ("invalid constant for output modifier '%c'",
+                               code);
       break;
     case CONST_VECTOR:
       switch (code)
@@ -18768,6 +18765,27 @@ s390_c_mode_for_floating_type (enum tree_index ti)
   return default_mode_for_floating_type (ti);
 }
 
+/* Return true if _BitInt(N) is supported and fill its details into *INFO.  */
+
+bool
+s390_bitint_type_info (int n, struct bitint_info *info)
+{
+  if (!TARGET_64BIT)
+    return false;
+  if (n <= 8)
+    info->limb_mode = QImode;
+  else if (n <= 16)
+    info->limb_mode = HImode;
+  else if (n <= 32)
+    info->limb_mode = SImode;
+  else
+    info->limb_mode = DImode;
+  info->abi_limb_mode = info->limb_mode;
+  info->big_endian = true;
+  info->extended = true;
+  return true;
+}
+
 /* Initialize GCC target structure.  */
 
 #undef  TARGET_ASM_ALIGNED_HI_OP
@@ -19089,6 +19107,9 @@ s390_c_mode_for_floating_type (enum tree_index ti)
 #undef TARGET_DOCUMENTATION_NAME
 #define TARGET_DOCUMENTATION_NAME "S/390"
 
+#undef TARGET_C_BITINT_TYPE_INFO
+#define TARGET_C_BITINT_TYPE_INFO s390_bitint_type_info
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-s390.h"
diff --git a/gcc/testsuite/gcc.target/s390/bitint-1.c 
b/gcc/testsuite/gcc.target/s390/bitint-1.c
new file mode 100644
index 000000000000..8bdf2ae09bc2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/bitint-1.c
@@ -0,0 +1,83 @@
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-O2 -march=z9-109" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Verify calling convention. */
+
+static_assert (sizeof (_BitInt(5)) == 1);
+static_assert (sizeof (_BitInt(9)) == 2);
+static_assert (sizeof (_BitInt(17)) == 4);
+static_assert (sizeof (_BitInt(33)) == 8);
+
+/*
+** bitint5_zero_extend_call:
+**         lghi        %r2,22
+**         jg  bitint5_zero_extend@PLT
+*/
+
+void bitint5_zero_extend (unsigned _BitInt(5) x);
+void bitint5_zero_extend_call (void) { bitint5_zero_extend (22wbu); }
+
+/*
+** bitint5_sign_extend_call:
+**         lghi        %r2,-10
+**         jg  bitint5_sign_extend@PLT
+*/
+
+void bitint5_sign_extend (_BitInt(5) x);
+void bitint5_sign_extend_call (void) { bitint5_sign_extend (-10wb); }
+
+/*
+** bitint9_zero_extend_call:
+**         lghi        %r2,422
+**         jg  bitint9_zero_extend@PLT
+*/
+
+void bitint9_zero_extend (unsigned _BitInt(9) x);
+void bitint9_zero_extend_call (void) { bitint9_zero_extend (422wbu); }
+
+/*
+** bitint9_sign_extend_call:
+**         lghi        %r2,-90
+**         jg  bitint9_sign_extend@PLT
+*/
+
+void bitint9_sign_extend (_BitInt(9) x);
+void bitint9_sign_extend_call (void) { bitint9_sign_extend (-90wb); }
+
+/*
+** bitint17_zero_extend_call:
+**         lgfi        %r2,108198
+**         jg  bitint17_zero_extend@PLT
+*/
+
+void bitint17_zero_extend (unsigned _BitInt(17) x);
+void bitint17_zero_extend_call (void) { bitint17_zero_extend (108198wbu); }
+
+/*
+** bitint17_sign_extend_call:
+**         lghi        %r2,-22874
+**         jg  bitint17_sign_extend@PLT
+*/
+
+void bitint17_sign_extend (_BitInt(17) x);
+void bitint17_sign_extend_call (void) { bitint17_sign_extend (-22874wb); }
+
+/*
+** bitint33_zero_extend_call:
+**         llihl       %r2,1
+**         oilf        %r2,2795939494
+**         jg  bitint33_zero_extend@PLT
+*/
+
+void bitint33_zero_extend (unsigned _BitInt(33) x);
+void bitint33_zero_extend_call (void) { bitint33_zero_extend (7090906790wbu); }
+
+/*
+** bitint33_sign_extend_call:
+**         lgfi        %r2,-1499027802
+**         jg  bitint33_sign_extend@PLT
+*/
+
+void bitint33_sign_extend (_BitInt(33) x);
+void bitint33_sign_extend_call (void) { bitint33_sign_extend (-1499027802wb); }
diff --git a/gcc/testsuite/gcc.target/s390/bitint-2.c 
b/gcc/testsuite/gcc.target/s390/bitint-2.c
new file mode 100644
index 000000000000..9b0e6b916aa0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/bitint-2.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target bitint } } */
+/* { dg-options "-std=c23" } */
+
+/* Verify calling convention. */
+
+static_assert (sizeof (_BitInt(65)) == 16);
+
+[[gnu::noipa]] void
+bitint65_zero_extend (unsigned _BitInt(65) x)
+{
+  static const char y[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+                             0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D};
+  if (__builtin_memcmp (&x, y, 16) != 0)
+    __builtin_abort ();
+}
+
+[[gnu::noipa]] void
+bitint65_sign_extend (signed _BitInt(65) x)
+{
+  static const char y[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                             0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D};
+  if (__builtin_memcmp (&x, y, 16) != 0)
+    __builtin_abort ();
+}
+
+int
+main (void)
+{
+  bitint65_zero_extend (0x1BADC0FFEE0DDF00Dwbu);
+  bitint65_sign_extend (0x1BADC0FFEE0DDF00Dwb);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/s390/bitint-3.c 
b/gcc/testsuite/gcc.target/s390/bitint-3.c
new file mode 100644
index 000000000000..913202825258
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/bitint-3.c
@@ -0,0 +1,28 @@
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-march=z9-109 -fdump-rtl-expand" } */
+
+/* Verify calling convention. */
+
+/* { dg-final { scan-rtl-dump-times "zero_extend:DI.*reg:QI" 1 "expand" } } */
+void bitint5_zero_extend (unsigned _BitInt(5) x);
+void bitint5_zero_extend_call (unsigned _BitInt(5) x) { bitint5_zero_extend (x 
+ 1); }
+
+/* { dg-final { scan-rtl-dump-times "sign_extend:DI.*reg:QI" 1 "expand" } } */
+void bitint5_sign_extend (_BitInt(5) x);
+void bitint5_sign_extend_call (_BitInt(5) x) { bitint5_sign_extend (x + 1); }
+
+/* { dg-final { scan-rtl-dump-times "zero_extend:DI.*reg:HI" 1 "expand" } } */
+void bitint9_zero_extend (unsigned _BitInt(9) x);
+void bitint9_zero_extend_call (unsigned _BitInt(9) x) { bitint9_zero_extend (x 
+ 1); }
+
+/* { dg-final { scan-rtl-dump-times "sign_extend:DI.*reg:HI" 1 "expand" } } */
+void bitint9_sign_extend (_BitInt(9) x);
+void bitint9_sign_extend_call (_BitInt(9) x) { bitint9_sign_extend (x + 1); }
+
+/* { dg-final { scan-rtl-dump-times "zero_extend:DI.*reg:SI" 1 "expand" } } */
+void bitint17_zero_extend (unsigned _BitInt(17) x);
+void bitint17_zero_extend_call (unsigned _BitInt(17) x) { bitint17_zero_extend 
(x + 1); }
+
+/* { dg-final { scan-rtl-dump-times "sign_extend:DI.*reg:SI" 1 "expand" } } */
+void bitint17_sign_extend (_BitInt(17) x);
+void bitint17_sign_extend_call (_BitInt(17) x) { bitint17_sign_extend (x + 1); 
}
diff --git a/gcc/testsuite/gcc.target/s390/bitint-4.c 
b/gcc/testsuite/gcc.target/s390/bitint-4.c
new file mode 100644
index 000000000000..dce72d8ab11c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/bitint-4.c
@@ -0,0 +1,71 @@
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-march=z9-109 -O2" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/* Verify calling convention. */
+
+struct s_bitint5 {
+  short a;
+  unsigned _BitInt(5) b;
+  char c;
+};
+
+static_assert (sizeof (struct s_bitint5) == 4);
+
+/*
+** s_bitint5_call:
+**         iilf        %r2,2758168
+**         jg  s_bitint5@PLT
+*/
+
+void s_bitint5 (struct s_bitint5 x);
+void s_bitint5_call (void) { s_bitint5 ((struct s_bitint5){42, 22wbu, 24}); }
+
+struct s_bitint9 {
+  short a;
+  unsigned _BitInt(9) b;
+};
+
+static_assert (sizeof (struct s_bitint9) == 4);
+
+/*
+** s_bitint9_call:
+**         iilf        %r2,2752934
+**         jg  s_bitint9@PLT
+*/
+
+void s_bitint9 (struct s_bitint9 x);
+void s_bitint9_call (void) { s_bitint9 ((struct s_bitint9){42, 422wbu}); }
+
+struct s_bitint17 {
+  int a;
+  unsigned _BitInt(17) b;
+};
+
+static_assert (sizeof (struct s_bitint17) == 8);
+
+/*
+** s_bitint17_call:
+**         llihl       %r2,42
+**         oilf        %r2,108198
+**         jg  s_bitint17@PLT
+*/
+
+void s_bitint17 (struct s_bitint17 x);
+void s_bitint17_call (void) { s_bitint17 ((struct s_bitint17){42, 108198wbu}); 
}
+
+struct s_bitint33 {
+  unsigned _BitInt(33) b;
+};
+
+static_assert (sizeof (struct s_bitint33) == 8);
+
+/*
+** s_bitint33_call:
+**         llihl       %r2,1
+**         oilf        %r2,2795939494
+**         jg  s_bitint33@PLT
+*/
+
+void s_bitint33 (struct s_bitint33 x);
+void s_bitint33_call (void) { s_bitint33 ((struct s_bitint33){7090906790wbu}); 
}
diff --git a/libgcc/config/s390/libgcc-glibc.ver 
b/libgcc/config/s390/libgcc-glibc.ver
index 86c55a0128be..00375b3df0e8 100644
--- a/libgcc/config/s390/libgcc-glibc.ver
+++ b/libgcc/config/s390/libgcc-glibc.ver
@@ -114,3 +114,17 @@ GCC_4.1.0 {
   __floatditf
 %endif
 }
+
+%ifdef __s390x__
+%inherit GCC_16.0.0 GCC_4.1.0
+GCC_16.0.0 {
+  __mulbitint3
+  __divmodbitint4
+  __fixsfbitint
+  __fixdfbitint
+  __fixtfbitint
+  __floatbitintsf
+  __floatbitintdf
+  __floatbitinttf
+}
+%endif
diff --git a/libgcc/config/s390/t-softfp b/libgcc/config/s390/t-softfp
index f29f40f2cedc..724b15e83ba9 100644
--- a/libgcc/config/s390/t-softfp
+++ b/libgcc/config/s390/t-softfp
@@ -1 +1,2 @@
 LIB2ADD += $(srcdir)/config/s390/sfp-exceptions.c
+softfp_extras := fixtfbitint floatbitinttf

Reply via email to