[RS6000] rs6000_call_template for external call insn assembly output
authorAlan Modra <amodra@gmail.com>
Thu, 29 Nov 2018 04:41:06 +0000 (15:11 +1030)
committerAlan Modra <amodra@gcc.gnu.org>
Thu, 29 Nov 2018 04:41:06 +0000 (15:11 +1030)
This is a first step in tidying rs6000 call patterns, in preparation
to support inline plt calls.

* config/rs6000/rs6000-protos.h (rs6000_call_template): Declare.
(rs6000_sibcall_template): Declare.
(macho_call_template): Rename from output_call.
* config/rs6000/rs6000.c (rs6000_call_template_1): New function.
(rs6000_call_template, rs6000_sibcall_template): Likewise.
(macho_call_template): Rename from output_call.
* config/rs6000/rs6000.md (tls_gd_aix, tls_gd_sysv),
(tls_gd_call_aix, tls_gd_call_sysv, tls_ld_aix, tls_ld_sysv),
(tls_ld_call_aix, tls_ld_call_sysv, call_nonlocal_sysv),
(call_nonlocal_sysv_secure, call_value_nonlocal_sysv),
(call_value_nonlocal_sysv_secure, call_nonlocal_aix),
(call_value_nonlocal_aix): Use rs6000_call_template and update
occurrences of output_call to macho_call_template.
(sibcall_nonlocal_sysv, sibcall_value_nonlocal_sysv, sibcall_aix),
(sibcall_value_aix): Use rs6000_sibcall_template.

From-SVN: r266600

gcc/ChangeLog
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md

index 98f4f3fe3a8599f8f66bb0d539d8b85b923ef85d..0186a40e45b6dc56e268e89a0a1862602a50b823 100644 (file)
@@ -1,3 +1,21 @@
+2018-11-29  Alan Modra  <amodra@gmail.com>
+
+       * config/rs6000/rs6000-protos.h (rs6000_call_template): Declare.
+       (rs6000_sibcall_template): Declare.
+       (macho_call_template): Rename from output_call.
+       * config/rs6000/rs6000.c (rs6000_call_template_1): New function.
+       (rs6000_call_template, rs6000_sibcall_template): Likewise.
+       (macho_call_template): Rename from output_call.
+       * config/rs6000/rs6000.md (tls_gd_aix, tls_gd_sysv),
+       (tls_gd_call_aix, tls_gd_call_sysv, tls_ld_aix, tls_ld_sysv),
+       (tls_ld_call_aix, tls_ld_call_sysv, call_nonlocal_sysv),
+       (call_nonlocal_sysv_secure, call_value_nonlocal_sysv),
+       (call_value_nonlocal_sysv_secure, call_nonlocal_aix),
+       (call_value_nonlocal_aix): Use rs6000_call_template and update
+       occurrences of output_call to macho_call_template.
+       (sibcall_nonlocal_sysv, sibcall_value_nonlocal_sysv, sibcall_aix),
+       (sibcall_value_aix): Use rs6000_sibcall_template.
+
 2018-11-28  Aaron Sawdey  <acsawdey@linux.ibm.com>
 
        * config/rs6000/rs6000-string.c (expand_block_clear): Change how
index 6e58ce78d08d4b91edfd5b9ee570d586becf0f30..bdb2a595a4f4185ed561993d344f82e8c9caf26b 100644 (file)
@@ -105,6 +105,8 @@ extern int ccr_bit (rtx, int);
 extern void rs6000_output_function_entry (FILE *, const char *);
 extern void print_operand (FILE *, rtx, int);
 extern void print_operand_address (FILE *, rtx);
+extern const char *rs6000_call_template (rtx *, unsigned int, const char *);
+extern const char *rs6000_sibcall_template (rtx *, unsigned int, const char *);
 extern enum rtx_code rs6000_reverse_condition (machine_mode,
                                               enum rtx_code);
 extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx);
@@ -222,7 +224,7 @@ extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT,
 extern void rs6000_d_target_versions (void);
 
 #if TARGET_MACHO
-char *output_call (rtx_insn *, rtx *, int, int);
+char *macho_call_template (rtx_insn *, rtx *, int, int);
 #endif
 
 #ifdef NO_DOLLAR_IN_LABEL
index 965488caabfe5057353da222e7802e1092be4d00..7c7117c5d1e9f8fdaefb58ef51c14123eecdf7d5 100644 (file)
@@ -21367,6 +21367,50 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
   return default_assemble_integer (x, size, aligned_p);
 }
 
+/* Return a template string for assembly to emit when making an
+   external call.  FUNOP is the call mem argument operand number,
+   ARG is either NULL or a @TLSGD or @TLSLD __tls_get_addr argument
+   specifier.  */
+
+static const char *
+rs6000_call_template_1 (rtx *operands ATTRIBUTE_UNUSED, unsigned int funop,
+                       bool sibcall, const char *arg)
+{
+  /* -Wformat-overflow workaround, without which gcc thinks that %u
+      might produce 10 digits.  */
+  gcc_assert (funop <= MAX_RECOG_OPERANDS);
+
+  /* The magic 32768 offset here corresponds to the offset of
+     r30 in .got2, as given by LCTOC1.  See sysv4.h:toc_section.  */
+  char z[11];
+  sprintf (z, "%%z%u%s", funop,
+          (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic == 2
+           ? "+32768" : ""));
+
+  static char str[32];  /* 4 spare */
+  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" : "");
+  else
+    gcc_unreachable ();
+  return str;
+}
+
+const char *
+rs6000_call_template (rtx *operands, unsigned int funop, const char *arg)
+{
+  return rs6000_call_template_1 (operands, funop, false, arg);
+}
+
+const char *
+rs6000_sibcall_template (rtx *operands, unsigned int funop, const char *arg)
+{
+  return rs6000_call_template_1 (operands, funop, true, arg);
+}
+
 #if defined (HAVE_GAS_HIDDEN) && !TARGET_MACHO
 /* Emit an assembler directive to set symbol visibility for DECL to
    VISIBILITY_TYPE.  */
@@ -32805,8 +32849,8 @@ get_prev_label (tree function_name)
    CALL_DEST is the routine we are calling.  */
 
 char *
-output_call (rtx_insn *insn, rtx *operands, int dest_operand_number,
-            int cookie_operand_number)
+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
index f2b10afe35b5b292fbf9e210474298758b01c9b3..fd0ae58607049838820fcfe8732e601357a32a07 100644 (file)
   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
 {
   if (TARGET_CMODEL != CMODEL_SMALL)
-    return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
-          "bl %z3\;nop";
+    output_asm_insn ("addis %0,%1,%2@got@tlsgd@ha\;"
+                    "addi %0,%0,%2@got@tlsgd@l", operands);
   else
-    return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
+    output_asm_insn ("addi %0,%1,%2@got@tlsgd", operands);
+  return rs6000_call_template (operands, 3, "");
 }
   "&& TARGET_TLS_MARKERS"
   [(set (match_dup 0)
    (clobber (reg:SI LR_REGNO))]
   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
 {
-  if (flag_pic)
-    {
-      if (TARGET_SECURE_PLT && flag_pic == 2)
-       return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
-      else
-       return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
-    }
-  else
-    return "addi %0,%1,%2@got@tlsgd\;bl %z3";
+  output_asm_insn ("addi %0,%1,%2@got@tlsgd", operands);
+  return rs6000_call_template (operands, 3, "");
 }
   "&& TARGET_TLS_MARKERS"
   [(set (match_dup 0)
    (clobber (reg:SI LR_REGNO))]
   "HAVE_AS_TLS && TARGET_TLS_MARKERS
    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
-  "bl %z1(%3@tlsgd)\;nop"
+{
+  return rs6000_call_template (operands, 1, "(%3@tlsgd)");
+}
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 
    (clobber (reg:SI LR_REGNO))]
   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
 {
-  if (flag_pic)
-    {
-      if (TARGET_SECURE_PLT && flag_pic == 2)
-       return "bl %z1+32768(%3@tlsgd)@plt";
-      return "bl %z1(%3@tlsgd)@plt";
-    }
-  return "bl %z1(%3@tlsgd)";
+  return rs6000_call_template (operands, 1, "(%3@tlsgd)");
 }
   [(set_attr "type" "branch")])
 
   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
 {
   if (TARGET_CMODEL != CMODEL_SMALL)
-    return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
-          "bl %z2\;nop";
+    output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\;"
+                    "addi %0,%0,%&@got@tlsld@l", operands);
   else
-    return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
+    output_asm_insn ("addi %0,%1,%&@got@tlsld", operands);
+  return rs6000_call_template (operands, 2, "");
 }
   "&& TARGET_TLS_MARKERS"
   [(set (match_dup 0)
    (clobber (reg:SI LR_REGNO))]
   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
 {
-  if (flag_pic)
-    {
-      if (TARGET_SECURE_PLT && flag_pic == 2)
-       return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
-      else
-       return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
-    }
-  else
-    return "addi %0,%1,%&@got@tlsld\;bl %z2";
+  output_asm_insn ("addi %0,%1,%&@got@tlsld", operands);
+  return rs6000_call_template (operands, 2, "");
 }
   "&& TARGET_TLS_MARKERS"
   [(set (match_dup 0)
    (clobber (reg:SI LR_REGNO))]
   "HAVE_AS_TLS && TARGET_TLS_MARKERS
    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
-  "bl %z1(%&@tlsld)\;nop"
+{
+  return rs6000_call_template (operands, 1, "(%&@tlsld)");
+}
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 
    (clobber (reg:SI LR_REGNO))]
   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
 {
-  if (flag_pic)
-    {
-      if (TARGET_SECURE_PLT && flag_pic == 2)
-       return "bl %z1+32768(%&@tlsld)@plt";
-      return "bl %z1(%&@tlsld)@plt";
-    }
-  return "bl %z1(%&@tlsld)";
+  return rs6000_call_template (operands, 1, "(%&@tlsld)");
 }
   [(set_attr "type" "branch")])
 
     output_asm_insn ("creqv 6,6,6", operands);
 
 #if TARGET_MACHO
-  return output_call(insn, operands, 0, 2);
+  return macho_call_template (insn, operands, 0, 2);
 #else
-  if (DEFAULT_ABI == ABI_V4 && flag_pic)
-    {
-      gcc_assert (!TARGET_SECURE_PLT);
-      return "bl %z0@plt";
-    }
-  else
-    return "bl %z0";
+  return rs6000_call_template (operands, 0, "");
 #endif
 }
   "DEFAULT_ABI == ABI_V4
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn ("creqv 6,6,6", operands);
 
-  if (flag_pic == 2)
-    /* The magic 32768 offset here and in the other sysv call insns
-       corresponds to the offset of r30 in .got2, as given by LCTOC1.
-       See sysv4.h:toc_section.  */
-    return "bl %z0+32768@plt";
-  else
-    return "bl %z0@plt";
+  return rs6000_call_template (operands, 0, "");
 }
   [(set_attr "type" "branch,branch")
    (set_attr "length" "4,8")])
     output_asm_insn ("creqv 6,6,6", operands);
 
 #if TARGET_MACHO
-  return output_call(insn, operands, 1, 3);
+  return macho_call_template (insn, operands, 1, 3);
 #else
-  if (DEFAULT_ABI == ABI_V4 && flag_pic)
-    {
-      gcc_assert (!TARGET_SECURE_PLT);
-      return "bl %z1@plt";
-    }
-  else
-    return "bl %z1";
+  return rs6000_call_template (operands, 1, "");
 #endif
 }
   "DEFAULT_ABI == ABI_V4
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn ("creqv 6,6,6", operands);
 
-  if (flag_pic == 2)
-    return "bl %z1+32768@plt";
-  else
-    return "bl %z1@plt";
+  return rs6000_call_template (operands, 1, "");
 }
   [(set_attr "type" "branch,branch")
    (set_attr "length" "4,8")])
         (match_operand 1 "" "g"))
    (clobber (reg:P LR_REGNO))]
   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
-  "bl %z0\;nop"
+{
+  return rs6000_call_template (operands, 0, "");
+}
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 
              (match_operand 2 "" "g")))
    (clobber (reg:P LR_REGNO))]
   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
-  "bl %z1\;nop"
+{
+  return rs6000_call_template (operands, 1, "");
+}
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 
        /* Can use CR0 since it is volatile across sibcalls.  */
        return "crset 2\;beq%T0-\;b $";
     }
-  else if (DEFAULT_ABI == ABI_V4 && flag_pic)
-    {
-      gcc_assert (!TARGET_SECURE_PLT);
-      return "b %z0@plt";
-    }
   else
-    return "b %z0";
+    return rs6000_sibcall_template (operands, 0, "");
 }
   [(set_attr "type" "branch")
    (set_attr_alternative "length"
        /* Can use CR0 since it is volatile across sibcalls.  */
        return "crset 2\;beq%T1-\;b $";
     }
-  else if (DEFAULT_ABI == ABI_V4 && flag_pic)
-    {
-      gcc_assert (!TARGET_SECURE_PLT);
-      return "b %z1@plt";
-    }
   else
-    return "b %z1";
+    return rs6000_sibcall_template (operands, 1, "");
 }
   [(set_attr "type" "branch")
    (set_attr_alternative "length"
         (match_operand 1 "" "g,g"))
    (simple_return)]
   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
-  "@
-   b %z0
-   b%T0"
+{
+  if (which_alternative == 0)
+    return rs6000_sibcall_template (operands, 0, "");
+  else
+    return "b%T0";
+}
   [(set_attr "type" "branch")])
 
 (define_insn "*sibcall_value_aix<mode>"
              (match_operand 2 "" "g,g")))
    (simple_return)]
   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
-  "@
-   b %z1
-   b%T1"
+{
+  if (which_alternative == 0)
+    return rs6000_sibcall_template (operands, 1, "");
+  else
+    return "b%T1";
+}
   [(set_attr "type" "branch")])
 
 (define_expand "sibcall_epilogue"