public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] aarch64: Incoming side of new Morello varargs PCS
@ 2021-12-10 16:49 Matthew Malcomson
  0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2021-12-10 16:49 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:ae1682cf8a2dd640c0d6fe3ca5934e5df9ace342

commit ae1682cf8a2dd640c0d6fe3ca5934e5df9ace342
Author: Alex Coplan <alex.coplan@arm.com>
Date:   Fri Oct 29 12:52:46 2021 +0100

    aarch64: Incoming side of new Morello varargs PCS
    
    This patch implements the incoming side of the new Morello varargs PCS
    (https://github.com/ARM-software/abi-aa/pull/112).
    
    gcc/ChangeLog:
    
            * config/aarch64/aarch64.c
            (aarch64_current_function_variadic_p): New. Use it ...
            (aarch64_function_arg_regno_p): ... here. Return true for C9 on
            AAPCS64-cap if the current function is variadic.
            (aarch64_build_builtin_va_list): For
            AAPCS64-cap, return ptr_type_node (i.e. void *).
            (aarch64_expand_builtin_va_start): For AAPCS64-cap, set the
            valist pointer to the incoming varargs pseudo.
            (aarch64_purecap_gimplify_va_arg_expr): New. Call it ...
            (aarch64_gimplify_va_arg_expr): ... here (for purecap).
            (aarch64_setup_incoming_varargs): For AAPCS64-cap, move c9 to a
            pseudo at the start of the function so that we can use it later
            on in va_start.
            * config/aarch64/aarch64.h (machine_function): New member
            purecap_incoming_varargs_reg.

Diff:
---
 gcc/config/aarch64/aarch64.c | 98 ++++++++++++++++++++++++++++++++++++++++++++
 gcc/config/aarch64/aarch64.h |  2 +
 2 files changed, 100 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 22bd98ddd2e..3575714d01e 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -6610,9 +6610,23 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v,
     }
 }
 
+static bool
+aarch64_current_function_variadic_p (void)
+{
+  tree t = TREE_TYPE (current_function_decl);
+  for (t = TYPE_ARG_TYPES (t); t; t = TREE_CHAIN (t))
+    if (t == void_list_node)
+      return false;
+
+  return true;
+}
+
 bool
 aarch64_function_arg_regno_p (unsigned regno)
 {
+  if (TARGET_CAPABILITY_PURE && regno == R9_REGNUM)
+    return aarch64_current_function_variadic_p ();
+
   return ((GP_REGNUM_P (regno) && regno < R0_REGNUM + NUM_ARG_REGS)
 	  || (FP_REGNUM_P (regno) && regno < V0_REGNUM + NUM_FP_ARG_REGS));
 }
@@ -17016,6 +17030,10 @@ static GTY(()) tree va_list_type;
 static tree
 aarch64_build_builtin_va_list (void)
 {
+  /* For AAPCS64-cap, va_list is just void*.  */
+  if (TARGET_CAPABILITY_PURE)
+    return ptr_type_node;
+
   tree va_list_name;
   tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff;
 
@@ -17090,6 +17108,14 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
   int vr_save_area_size = cfun->va_list_fpr_size;
   int vr_offset;
 
+  if (TARGET_CAPABILITY_PURE)
+    {
+      t = make_tree (TREE_TYPE (valist), cfun->machine->purecap_incoming_varargs_reg);
+      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
+      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+      return;
+    }
+
   cum = &crtl->args.info;
   if (cfun->va_list_gpr_size)
     gr_save_area_size = MIN ((NUM_ARG_REGS - cum->aapcs_ncrn) * UNITS_PER_WORD,
@@ -17161,6 +17187,42 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
 }
 
+static tree
+aarch64_purecap_gimplify_va_arg_expr (tree ap, tree type, gimple_seq *pre_p)
+{
+  tree t, arg, ap0;
+
+  /* First, save a copy of ap into a temporary.  */
+  arg = ap0 = get_initialized_tmp_var (ap, pre_p, NULL);
+
+  auto type_sz = int_size_in_bytes (type);
+  if (type_sz == -1
+      || type_sz > 16
+      || maybe_gt (TYPE_ALIGN (type), 16U * BITS_PER_UNIT))
+    {
+      /* Indirection: arg = *(void **)arg.  */
+      tree void_star_star = build_pointer_type (TREE_TYPE (ap));
+      t = build2 (MEM_REF, TREE_TYPE (ap),
+		  arg,
+		  build_int_cst (void_star_star, 0));
+
+      arg = get_initialized_tmp_var (t, pre_p, NULL);
+    }
+
+  /* Advance ap: ap = (void**)ap + 1.  */
+  if (type_sz)
+    {
+      t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ap), ap0,
+		  size_int (int_size_in_bytes (TREE_TYPE (ap))));
+      t = get_initialized_tmp_var (t, pre_p, NULL);
+      gimple_seq_add_stmt (pre_p, gimple_build_assign (ap, t));
+    }
+
+  /* Compute result: *(type *)arg.  */
+  t = build2 (MEM_REF, type, arg, build_int_cst (build_pointer_type (type), 0));
+  return t;
+}
+
 /* Implement TARGET_GIMPLIFY_VA_ARG_EXPR.  */
 
 static tree
@@ -17180,6 +17242,9 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
   HOST_WIDE_INT size, rsize, adjust, align;
   tree t, u, cond1, cond2;
 
+  if (TARGET_CAPABILITY_PURE)
+    return aarch64_purecap_gimplify_va_arg_expr (valist, type, pre_p);
+
   indirect_p = pass_va_arg_by_reference (type);
   if (indirect_p)
     type = build_pointer_type (type);
@@ -17440,6 +17505,39 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v,
   int gr_saved = cfun->va_list_gpr_size;
   int vr_saved = cfun->va_list_fpr_size;
 
+  /* For AAPCS64-cap, the incoming varargs are passed in C9, so to set
+     them up we simply move C9 to a pseudo that we can use to access them in
+     the body of the function.
+
+     The documentation for this hook says "Use [the hook] to store the
+     anonymous register arguments into the stack [...].  Once this is done,
+     you can use the standard implementation of varargs that works for
+     machines that pass all their arguments on the stack."
+
+     Of course, moving C9 to a pseudo does not constitute pushing any
+     arguments to the stack.  So why is this valid?  Note that targets that
+     override gimplify_va_arg_expr and build_builtin_va_list (such as
+     AArch64) are already not using the "standard implementation of
+     varargs", so this constraint does not matter.  Moreover, the code that
+     calls this hook (from calls.c:assign_parms) is precisely the code that
+     moves the hard registers in which the function receives its arguments
+     into pseudos to be used in the function body.  So we are just using
+     this hook as a convenient place to do this for the C9 register used to
+     pass the Anonymous Argument Memory Area for AAPCS64-cap.  */
+  if (TARGET_CAPABILITY_PURE)
+    {
+      if (!no_rtl)
+	{
+	  rtx c9 = gen_rtx_REG (Pmode, R9_REGNUM);
+	  rtx pseudo = gen_reg_rtx (Pmode);
+	  emit_move_insn (pseudo, c9);
+	  cfun->machine->purecap_incoming_varargs_reg = pseudo;
+	}
+
+      cfun->machine->frame.saved_varargs_size = 0;
+      return;
+    }
+
   /* The caller has advanced CUM up to, but not beyond, the last named
      argument.  Advance a local copy of CUM past the last "real" named
      argument, to find out how many registers are left over.  */
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 080c858c35b..81715803e48 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -922,6 +922,8 @@ typedef struct GTY (()) machine_function
   bool reg_is_wrapped_separately[LAST_SAVED_REGNUM];
   /* One entry for each general purpose register.  */
   rtx call_via[SP_REGNUM];
+  /* AAPCS64-cap incoming varargs pseudo.  */
+  rtx purecap_incoming_varargs_reg;
   bool label_is_assembled;
 } machine_function;
 #endif


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-12-10 16:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-10 16:49 [gcc(refs/vendors/ARM/heads/morello)] aarch64: Incoming side of new Morello varargs PCS Matthew Malcomson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).