return default_mode_for_floating_type (ti);
}
+/* Implement TARGET_C_BITINT_TYPE_INFO.
+ Return true if _BitInt(N) is supported and fill its details into *INFO. */
+bool
+riscv_bitint_type_info (int n, struct bitint_info *info)
+{
+ if (n <= 8)
+ info->limb_mode = QImode;
+ else if (n <= 16)
+ info->limb_mode = HImode;
+ else if (n <= 32)
+ info->limb_mode = SImode;
+ else if (n <= 64)
+ info->limb_mode = DImode;
+ else if (n <= 128 && TARGET_64BIT)
+ info->limb_mode = TImode;
+ else
+ info->limb_mode = TARGET_64BIT ? DImode : SImode;
+
+ info->abi_limb_mode = info->limb_mode;
+
+ if (n > 64 && TARGET_64BIT)
+ info->abi_limb_mode = TImode;
+
+ if (n > 32 && !TARGET_64BIT)
+ info->abi_limb_mode = DImode;
+
+ info->big_endian = TARGET_BIG_ENDIAN;
+ info->extended = true;
+ return true;
+}
+
/* This parses the version string STR and modifies the feature mask and
priority required to select those targets.
If LOC is nonnull, report diagnostics against *LOC, otherwise
#undef TARGET_C_MODE_FOR_FLOATING_TYPE
#define TARGET_C_MODE_FOR_FLOATING_TYPE riscv_c_mode_for_floating_type
+#undef TARGET_C_BITINT_TYPE_INFO
+#define TARGET_C_BITINT_TYPE_INFO riscv_bitint_type_info
+
#undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
#define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P riscv_use_by_pieces_infrastructure_p
/* PR middle-end/114332 */
/* { dg-do run { target bitint } } */
+/* { dg-require-effective-target sync_char_short } */
/* { dg-options "-std=c23 -fwrapv" } */
/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */
/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
/* { dg-do run { target bitint } } */
+/* { dg-require-effective-target sync_char_short } */
/* { dg-options "-std=c23 -pedantic-errors" } */
/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */
/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
/* A simple variant of gcc.dg/torture/bitint-64.c */
/* { dg-do run { target bitint } } */
+/* { dg-require-effective-target sync_char_short } */
/* { dg-options "-std=c23" } */
/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */
/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
--- /dev/null
+/* { dg-do compile { target bitint } } */
+/* { dg-additional-options "-march=rv64gc -mabi=lp64d -std=c23 -O -fno-stack-clash-protection -g -fpie -mcmodel=medlow -fno-section-anchors" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" "-O0"} } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+signed _BitInt(32) a;
+unsigned _BitInt(32) b;
+signed _BitInt(16) c;
+unsigned _BitInt(16) d;
+
+signed _BitInt(32) f1(void) {
+/*
+** f1:
+** ...
+** lw a0,a
+** ret
+*/
+ return a;
+}
+unsigned _BitInt(32) f2(void) {
+/*
+** f2:
+** ...
+** lw a0,b
+** ret
+*/
+ return b;
+}
+
+signed _BitInt(16) f3(void) {
+/*
+** f3:
+** ...
+** lh a0,c
+** ret
+*/
+ return c;
+}
+unsigned _BitInt(16) f4(void) {
+/*
+** f4:
+** ...
+** lhu a0,d
+** ret
+*/
+ return d;
+}
--- /dev/null
+/* { dg-do run { target bitint } } */
+/* { dg-additional-options "-std=c23" } */
+
+static long unsigned int
+calc_alignof (int n)
+{
+#if __riscv_xlen == 64
+ if (n > 64)
+ return alignof(__int128_t);
+#endif
+ if (n > 32)
+ return alignof(long long);
+ if (n > 16)
+ return alignof(int);
+ if (n > 8)
+ return alignof(short);
+ else
+ return alignof(char);
+}
+
+#define CHECK_ALIGNMENT(N) \
+ if (alignof(_BitInt(N)) != calc_alignof(N)) \
+ __builtin_abort ();
+
+int main (void)
+{
+ CHECK_ALIGNMENT(2);
+ CHECK_ALIGNMENT(3);
+ CHECK_ALIGNMENT(7);
+ CHECK_ALIGNMENT(8);
+ CHECK_ALIGNMENT(9);
+ CHECK_ALIGNMENT(13);
+ CHECK_ALIGNMENT(15);
+ CHECK_ALIGNMENT(16);
+ CHECK_ALIGNMENT(17);
+ CHECK_ALIGNMENT(24);
+ CHECK_ALIGNMENT(31);
+ CHECK_ALIGNMENT(32);
+ CHECK_ALIGNMENT(33);
+ CHECK_ALIGNMENT(42);
+ CHECK_ALIGNMENT(53);
+ CHECK_ALIGNMENT(63);
+ CHECK_ALIGNMENT(64);
+ CHECK_ALIGNMENT(65);
+ CHECK_ALIGNMENT(79);
+ CHECK_ALIGNMENT(96);
+ CHECK_ALIGNMENT(113);
+ CHECK_ALIGNMENT(127);
+ CHECK_ALIGNMENT(128);
+ CHECK_ALIGNMENT(129);
+ CHECK_ALIGNMENT(153);
+ CHECK_ALIGNMENT(255);
+ CHECK_ALIGNMENT(256);
+ CHECK_ALIGNMENT(257);
+ CHECK_ALIGNMENT(353);
+ CHECK_ALIGNMENT(512);
+ CHECK_ALIGNMENT(620);
+ CHECK_ALIGNMENT(1024);
+ CHECK_ALIGNMENT(30000);
+}
--- /dev/null
+/* { dg-do compile { target bitint } } */
+/* { dg-additional-options "-march=rv64gc -mabi=lp64d -std=c23 -O -fno-stack-clash-protection -g" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" "-O0"} } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#define CHECK_ARG(N) \
+void f##N(_BitInt(N) *ptr, _BitInt(N) y) \
+{ \
+ *ptr = y; \
+}
+
+
+CHECK_ARG(2)
+/*
+** f2:
+** sb a1,0\(a0\)
+** ret
+*/
+CHECK_ARG(8)
+/*
+** f8:
+** sb a1,0\(a0\)
+** ret
+*/
+CHECK_ARG(9)
+/*
+** f9:
+** sh a1,0\(a0\)
+** ret
+*/
+CHECK_ARG(16)
+/*
+** f16:
+** sh a1,0\(a0\)
+** ret
+*/
+CHECK_ARG(19)
+/*
+** f19:
+** sw a1,0\(a0\)
+** ret
+*/
+CHECK_ARG(32)
+/*
+** f32:
+** sw a1,0\(a0\)
+** ret
+*/
+CHECK_ARG(42)
+/*
+** f42:
+** sd a1,0\(a0\)
+** ret
+*/
+CHECK_ARG(64)
+/*
+** f64:
+** sd a1,0\(a0\)
+** ret
+*/
+CHECK_ARG(65)
+/*
+** f65:
+** sd a1,0\(a0\)
+** sd a2,8\(a0\)
+** ret
+*/
+CHECK_ARG(127)
+/*
+** f127:
+** sd a1,0\(a0\)
+** sd a2,8\(a0\)
+** ret
+*/
+
+CHECK_ARG(128)
+/*
+** f128:
+** sd a1,0\(a0\)
+** sd a2,8\(a0\)
+** ret
+*/
--- /dev/null
+/* { dg-do run { target bitint } } */
+/* { dg-additional-options "-std=c23" } */
+
+static long unsigned int
+calc_size (int n)
+{
+#if __riscv_xlen == 64
+ if (n > 128)
+ return ((n - 1)/128 + 1) * sizeof(__int128_t);
+ if (n > 64)
+ return sizeof(__int128_t);
+#elif __riscv_xlen == 32
+ if (n > 64)
+ return ((n - 1)/64 + 1) * sizeof(long long);
+#endif
+ if (n > 32)
+ return sizeof(long long);
+ if (n > 16)
+ return sizeof(int);
+ if (n > 8)
+ return sizeof(short);
+ else
+ return sizeof(char);
+}
+
+#define CHECK_SIZE(N) \
+ if (sizeof(_BitInt(N)) != calc_size(N)) \
+ __builtin_abort ();
+
+int main (void)
+{
+ CHECK_SIZE(2);
+ CHECK_SIZE(3);
+ CHECK_SIZE(7);
+ CHECK_SIZE(8);
+ CHECK_SIZE(9);
+ CHECK_SIZE(13);
+ CHECK_SIZE(15);
+ CHECK_SIZE(16);
+ CHECK_SIZE(17);
+ CHECK_SIZE(24);
+ CHECK_SIZE(31);
+ CHECK_SIZE(32);
+ CHECK_SIZE(33);
+ CHECK_SIZE(42);
+ CHECK_SIZE(53);
+ CHECK_SIZE(63);
+ CHECK_SIZE(64);
+ CHECK_SIZE(65);
+ CHECK_SIZE(79);
+ CHECK_SIZE(96);
+ CHECK_SIZE(113);
+ CHECK_SIZE(127);
+ CHECK_SIZE(128);
+ CHECK_SIZE(129);
+ CHECK_SIZE(153);
+ CHECK_SIZE(255);
+ CHECK_SIZE(256);
+ CHECK_SIZE(257);
+ CHECK_SIZE(353);
+ CHECK_SIZE(512);
+ CHECK_SIZE(620);
+ CHECK_SIZE(1024);
+ CHECK_SIZE(30000);
+}
--- /dev/null
+# Copyright (C) 2025 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+GCC_16.0.0 {
+ __mulbitint3
+ __divmodbitint4
+ __fixsfbitint
+ __fixdfbitint
+ __fixtfbitint
+ __floatbitinthf
+ __floatbitintsf
+ __floatbitintdf
+ __floatbitinttf
+}
# Avoid the full unwinder being pulled along with the division libcalls.
LIB2_DIVMOD_EXCEPTION_FLAGS := -fasynchronous-unwind-tables
+
+SHLIB_MAPFILES += $(srcdir)/config/riscv/libgcc-riscv.ver
endif
+softfp_extras += floatbitinttf fixtfbitint
+
else
# ABI_QUAD
hfbf bfhf
softfp_extras += fixhfsi fixhfdi fixunshfsi fixunshfdi \
floatsihf floatdihf floatunsihf floatundihf \
- floatsibf floatdibf floatunsibf floatundibf
+ floatsibf floatdibf floatunsibf floatundibf \
+ floatbitinthf