From 0cb8aad8a376643792166797b87d89dce02a18f1 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sun, 23 Aug 2020 16:02:01 +0100 Subject: [PATCH] Darwin, Arm64 : Adjust cases where stack spills pack differently. + Temporary handling for complex values. Complex values with a total size less than one stack slot might conceivably be packed in the same manner as other small values. However, this is not done - and we need to override the process for them. + Don't pack small structs either. Darwinpcs doesn't mention some things - and one is small structs. These are put into regs - but, when they spill to the stack, they don't pack in the manner of char, int et. al. + Handle HFA cases that have packed stack layout. bleah! (not sure this is complete). + Exclude unions from packing rule. + Hide an unused function. We are not using aarch64_vfp_is_call_candidate so wrap it in an #ifdef. + Fix a build error. Drop an unused var. --- gcc/config/aarch64/aarch64.cc | 38 ++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 3c1da69be97b..aaceb7eda3c9 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -6626,6 +6626,7 @@ aarch64_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) gcc_unreachable (); } +#if !TARGET_MACHO static bool aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, const_tree type, int *nregs) @@ -6635,6 +6636,7 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, &pcum->aapcs_vfp_rmode, nregs, NULL, pcum->silent_p); } +#endif /* Given MODE and TYPE of a function argument, return the alignment in bits. The idea is to suppress any stronger alignment requested by @@ -6778,10 +6780,18 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) size = ROUND_UP (size, UNITS_PER_WORD); allocate_ncrn = (type) ? !(FLOAT_TYPE_P (type)) : !FLOAT_MODE_P (mode); + bool is_ha = false; +#if !TARGET_MACHO allocate_nvrn = aarch64_vfp_is_call_candidate (pcum_v, mode, type, &nregs); +#else + allocate_nvrn = aarch64_vfp_is_call_or_return_candidate (mode, type, + &pcum->aapcs_vfp_rmode, + &nregs, &is_ha, + pcum->silent_p); +#endif gcc_assert (!sve_p || !allocate_nvrn); /* allocate_ncrn may be false-positive, but allocate_nvrn is quite reliable. @@ -6943,9 +6953,15 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) at the end. When the current position is 0 - any allocation needs a stack slot. CHECKME: do we need to align 16byte entities? - but we don't do this for unnamed parms in variadic functions, they + but we don't do this for: + * unnamed parms in variadic functions + * complex types smaller than 4 bytes each get their own slot. */ - if (!arg.named) + if (!arg.named + || TREE_CODE (type) == COMPLEX_TYPE + || (TREE_CODE (type) == RECORD_TYPE + && !is_ha && !SCALAR_FLOAT_MODE_P (pcum->aapcs_vfp_rmode)) + || TREE_CODE (type) == UNION_TYPE) { pcum->aapcs_stack_words = size / UNITS_PER_WORD; pcum->darwinpcs_sub_word_offset = 0; @@ -7032,6 +7048,7 @@ aarch64_init_cumulative_args (CUMULATIVE_ARGS *pcum, pcum->darwinpcs_sub_word_offset = 0; pcum->darwinpcs_sub_word_pos = 0; pcum->silent_p = silent_p; + pcum->aapcs_vfp_rmode = VOIDmode; if (!silent_p && !TARGET_FLOAT @@ -7105,12 +7122,23 @@ aarch64_function_arg_regno_p (unsigned regno) static unsigned int aarch64_function_arg_boundary (machine_mode mode, const_tree type) { -#if TARGET_MACHO - return MIN (alignment, STACK_BOUNDARY); -#else unsigned int abi_break; unsigned int alignment = aarch64_function_arg_alignment (mode, type, &abi_break); +#if TARGET_MACHO + /* Temporary fudge to put some non-scalar types in distinct stack slots. */ + machine_mode comp_mode = VOIDmode; + int nregs; + bool is_ha; + aarch64_vfp_is_call_or_return_candidate (mode, type, &comp_mode, &nregs, + &is_ha, /*silent*/true); + if (TREE_CODE (type) == COMPLEX_TYPE + || (TREE_CODE (type) == RECORD_TYPE + && !is_ha && !SCALAR_FLOAT_MODE_P (comp_mode)) + || TREE_CODE (type) == UNION_TYPE) + return MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); + return MIN (alignment, STACK_BOUNDARY); +#else alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); if (abi_break & warn_psabi) {