From ca58d3990e8d29e0e3e97f5236baf6501ba3a1a2 Mon Sep 17 00:00:00 2001
From: Iain Sandoe <iain@sandoe.co.uk>
Date: Thu, 20 Aug 2020 17:08:46 +0100
Subject: [PATCH] Darwin, Arm64 : Initial stab at darwinpcs variadic functions.

These use the simpler char * version - but it remains to be seen if
we need a non-standard rendition to cater for any amusing platform
differences.

(cherry picked from commit b6a37008af81caa7bfcedf9f5c0d7c6122235c35)
Signed-off-by: Kirill A. Korinsky <kirill@korins.ky>
---
 gcc/config/aarch64/aarch64.c | 38 ++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git gcc/config/aarch64/aarch64.c gcc/config/aarch64/aarch64.c
index 92ae9bc1f40..99cf8652c70 100644
--- gcc/config/aarch64/aarch64.c
+++ gcc/config/aarch64/aarch64.c
@@ -6327,7 +6327,18 @@ on_stack:
 	 size is rounded up to 8 bytes, so will account for enough slots to
 	 accommodate the entire argument - potentially, with some padding
 	 at the end.  When the current position is 0 - any allocation needs
-	 a stack slot.  CHECKME: do we need to align 16byte entities?  */
+	 a stack slot.  CHECKME: do we need to align 16byte entities?
+
+	 but we don't do this for unnamed parms in variadic functinos, they
+	 each get their own slot.  */
+      if (!arg.named)
+	{
+	  pcum->aapcs_stack_words = size / UNITS_PER_WORD;
+	  /* We skip the re-alignment for 16byte things, since we currently
+	     assume that the don't force such alignment.  */
+	  return;
+	}
+
       if (pcum->darwinpcs_sub_word_pos == 0)
 	pcum->aapcs_stack_words = size / UNITS_PER_WORD;
 
@@ -16659,7 +16670,10 @@ static GTY(()) tree va_list_type;
      void *__vr_top;
      int   __gr_offs;
      int   __vr_offs;
-   };  */
+   };
+
+  darwinpcs uses 'char *' for the va_list (in common with other platform
+  ports).  */
 
 static tree
 aarch64_build_builtin_va_list (void)
@@ -16667,6 +16681,13 @@ aarch64_build_builtin_va_list (void)
   tree va_list_name;
   tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff;
 
+  /* darwinpcs uses a simple char * for this.  */
+  if (TARGET_MACHO)
+    {
+      va_list_type = build_pointer_type (char_type_node);
+      return va_list_type;
+    }
+
   /* Create the type.  */
   va_list_type = lang_hooks.types.make_type (RECORD_TYPE);
   /* Give it the required name.  */
@@ -16738,6 +16759,13 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
   int vr_save_area_size = cfun->va_list_fpr_size;
   int vr_offset;
 
+  /* darwinpcs uses the default, char * va_list impl.  */
+  if (TARGET_MACHO)
+    {
+      std_expand_builtin_va_start (valist, nextarg);
+      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,
@@ -16828,6 +16856,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_MACHO)
+    return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
+
   indirect_p = pass_va_arg_by_reference (type);
   if (indirect_p)
     type = build_pointer_type (type);
@@ -17083,6 +17114,9 @@ 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;
 
+  if (TARGET_MACHO)
+    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.  */
-- 
2.42.1

