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).