diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h index e849af9038b..552f58b2cc8 100644 --- a/gcc/config/sparc/sol2.h +++ b/gcc/config/sparc/sol2.h @@ -456,3 +456,6 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #undef SPARC_LOW_FE_EXCEPT_VALUES #define SPARC_LOW_FE_EXCEPT_VALUES 1 + +#undef SUN_V9_ABI_COMPATIBILITY +#define SUN_V9_ABI_COMPATIBILITY 1 diff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc index 30fa4474bbd..8a5f76c8885 100644 --- a/gcc/config/sparc/sparc.cc +++ b/gcc/config/sparc/sparc.cc @@ -6782,6 +6782,22 @@ sparc_pass_by_reference (cumulative_args_t, const function_arg_info &arg) || GET_MODE_SIZE (mode) > 16); } +/* Return true if TYPE is considered as a floating-point type by the ABI. */ + +static bool +fp_type_for_abi (const_tree type) +{ + /* This is the original GCC implementation. */ + if (FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)) + return true; + + /* This has been introduced in GCC 14 to match the vendor compiler. */ + if (SUN_V9_ABI_COMPATIBILITY && TREE_CODE (type) == ARRAY_TYPE) + return fp_type_for_abi (TREE_TYPE (type)); + + return false; +} + /* Traverse the record TYPE recursively and call FUNC on its fields. NAMED is true if this is for a named parameter. DATA is passed to FUNC for each field. OFFSET is the starting position and @@ -6820,8 +6836,7 @@ traverse_record_type (const_tree type, bool named, T *data, packed); else { - const bool fp_type - = FLOAT_TYPE_P (field_type) || VECTOR_TYPE_P (field_type); + const bool fp_type = fp_type_for_abi (field_type); Func (field, bitpos, fp_type && named && !packed && TARGET_FPU, data); } @@ -7072,6 +7087,13 @@ compute_fp_layout (const_tree field, int bitpos, assign_data_t *data, mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (field))); nregs = 2; } + else if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE) + { + tree elt_type = strip_array_types (TREE_TYPE (field)); + mode = TYPE_MODE (elt_type); + nregs + = int_size_in_bytes (TREE_TYPE (field)) / int_size_in_bytes (elt_type); + } else nregs = 1; diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index fb074808d30..232ecb30ddc 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1700,3 +1700,6 @@ extern int sparc_indent_opcode; #define SPARC_LOW_FE_EXCEPT_VALUES 0 #define TARGET_SUPPORTS_WIDE_INT 1 + +/* Define this to 1 to accept ABI changes to match the vendor compiler. */ +#define SUN_V9_ABI_COMPATIBILITY 0