Note: This patch is not yet ready for trunk as its dependent on some patches that are not-yet-upstream, however it serves as motivation for the previous patch(es) which are independent.
---- The AArch64 Darwin platform requires that named stack arguments are passed naturally-aligned, while variadic stack arguments are passed on word boundaries. Use the TARGET_FUNCTION_ARG_BOUNDARY_CA and TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA target hooks to let the backend correctly layout stack parameters. gcc/ChangeLog: * config.gcc: Enable -fstack-use-cumulative-args by default if the host platform is MacOS 11.x or 12.x and we're on AArch64. gcc/config/aarch64/ChangeLog: * aarch64-protos.h (aarch64_init_cumulative_incoming_args): Declare. * aarch64.c (aarch64_init_cumulative_args): Initialize `darwinpcs_n_named` (Total number of named parameters) and `darwinpcs_n_args_processed` (Total number of parameters we have processed, including variadic if any.) (aarch64_init_cumulative_incoming_args): Implement the INIT_CUMULATIVE_INCOMING_ARGS macro in order to capture information on the number of named parameters for the current function. (aarch64_function_arg_advance): Increment `darwinpcs_n_args_processed` each time we layout a function parameter. (aarch64_function_arg_boundary_ca): Implement TARGET_FUNCTION_ARG_BOUNDARY_CA and TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA to layout args based on whether we're a named parameter or not. (aarch64_function_arg_round_boundary_ca): Ditto. (TARGET_FUNCTION_ARG_BOUNDARY_CA): Define. (TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA): Ditto. * aarch64.h (CUMULATIVE_ARGS): Add `darwinpcs_n_named` and `darwinpcs_n_args_processed`. (INIT_CUMULATIVE_INCOMING_ARGS): Define. --- gcc/config.gcc | 7 ++++ gcc/config/aarch64/aarch64-protos.h | 1 + gcc/config/aarch64/aarch64.c | 56 +++++++++++++++++++++++++++++ gcc/config/aarch64/aarch64.h | 5 +++ 4 files changed, 69 insertions(+) diff --git a/gcc/config.gcc b/gcc/config.gcc index e12a9f042d0..626ba089c07 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1072,6 +1072,13 @@ esac # Figure out if we need to enable -foff-stack-trampolines by default. case ${target} in +aarch64*-*darwin* | arm64*-*darwin*) + if test ${macos_maj} = 11 || test ${macos_maj} = 12; then + tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=1" + else + tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0" + fi + ;; *) tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0" ;; diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index a204647241e..cdc51fce906 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -896,6 +896,7 @@ void aarch64_expand_vector_init (rtx, rtx); void aarch64_sve_expand_vector_init (rtx, rtx); void aarch64_init_cumulative_args (CUMULATIVE_ARGS *, const_tree, rtx, const_tree, unsigned, bool = false); +void aarch64_init_cumulative_incoming_args (CUMULATIVE_ARGS *, const_tree, rtx); void aarch64_init_expanders (void); void aarch64_init_simd_builtins (void); void aarch64_emit_call_insn (rtx); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 38b3f1eab89..70c2336ab3a 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -7042,6 +7042,8 @@ aarch64_init_cumulative_args (CUMULATIVE_ARGS *pcum, pcum->darwinpcs_stack_bytes = 0; pcum->darwinpcs_sub_word_offset = 0; pcum->darwinpcs_sub_word_pos = 0; + pcum->darwinpcs_n_named = n_named; + pcum->darwinpcs_n_args_processed = 0; pcum->silent_p = silent_p; pcum->aapcs_vfp_rmode = VOIDmode; @@ -7072,6 +7074,20 @@ aarch64_init_cumulative_args (CUMULATIVE_ARGS *pcum, } } +void +aarch64_init_cumulative_incoming_args (CUMULATIVE_ARGS *pcum, + const_tree fntype, + rtx libname ATTRIBUTE_UNUSED) +{ +#if !TARGET_MACHO + INIT_CUMULATIVE_ARGS (*pcum, fntype, libname, current_function_decl, -1); +#else + int n_named_args = (list_length (TYPE_ARG_TYPES (fntype))); + + aarch64_init_cumulative_args (pcum, fntype, libname, current_function_decl, n_named_args); +#endif +} + static void aarch64_function_arg_advance (cumulative_args_t pcum_v, const function_arg_info &arg) @@ -7092,6 +7108,7 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v, pcum->aapcs_stack_size += pcum->aapcs_stack_words; pcum->aapcs_stack_words = 0; pcum->aapcs_reg = NULL_RTX; + pcum->darwinpcs_n_args_processed++; } } @@ -7147,6 +7164,19 @@ aarch64_function_arg_boundary (machine_mode mode, const_tree type) #endif } +static unsigned int +aarch64_function_arg_boundary_ca (machine_mode mode, const_tree type, + cumulative_args_t ca) +{ + CUMULATIVE_ARGS *pcum = get_cumulative_args (ca); + bool named_p = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named; + + if (named_p) + return aarch64_function_arg_boundary (mode, type); + else + return MAX (aarch64_function_arg_boundary (mode, type), PARM_BOUNDARY); +} + #if TARGET_MACHO /* Implement TARGET_FUNCTION_ARG_ROUND_BOUNDARY for darwinpcs which allows non-standard passing of byte-aligned items [D.2]. @@ -7157,6 +7187,26 @@ aarch64_function_arg_round_boundary (machine_mode, const_tree) { return BITS_PER_UNIT; } + +static unsigned int +aarch64_function_arg_round_boundary_ca (machine_mode mode, const_tree type, + cumulative_args_t ca) +{ + CUMULATIVE_ARGS *pcum = get_cumulative_args (ca); + bool named_p = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named; + bool last_named_p = pcum->darwinpcs_n_args_processed + 1 == pcum->darwinpcs_n_named; + + if (named_p) + { + if (last_named_p) + return PARM_BOUNDARY; + else + return aarch64_function_arg_round_boundary (mode, type); + } + else + return PARM_BOUNDARY; +} + #endif /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */ @@ -26692,9 +26742,15 @@ aarch64_run_selftests (void) #undef TARGET_FUNCTION_ARG_BOUNDARY #define TARGET_FUNCTION_ARG_BOUNDARY aarch64_function_arg_boundary +#undef TARGET_FUNCTION_ARG_BOUNDARY_CA +#define TARGET_FUNCTION_ARG_BOUNDARY_CA aarch64_function_arg_boundary_ca + #if TARGET_MACHO #undef TARGET_FUNCTION_ARG_ROUND_BOUNDARY #define TARGET_FUNCTION_ARG_ROUND_BOUNDARY aarch64_function_arg_round_boundary + +#undef TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA +#define TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA aarch64_function_arg_round_boundary_ca #endif #undef TARGET_FUNCTION_ARG_PADDING diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 82d8803149b..2ea45fd829b 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -997,6 +997,8 @@ typedef struct when placing smaller items for darwinpcs. */ int darwinpcs_sub_word_pos; /* The next byte available within the word for darwinpcs. */ + int darwinpcs_n_named; /* Number of named arguments. */ + int darwinpcs_n_args_processed; /* Number of arguments processed so far. */ bool silent_p; /* True if we should act silently, rather than raise an error for invalid calls. */ } CUMULATIVE_ARGS; @@ -1010,6 +1012,9 @@ typedef struct #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \ aarch64_init_cumulative_args (&(CUM), FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) +#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \ + aarch64_init_cumulative_incoming_args (&(CUM), FNTYPE, LIBNAME) + #define FUNCTION_ARG_REGNO_P(REGNO) \ aarch64_function_arg_regno_p(REGNO) -- 2.30.1 (Apple Git-130)