https://gcc.gnu.org/g:e256eb478ad1b8c2c767aa35e03903bf4cd7c842
commit r16-8084-ge256eb478ad1b8c2c767aa35e03903bf4cd7c842 Author: Andre Vieira <[email protected]> Date: Fri Mar 13 15:31:18 2026 +0000 arm: Add support for _BitInt(N) This patch adds support for C23's _BitInt feature to the arm port. 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. * config/arm/arm-protos.h (arm_bitint_type_info): New declaration. 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. Diff: --- gcc/config/arm/arm-protos.h | 1 + gcc/config/arm/arm.cc | 55 ++++++++++++++++++++++++++++++++++++-- libgcc/config/arm/libgcc-bpabi.ver | 11 ++++++++ libgcc/config/arm/t-softfp | 2 ++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 7dc5dacf62d0..cbfb473037c5 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 decbeaad0f7b..24a57c687787 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -842,6 +842,9 @@ static const scoped_attribute_specs *const arm_attribute_table[] = #undef TARGET_FLAGS_REGNUM #define TARGET_FLAGS_REGNUM CC_REGNUM + +#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; @@ -6130,6 +6133,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; @@ -6159,8 +6164,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; @@ -7219,6 +7226,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; @@ -35886,6 +35901,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 75cb6261f7ba..8e3b382e4bbf 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 554ec9bc47b0..68aff4de0687 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
