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)

Reply via email to