From: Stefan Schulze Frielinghaus Date: Thu, 7 Aug 2025 06:39:11 +0000 (+0200) Subject: s390: Add _BitInt support X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=48787c734ee647cb99abb1e95d937f1ba66e78d0;p=thirdparty%2Fgcc.git 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 --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 012b6dbb6e0..d044f9a010c 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 00000000000..8bdf2ae09bc --- /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 00000000000..9b0e6b916aa --- /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 00000000000..91320282525 --- /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 00000000000..dce72d8ab11 --- /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 86c55a0128b..00375b3df0e 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 f29f40f2ced..724b15e83ba 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