This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, ppc/darwin 2/2] Make Darwin's call handling follow the style of AIX/ELFv2/sysv.


Hi,

The second patch normalises Darwin’s call handling to follow the same pattern that Alan introduced recently.

Hopefully it makes it clearer where there are differences (actually quite small in this case, but enough to make it better to separate the lowering).  It isn’t needed to fix bootstrap, but it was a good time to figure it out when dealing with this.

OK for trunk / next stage #1 / comments?
Iain

gcc/

	* config/rs6000/rs6000-protos.h (rs6000_call_darwin, rs6000_sibcall_darwin): New.
	(macho_call_template): remove.
	* config/rs6000/rs6000.c (get_prev_label): Forward declaration. 
	(rs6000_call_template_1): Handle Darwin. (macho_call_template): Remove.
	(rs6000_call_sysv): Remove handling for Darwin, save cookie value.
	(rs6000_call_darwin_1, rs6000_call_darwin, rs6000_sibcall_darwin): New.
	* config/rs6000/rs6000.md (define_expand “call”): Handle Darwin with its own
	expander. (define_expand “call_value”): Likewise. (define_expand “sibcall”): Likewise.
	(define_expand “sibcall_value”): Likewise.  (call_nonlocal_sysv): Remove 
	Darwin special-casing.  (call_value_nonlocal_sysv): Likewise.

From cf45459dc7f317bcf5f415219884e6b846fe01a1 Mon Sep 17 00:00:00 2001
From: Iain Sandoe <iain@sandoe.co.uk>
Date: Sat, 1 Dec 2018 16:23:20 +0000
Subject: [PATCH] [darwin,ppc] Update call expansions to follow the new scheme.

This also makes it a bit more apparent what we can remove when the
mlongcall optimisation is removed.
---
 gcc/config/rs6000/rs6000-protos.h |   8 +-
 gcc/config/rs6000/rs6000.c        | 195 +++++++++++++++++++++---------
 gcc/config/rs6000/rs6000.md       |  47 +++++--
 3 files changed, 180 insertions(+), 70 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index dfee1f28aa..6d2b7ed917 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -199,6 +199,10 @@ extern void rs6000_call_aix (rtx, rtx, rtx, rtx);
 extern void rs6000_sibcall_aix (rtx, rtx, rtx, rtx);
 extern void rs6000_call_sysv (rtx, rtx, rtx, rtx);
 extern void rs6000_sibcall_sysv (rtx, rtx, rtx, rtx);
+#if TARGET_MACHO
+extern void rs6000_call_darwin (rtx, rtx, rtx, rtx);
+extern void rs6000_sibcall_darwin (rtx, rtx, rtx, rtx);
+#endif
 extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
 extern void get_ppc476_thunk_name (char name[32]);
 extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins);
@@ -226,10 +230,6 @@ extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT,
 /* Declare functions in rs6000-d.c  */
 extern void rs6000_d_target_versions (void);
 
-#if TARGET_MACHO
-char *macho_call_template (rtx_insn *, rtx *, int, int);
-#endif
-
 #ifdef NO_DOLLAR_IN_LABEL
 const char * rs6000_xcoff_strip_dollar (const char *);
 #endif
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index bce968516c..5fef3fa036 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1364,6 +1364,7 @@ static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree,
 				       bool, bool);
 #if TARGET_MACHO
 static void macho_branch_islands (void);
+static tree get_prev_label (tree);
 #endif
 static rtx rs6000_legitimize_reload_address (rtx, machine_mode, int, int,
 					     int, int *);
@@ -21513,13 +21514,39 @@ rs6000_call_template_1 (rtx *operands, unsigned int funop, bool sibcall)
 	    ? "+32768" : ""));
 
   static char str[32];  /* 2 spare */
-  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2
-      || DEFAULT_ABI == ABI_DARWIN)
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg,
 	     sibcall ? "" : "\n\tnop");
   else if (DEFAULT_ABI == ABI_V4)
     sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg,
 	     flag_pic ? "@plt" : "");
+#if TARGET_MACHO
+  /* If/when we remove the mlongcall opt, we can share the AIX/ELFv2 case. */
+   else if (DEFAULT_ABI == ABI_DARWIN)
+    {
+      /* The cookie is in operand func+2.  */
+      gcc_checking_assert (GET_CODE (operands[funop + 2]) == CONST_INT);
+      int cookie = INTVAL (operands[funop + 2]);
+      if (cookie & CALL_LONG)
+	{
+	  tree funname = get_identifier (XSTR (operands[funop], 0));
+	  tree labelname = get_prev_label (funname);
+	  gcc_checking_assert (labelname && !sibcall);
+
+	  /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
+	     instruction will reach 'foo', otherwise link as 'bl L42'".
+	     "L42" should be a 'branch island', that will do a far jump to
+	     'foo'.  Branch islands are generated in
+	     macho_branch_islands().  */
+	  sprintf (str, "jbsr %%z%u,%.10s", funop,
+		   IDENTIFIER_POINTER (labelname));
+	}
+      else
+        /* Same as AIX or ELFv2, except to keep backwards compat, no nop
+	   after the call.  */
+	sprintf (str, "b%s %s%s", sibcall ? "" : "l", z, arg);
+    }
+#endif
   else
     gcc_unreachable ();
   return str;
@@ -33167,49 +33194,6 @@ get_prev_label (tree function_name)
   return NULL_TREE;
 }
 
-/* INSN is either a function call or a millicode call.  It may have an
-   unconditional jump in its delay slot.
-
-   CALL_DEST is the routine we are calling.  */
-
-char *
-macho_call_template (rtx_insn *insn, rtx *operands, int dest_operand_number,
-		     int cookie_operand_number)
-{
-  static char buf[256];
-  if (darwin_emit_branch_islands
-      && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
-      && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
-    {
-      tree labelname;
-      tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
-
-      if (no_previous_def (funname))
-	{
-	  rtx label_rtx = gen_label_rtx ();
-	  char *label_buf, temp_buf[256];
-	  ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
-				       CODE_LABEL_NUMBER (label_rtx));
-	  label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
-	  labelname = get_identifier (label_buf);
-	  add_compiler_branch_island (labelname, funname, insn_line (insn));
-	}
-      else
-	labelname = get_prev_label (funname);
-
-      /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
-	 instruction will reach 'foo', otherwise link as 'bl L42'".
-	 "L42" should be a 'branch island', that will do a far jump to
-	 'foo'.  Branch islands are generated in
-	 macho_branch_islands().  */
-      sprintf (buf, "jbsr %%z%d,%.246s",
-	       dest_operand_number, IDENTIFIER_POINTER (labelname));
-    }
-  else
-    sprintf (buf, "bl %%z%d", dest_operand_number);
-  return buf;
-}
-
 /* Generate PIC and indirect symbol stubs.  */
 
 void
@@ -37932,13 +37916,13 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
   rtx call[3];
   rtx insn;
   rtx abi_reg = NULL_RTX;
+  int cookie_val = INTVAL (cookie);
 
   if (global_tlsarg)
     tlsarg = global_tlsarg;
 
   /* Handle longcall attributes.  */
-  if ((INTVAL (cookie) & CALL_LONG) != 0
-      && DEFAULT_ABI != ABI_DARWIN /* Darwin does it's own thing.  */
+  if ((cookie_val & CALL_LONG) != 0
       && GET_CODE (func_desc) == SYMBOL_REF)
     {
       func = rs6000_longcall_ref (func_desc, tlsarg);
@@ -37979,14 +37963,8 @@ rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
   if (value != NULL_RTX)
     call[0] = gen_rtx_SET (value, call[0]);
 
-  if (DEFAULT_ABI == ABI_DARWIN && TARGET_32BIT)
-    call[1] = gen_rtx_USE (VOIDmode, GEN_INT (INTVAL (cookie)));
-  else
-    {
-      unsigned int mask = CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS;
-      call[1] = gen_rtx_USE (VOIDmode, GEN_INT (INTVAL (cookie) & mask));
-    }
-
+  unsigned int mask = CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS;
+  call[1] = gen_rtx_USE (VOIDmode, GEN_INT (cookie_val & mask));
   call[2] = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO));
 
   insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call));
@@ -38060,6 +38038,113 @@ rs6000_sibcall_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
     use_reg (&CALL_INSN_FUNCTION_USAGE (insn), abi_reg);
 }
 
+#if TARGET_MACHO
+
+/* Expand code to perform a call under the Darwin ABI.
+   Modulo handling of mlongcall, this is much the same as sysv.
+   if/when the longcall optimisation is removed, we could drop this
+   code and use the sysv case (taking care to avoid the tls stuff).
+
+   We can use this for sibcalls too, if needed.  */
+
+void
+rs6000_call_darwin_1 (rtx value, rtx func_desc, rtx tlsarg,
+		      rtx cookie, bool sibcall)
+{
+  rtx func = func_desc;
+  rtx func_addr;
+  rtx call[3];
+  rtx insn;
+  int cookie_val = INTVAL (cookie);
+  bool make_island = false;
+
+  /* Handle longcall attributes, there are two cases for Darwin:
+     1) Newer linkers are capable of synthesising any branch islands needed.
+     2) We need a helper branch island synthesised by the compiler.
+     The second case has mostly been retired and we don't use it for m64.
+     In fact, it's is an optimisation, we could just indirect as sysv does..
+     ... however, backwards compatibility for now.
+     If we're going to use this, then we need to keep the CALL_LONG bit set,
+     so that we can pick up the special insn form later.  */
+  if ((cookie_val & CALL_LONG) != 0
+      && GET_CODE (func_desc) == SYMBOL_REF)
+    {
+      if (darwin_emit_branch_islands && TARGET_32BIT)
+	make_island = true; /* Do nothing yet, retain the CALL_LONG flag.  */
+      else
+	{
+	  /* The linker is capable of doing this, but the user explicitly
+	     asked for -mlongcall, so we'll do the 'normal' version.  */
+	  func = rs6000_longcall_ref (func_desc, NULL_RTX);
+	  cookie_val &= ~CALL_LONG; /* Handled, zap it.  */
+	}
+    }
+
+  /* Handle indirect calls.  */
+  if (GET_CODE (func) != SYMBOL_REF)
+    {
+      func = force_reg (Pmode, func);
+
+      /* Indirect calls via CTR are strongly preferred over indirect
+	 calls via LR, and are required for indirect sibcalls, so move
+	 the address there.   */
+      func_addr = gen_rtx_REG (Pmode, CTR_REGNO);
+      emit_move_insn (func_addr, func);
+    }
+  else
+    func_addr = func;
+
+  /* Create the call.  */
+  call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), tlsarg);
+  if (value != NULL_RTX)
+    call[0] = gen_rtx_SET (value, call[0]);
+
+  call[1] = gen_rtx_USE (VOIDmode, GEN_INT (cookie_val));
+
+  if (sibcall)
+    call[2] = simple_return_rtx;
+  else
+    call[2] = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO));
+
+  insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call));
+  insn = emit_call_insn (insn);
+  /* Now we have the debug info in the insn, we can set up the branch island
+     if we're using one.  */
+  if (make_island)
+    {
+      tree funname = get_identifier (XSTR (func_desc, 0));
+
+      if (no_previous_def (funname))
+	{
+	  rtx label_rtx = gen_label_rtx ();
+	  char *label_buf, temp_buf[256];
+	  ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
+				       CODE_LABEL_NUMBER (label_rtx));
+	  label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
+	  tree labelname = get_identifier (label_buf);
+	  add_compiler_branch_island (labelname, funname,
+				     insn_line ((const rtx_insn*)insn));
+	}
+     }
+}
+
+void
+rs6000_call_darwin (rtx value, rtx func_desc,
+		    rtx tlsarg ATTRIBUTE_UNUSED, rtx cookie)
+{
+  rs6000_call_darwin_1 (value, func_desc, tlsarg, cookie, false);
+}
+
+
+void
+rs6000_sibcall_darwin (rtx value, rtx func_desc,
+		       rtx tlsarg ATTRIBUTE_UNUSED, rtx cookie)
+{
+  rs6000_call_darwin_1 (value, func_desc, tlsarg, cookie, true);
+}
+
+#endif
+
 /* Return whether we need to always update the saved TOC pointer when we update
    the stack pointer.  */
 
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index d684bed3ae..e4a71439ef 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -10289,12 +10289,20 @@
       DONE;
     }
 
-  if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN)
+  if (DEFAULT_ABI == ABI_V4)
     {
       rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
       DONE;
     }
 
+#if TARGET_MACHO
+  if (DEFAULT_ABI == ABI_DARWIN)
+    {
+      rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
+      DONE;
+    }
+#endif
+
   if (GET_CODE (operands[0]) != SYMBOL_REF)
     operands[0] = force_reg (Pmode, operands[0]);
 })
@@ -10322,12 +10330,20 @@
       DONE;
     }
 
-  if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN)
+  if (DEFAULT_ABI == ABI_V4)
     {
       rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
       DONE;
     }
 
+#if TARGET_MACHO
+  if (DEFAULT_ABI == ABI_DARWIN)
+    {
+      rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
+      DONE;
+    }
+#endif
+
   if (GET_CODE (operands[1]) != SYMBOL_REF)
     operands[1] = force_reg (Pmode, operands[1]);
 })
@@ -10463,11 +10479,7 @@
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn ("creqv 6,6,6", operands);
 
-#if TARGET_MACHO
-  return macho_call_template (insn, operands, 0, 2);
-#else
   return rs6000_call_template (operands, 0);
-#endif
 }
   "DEFAULT_ABI == ABI_V4
    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
@@ -10549,11 +10561,7 @@
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn ("creqv 6,6,6", operands);
 
-#if TARGET_MACHO
-  return macho_call_template (insn, operands, 1, 3);
-#else
   return rs6000_call_template (operands, 1);
-#endif
 }
   "DEFAULT_ABI == ABI_V4
    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
@@ -10771,6 +10779,14 @@
       rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
       DONE;
     }
+
+#if TARGET_MACHO
+  if (DEFAULT_ABI == ABI_DARWIN)
+    {
+      rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
+      DONE;
+    }
+#endif
 })
 
 (define_expand "sibcall_value"
@@ -10797,11 +10813,20 @@
       DONE;
     }
 
-  if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN)
+  if (DEFAULT_ABI == ABI_V4)
     {
       rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
       DONE;
     }
+
+#if TARGET_MACHO
+  if (DEFAULT_ABI == ABI_DARWIN)
+    {
+      rs6000_sibcall_darwin (operands[0], operands[1],
+			     operands[2], operands[3]);
+      DONE;
+    }
+#endif
 })
 
 (define_insn "*sibcall_local32"
-- 
2.17.1



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]