As mentioned before there are still some failures, this version fixed some 
issues with arm_return_in_memory and arm_needs_doubleword_align aswell as 
addressed some comments below.


gcc/ChangeLog:

        * config/arm/arm.cc (TARGET_C_BITINT_TYPE_INFO): New Macro.
        (arm_return_in_memory): Return true for any _BitInt(N) where N > 64.
        (arm_needs_doubleword_align): Return true for any _BitInt(N) where N > 
32.
        (arm_bitint_type_info): New.

libgcc/ChangeLog:

        * config/arm/libgcc-bpabi.ver: Add new symbols.
        * config/arm/t-softfp: Enable use of floatbitinthf and pass necessary 
options to build fp16.

On 30/09/2025 09:53, Ramana Radhakrishnan wrote:
On Mon, Sep 29, 2025 at 10:53 PM Jakub Jelinek <[email protected]> wrote:
On Thu, Sep 25, 2025 at 10:23:46AM +0100, Andre Vieira wrote:
+/* Implement TARGET_C_BITINT_TYPE_INFO
+   Return true if _BitInt(N) is supported and fill its details into *INFO.  */
+
+bool
+arm_bitint_type_info (int n, struct bitint_info *info)
+{
+  if (TARGET_BIG_END)
+    return false;
Why?  Just that it isn't tested so far?  Big endian support in the generic
code should be there already, s390x _BitInt works.
Yes and I also wasn't aware the Big endian support was in. I'll try to find some spare cycles to test it locally and will enable it if most pass.
--- a/libgcc/config/arm/libgcc-bpabi.ver
+++ b/libgcc/config/arm/libgcc-bpabi.ver
@@ -106,3 +106,11 @@ GCC_3.5 {
  GCC_4.3.0 {
    _Unwind_Backtrace
  }
+
+GCC_16.0.0 {
I miss
   __mulbitint3
   __divmodbitint4
here, that is pretty much essential to export.
Don't you also need %import above it from whatever was the latest
GCC_* symver on arm?
Done, but tbf I'm not sure about this libgcc-bpabi.ver file, I am not entirely convinced it is used in anyway shape or form. Richard E did mention downstream that we probably want to use GCC_14 as that's when the symbols were added?
+    __fixsfbitint
+    __fixdfbitint
+    __floatbitinthf
+    __floatbitintsf
+    __floatbitintdf
+}
diff --git a/libgcc/config/arm/t-softfp b/libgcc/config/arm/t-softfp
index 554ec9bc47b..68aff4de068 100644
--- a/libgcc/config/arm/t-softfp
+++ b/libgcc/config/arm/t-softfp
@@ -1,2 +1,4 @@
  softfp_wrap_start := '\#if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1'
  softfp_wrap_end := '\#endif'
+bitint_extras += floatbitinthf
+softfp_cflags := -mfp16-format=ieee
Other than that LGTM but I think you want Richard/Ramana to ack it; I'd suggest
to xfail the 2 tests for arm with a PR (and CC me on that), that can be
resolved incrementally.
I'm good with the approach to xfail + PR and get that sorted .

Still recovering from travel to be able to do this justice. I expect
to have some free time on Thursday / Friday due to public holidays
here so will get back then.

There was some downstream pointers from Richard E, but I'll wait for an upstream review.
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 
ff7e7658f912dcf6ca0bc22e0614091f8ba93f65..9478cb57de50844ee6ebddb016bc1ff84c45b8ae
 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -209,6 +209,7 @@ extern bool arm_pad_reg_upward (machine_mode, tree, int);
 #endif
 extern int arm_apply_result_size (void);
 extern opt_machine_mode arm_get_mask_mode (machine_mode mode);
+extern bool arm_bitint_type_info (int, struct bitint_info *);
 extern bool arm_noce_conversion_profitable_p (rtx_insn *,struct noce_if_info 
*);
 
 #endif /* RTX_CODE */
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 
da28d96298a415bb2758eeae966e0045c2e6cec3..be03479ff424abb6afe5adab2701fab72cb0293f
 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -839,6 +839,9 @@ static const scoped_attribute_specs *const 
arm_attribute_table[] =
 
 #undef TARGET_VECTORIZE_GET_MASK_MODE
 #define TARGET_VECTORIZE_GET_MASK_MODE arm_get_mask_mode
+
+#undef TARGET_C_BITINT_TYPE_INFO
+#define TARGET_C_BITINT_TYPE_INFO arm_bitint_type_info
 
 /* Obstack for minipool constant handling.  */
 static struct obstack minipool_obstack;
@@ -6089,6 +6092,8 @@ arm_return_in_memory (const_tree type, const_tree fntype)
         We don't care about which register here, so we can short-cut
         some of the detail.  */
       if (!AGGREGATE_TYPE_P (type)
+         /* A _BitInt(N) for N <= 64 is a simple, non-aggregate type.  */
+         && !(TREE_CODE (type) == BITINT_TYPE && size > 8)
          && TREE_CODE (type) != VECTOR_TYPE
          && TREE_CODE (type) != COMPLEX_TYPE)
        return false;
@@ -6118,8 +6123,10 @@ arm_return_in_memory (const_tree type, const_tree fntype)
   if (TREE_CODE (type) == VECTOR_TYPE)
     return (size < 0 || size > (4 * UNITS_PER_WORD));
 
-  if (!AGGREGATE_TYPE_P (type) &&
-      (TREE_CODE (type) != VECTOR_TYPE))
+  if (!AGGREGATE_TYPE_P (type)
+      /* A _BitInt(N) for N <= 64 is a simple, non-aggregate type.  */
+      && !(TREE_CODE (type) == BITINT_TYPE && size > 8)
+      && (TREE_CODE (type) != VECTOR_TYPE))
     /* All simple types are returned in registers.  */
     return false;
 
@@ -7178,6 +7185,14 @@ arm_needs_doubleword_align (machine_mode mode, 
const_tree type)
   if (!type)
     return GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY;
 
+  /* For any _BitInt(N) where N > 32 the ABI demands double word alignment.  */
+  if (TREE_CODE (type) == BITINT_TYPE)
+    {
+      if (int_size_in_bytes (type) > 4)
+       return 1;
+      return 0;
+    }
+
   /* Scalar and vector types: Use natural alignment, i.e. of base type.  */
   if (!AGGREGATE_TYPE_P (type))
     return TYPE_ALIGN (TYPE_MAIN_VARIANT (type)) > PARM_BOUNDARY;
@@ -35818,6 +35833,42 @@ arm_get_mask_mode (machine_mode mode)
   return default_get_mask_mode (mode);
 }
 
+
+/* Implement TARGET_C_BITINT_TYPE_INFO
+   Return true if _BitInt(N) is supported and fill its details into *INFO.  */
+
+bool
+arm_bitint_type_info (int n, struct bitint_info *info)
+{
+  if (TARGET_BIG_END)
+    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 if (n <= 64)
+    info->limb_mode = DImode;
+  else
+    /* The AAPCS for Arm defines _BitInt(N > 64) as an array with
+       type {signed,unsigned} __int64[M] where M = (N/64) + 1.  However, to be
+       able to use libgcc's implementation to support large _BitInt's we need
+       to use a LIMB_MODE that is no larger than 'long int'.  This is why we
+       use SImode for our internal LIMB_MODE and we define the ABI_LIMB_MODE to
+       be DImode to ensure we are ABI compliant.  */
+    info->limb_mode = SImode;
+
+  if (n > 64)
+    info->abi_limb_mode = DImode;
+  else
+    info->abi_limb_mode = info->limb_mode;
+  info->big_endian = TARGET_BIG_END;
+  info->extended = true;
+  return true;
+}
+
 /* Helper function to determine whether SEQ represents a sequence of
    instructions representing the vsel<cond> floating point instructions.
    This is an heuristic to check whether the proposed optimisation is desired,
diff --git a/libgcc/config/arm/libgcc-bpabi.ver 
b/libgcc/config/arm/libgcc-bpabi.ver
index 
e4fe021cc47c73d26ff1883efbb50bef76b953da..ab8c395c96c7f265f689540502111d0571e6355c
 100644
--- a/libgcc/config/arm/libgcc-bpabi.ver
+++ b/libgcc/config/arm/libgcc-bpabi.ver
@@ -106,3 +106,14 @@ GCC_3.5 {
 GCC_4.3.0 {
   _Unwind_Backtrace
 }
+
+%inherit GCC_14.0.0 GCC_4.3.0
+GGC_14.0.0 {
+    __fixsfbitint
+    __fixdfbitint
+    __floatbitinthf
+    __floatbitintsf
+    __floatbitintdf
+    __mulbitint3
+    __divmodbitint4
+}
diff --git a/libgcc/config/arm/t-softfp b/libgcc/config/arm/t-softfp
index 
554ec9bc47b04445e79e84b1f957bf88680c08d1..68aff4de0687cfadb062069ad152ea0af7f8c5d6
 100644
--- a/libgcc/config/arm/t-softfp
+++ b/libgcc/config/arm/t-softfp
@@ -1,2 +1,4 @@
 softfp_wrap_start := '\#if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1'
 softfp_wrap_end := '\#endif'
+bitint_extras += floatbitinthf
+softfp_cflags := -mfp16-format=ieee

Reply via email to