Commit 75a0b805 by Alan Modra Committed by Alan Modra

[RS6000] rs6000_call_template for external call insn assembly output

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
parent 645eee74
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> 2018-11-28 Aaron Sawdey <acsawdey@linux.ibm.com>
* config/rs6000/rs6000-string.c (expand_block_clear): Change how * config/rs6000/rs6000-string.c (expand_block_clear): Change how
...@@ -105,6 +105,8 @@ extern int ccr_bit (rtx, int); ...@@ -105,6 +105,8 @@ extern int ccr_bit (rtx, int);
extern void rs6000_output_function_entry (FILE *, const char *); extern void rs6000_output_function_entry (FILE *, const char *);
extern void print_operand (FILE *, rtx, int); extern void print_operand (FILE *, rtx, int);
extern void print_operand_address (FILE *, rtx); 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, extern enum rtx_code rs6000_reverse_condition (machine_mode,
enum rtx_code); enum rtx_code);
extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx); 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, ...@@ -222,7 +224,7 @@ extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT,
extern void rs6000_d_target_versions (void); extern void rs6000_d_target_versions (void);
#if TARGET_MACHO #if TARGET_MACHO
char *output_call (rtx_insn *, rtx *, int, int); char *macho_call_template (rtx_insn *, rtx *, int, int);
#endif #endif
#ifdef NO_DOLLAR_IN_LABEL #ifdef NO_DOLLAR_IN_LABEL
......
...@@ -21367,6 +21367,50 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p) ...@@ -21367,6 +21367,50 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
return default_assemble_integer (x, size, 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 #if defined (HAVE_GAS_HIDDEN) && !TARGET_MACHO
/* Emit an assembler directive to set symbol visibility for DECL to /* Emit an assembler directive to set symbol visibility for DECL to
VISIBILITY_TYPE. */ VISIBILITY_TYPE. */
...@@ -32805,8 +32849,8 @@ get_prev_label (tree function_name) ...@@ -32805,8 +32849,8 @@ get_prev_label (tree function_name)
CALL_DEST is the routine we are calling. */ CALL_DEST is the routine we are calling. */
char * char *
output_call (rtx_insn *insn, rtx *operands, int dest_operand_number, macho_call_template (rtx_insn *insn, rtx *operands, int dest_operand_number,
int cookie_operand_number) int cookie_operand_number)
{ {
static char buf[256]; static char buf[256];
if (darwin_emit_branch_islands if (darwin_emit_branch_islands
...@@ -9439,10 +9439,11 @@ ...@@ -9439,10 +9439,11 @@
"HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
{ {
if (TARGET_CMODEL != CMODEL_SMALL) if (TARGET_CMODEL != CMODEL_SMALL)
return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;" output_asm_insn ("addis %0,%1,%2@got@tlsgd@ha\;"
"bl %z3\;nop"; "addi %0,%0,%2@got@tlsgd@l", operands);
else 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" "&& TARGET_TLS_MARKERS"
[(set (match_dup 0) [(set (match_dup 0)
...@@ -9471,15 +9472,8 @@ ...@@ -9471,15 +9472,8 @@
(clobber (reg:SI LR_REGNO))] (clobber (reg:SI LR_REGNO))]
"HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
{ {
if (flag_pic) output_asm_insn ("addi %0,%1,%2@got@tlsgd", operands);
{ return rs6000_call_template (operands, 3, "");
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";
} }
"&& TARGET_TLS_MARKERS" "&& TARGET_TLS_MARKERS"
[(set (match_dup 0) [(set (match_dup 0)
...@@ -9544,7 +9538,9 @@ ...@@ -9544,7 +9538,9 @@
(clobber (reg:SI LR_REGNO))] (clobber (reg:SI LR_REGNO))]
"HAVE_AS_TLS && TARGET_TLS_MARKERS "HAVE_AS_TLS && TARGET_TLS_MARKERS
&& (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" && (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 "type" "branch")
(set_attr "length" "8")]) (set_attr "length" "8")])
...@@ -9557,13 +9553,7 @@ ...@@ -9557,13 +9553,7 @@
(clobber (reg:SI LR_REGNO))] (clobber (reg:SI LR_REGNO))]
"HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
{ {
if (flag_pic) return rs6000_call_template (operands, 1, "(%3@tlsgd)");
{
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)";
} }
[(set_attr "type" "branch")]) [(set_attr "type" "branch")])
...@@ -9577,10 +9567,11 @@ ...@@ -9577,10 +9567,11 @@
"HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
{ {
if (TARGET_CMODEL != CMODEL_SMALL) if (TARGET_CMODEL != CMODEL_SMALL)
return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;" output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\;"
"bl %z2\;nop"; "addi %0,%0,%&@got@tlsld@l", operands);
else 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" "&& TARGET_TLS_MARKERS"
[(set (match_dup 0) [(set (match_dup 0)
...@@ -9607,15 +9598,8 @@ ...@@ -9607,15 +9598,8 @@
(clobber (reg:SI LR_REGNO))] (clobber (reg:SI LR_REGNO))]
"HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
{ {
if (flag_pic) output_asm_insn ("addi %0,%1,%&@got@tlsld", operands);
{ return rs6000_call_template (operands, 2, "");
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";
} }
"&& TARGET_TLS_MARKERS" "&& TARGET_TLS_MARKERS"
[(set (match_dup 0) [(set (match_dup 0)
...@@ -9676,7 +9660,9 @@ ...@@ -9676,7 +9660,9 @@
(clobber (reg:SI LR_REGNO))] (clobber (reg:SI LR_REGNO))]
"HAVE_AS_TLS && TARGET_TLS_MARKERS "HAVE_AS_TLS && TARGET_TLS_MARKERS
&& (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" && (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 "type" "branch")
(set_attr "length" "8")]) (set_attr "length" "8")])
...@@ -9688,13 +9674,7 @@ ...@@ -9688,13 +9674,7 @@
(clobber (reg:SI LR_REGNO))] (clobber (reg:SI LR_REGNO))]
"HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
{ {
if (flag_pic) return rs6000_call_template (operands, 1, "(%&@tlsld)");
{
if (TARGET_SECURE_PLT && flag_pic == 2)
return "bl %z1+32768(%&@tlsld)@plt";
return "bl %z1(%&@tlsld)@plt";
}
return "bl %z1(%&@tlsld)";
} }
[(set_attr "type" "branch")]) [(set_attr "type" "branch")])
...@@ -10580,15 +10560,9 @@ ...@@ -10580,15 +10560,9 @@
output_asm_insn ("creqv 6,6,6", operands); output_asm_insn ("creqv 6,6,6", operands);
#if TARGET_MACHO #if TARGET_MACHO
return output_call(insn, operands, 0, 2); return macho_call_template (insn, operands, 0, 2);
#else #else
if (DEFAULT_ABI == ABI_V4 && flag_pic) return rs6000_call_template (operands, 0, "");
{
gcc_assert (!TARGET_SECURE_PLT);
return "bl %z0@plt";
}
else
return "bl %z0";
#endif #endif
} }
"DEFAULT_ABI == ABI_V4 "DEFAULT_ABI == ABI_V4
...@@ -10621,13 +10595,7 @@ ...@@ -10621,13 +10595,7 @@
else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn ("creqv 6,6,6", operands); output_asm_insn ("creqv 6,6,6", operands);
if (flag_pic == 2) return rs6000_call_template (operands, 0, "");
/* 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";
} }
[(set_attr "type" "branch,branch") [(set_attr "type" "branch,branch")
(set_attr "length" "4,8")]) (set_attr "length" "4,8")])
...@@ -10683,15 +10651,9 @@ ...@@ -10683,15 +10651,9 @@
output_asm_insn ("creqv 6,6,6", operands); output_asm_insn ("creqv 6,6,6", operands);
#if TARGET_MACHO #if TARGET_MACHO
return output_call(insn, operands, 1, 3); return macho_call_template (insn, operands, 1, 3);
#else #else
if (DEFAULT_ABI == ABI_V4 && flag_pic) return rs6000_call_template (operands, 1, "");
{
gcc_assert (!TARGET_SECURE_PLT);
return "bl %z1@plt";
}
else
return "bl %z1";
#endif #endif
} }
"DEFAULT_ABI == ABI_V4 "DEFAULT_ABI == ABI_V4
...@@ -10726,10 +10688,7 @@ ...@@ -10726,10 +10688,7 @@
else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn ("creqv 6,6,6", operands); output_asm_insn ("creqv 6,6,6", operands);
if (flag_pic == 2) return rs6000_call_template (operands, 1, "");
return "bl %z1+32768@plt";
else
return "bl %z1@plt";
} }
[(set_attr "type" "branch,branch") [(set_attr "type" "branch,branch")
(set_attr "length" "4,8")]) (set_attr "length" "4,8")])
...@@ -10762,7 +10721,9 @@ ...@@ -10762,7 +10721,9 @@
(match_operand 1 "" "g")) (match_operand 1 "" "g"))
(clobber (reg:P LR_REGNO))] (clobber (reg:P LR_REGNO))]
"DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
"bl %z0\;nop" {
return rs6000_call_template (operands, 0, "");
}
[(set_attr "type" "branch") [(set_attr "type" "branch")
(set_attr "length" "8")]) (set_attr "length" "8")])
...@@ -10772,7 +10733,9 @@ ...@@ -10772,7 +10733,9 @@
(match_operand 2 "" "g"))) (match_operand 2 "" "g")))
(clobber (reg:P LR_REGNO))] (clobber (reg:P LR_REGNO))]
"DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
"bl %z1\;nop" {
return rs6000_call_template (operands, 1, "");
}
[(set_attr "type" "branch") [(set_attr "type" "branch")
(set_attr "length" "8")]) (set_attr "length" "8")])
...@@ -11049,13 +11012,8 @@ ...@@ -11049,13 +11012,8 @@
/* Can use CR0 since it is volatile across sibcalls. */ /* Can use CR0 since it is volatile across sibcalls. */
return "crset 2\;beq%T0-\;b $"; return "crset 2\;beq%T0-\;b $";
} }
else if (DEFAULT_ABI == ABI_V4 && flag_pic)
{
gcc_assert (!TARGET_SECURE_PLT);
return "b %z0@plt";
}
else else
return "b %z0"; return rs6000_sibcall_template (operands, 0, "");
} }
[(set_attr "type" "branch") [(set_attr "type" "branch")
(set_attr_alternative "length" (set_attr_alternative "length"
...@@ -11094,13 +11052,8 @@ ...@@ -11094,13 +11052,8 @@
/* Can use CR0 since it is volatile across sibcalls. */ /* Can use CR0 since it is volatile across sibcalls. */
return "crset 2\;beq%T1-\;b $"; return "crset 2\;beq%T1-\;b $";
} }
else if (DEFAULT_ABI == ABI_V4 && flag_pic)
{
gcc_assert (!TARGET_SECURE_PLT);
return "b %z1@plt";
}
else else
return "b %z1"; return rs6000_sibcall_template (operands, 1, "");
} }
[(set_attr "type" "branch") [(set_attr "type" "branch")
(set_attr_alternative "length" (set_attr_alternative "length"
...@@ -11122,9 +11075,12 @@ ...@@ -11122,9 +11075,12 @@
(match_operand 1 "" "g,g")) (match_operand 1 "" "g,g"))
(simple_return)] (simple_return)]
"DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
"@ {
b %z0 if (which_alternative == 0)
b%T0" return rs6000_sibcall_template (operands, 0, "");
else
return "b%T0";
}
[(set_attr "type" "branch")]) [(set_attr "type" "branch")])
(define_insn "*sibcall_value_aix<mode>" (define_insn "*sibcall_value_aix<mode>"
...@@ -11133,9 +11089,12 @@ ...@@ -11133,9 +11089,12 @@
(match_operand 2 "" "g,g"))) (match_operand 2 "" "g,g")))
(simple_return)] (simple_return)]
"DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
"@ {
b %z1 if (which_alternative == 0)
b%T1" return rs6000_sibcall_template (operands, 1, "");
else
return "b%T1";
}
[(set_attr "type" "branch")]) [(set_attr "type" "branch")])
(define_expand "sibcall_epilogue" (define_expand "sibcall_epilogue"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment