summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000-protos.h
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-11-29 15:17:51 +1030
committerAlan Modra <amodra@gcc.gnu.org>2018-11-29 15:17:51 +1030
commitece3bca2bd08bd02028f9ac6b0a2b6b8fa111305 (patch)
tree04fa524ca73637833e033031b264e7c37c53c227 /gcc/config/rs6000/rs6000-protos.h
parent7a24893b2eb79af5785a7334126a82618a549c1e (diff)
downloadgcc-ece3bca2bd08bd02028f9ac6b0a2b6b8fa111305.tar.gz
[RS6000] Use standard call patterns for __tls_get_addr calls
The current code handling __tls_get_addr calls for powerpc*-linux generates a call then overwrites the call insn with a special tls_{gd,ld}_{aix,sysv} pattern. It's done that way to support !TARGET_TLS_MARKERS, where the arg setup insns need to be emitted immediately before the branch and link. When TARGET_TLS_MARKERS, the arg setup insns are split from the actual call, but we then have a non-standard call pattern that needs to be carried through to output. This patch changes that scheme, to instead use the standard call patterns for __tls_get_addr calls, except for the now rare !TARGET_TLS_MARKERS case. Doing it this way should be better for maintenance as the !TARGET_TLS_MARKERS code can eventually disappear. It also makes it possible to support longcalls (and in following patches, inline plt calls) for __tls_get_addr without introducing yet more special call patterns. __tls_get_addr calls do however need to be different to standard calls, because when TARGET_TLS_MARKERS the calls are decorated with an argument specifier, eg. "bl __tls_get_addr(thread_var@tlsgd)" that causes a reloc to be emitted by the assembler tying the call to its arg setup insns. I chose to smuggle the arg in the currently unused stack size rtl. I've also introduced rs6000_call_sysv to generate rtl for sysv calls, as rs6000_call_aix does for aix and elfv2 calls. This allows rs6000_longcall_ref to be local to rs6000.c since the calls in the expanders never did anything for darwin. * config/rs6000/predicates.md (unspec_tls): New. * config/rs6000/rs6000-protos.h (rs6000_call_template), (rs6000_sibcall_template): Update prototype. (rs6000_longcall_ref): Delete. (rs6000_call_sysv): Declare. * config/rs6000/rs6000.c (edit_tls_call_insn): New function. (global_tlsarg): New variable. (rs6000_legitimize_tls_address): Rewrite __tls_get_addr call handling. (print_operand): Extract UNSPEC_TLSGD address operand. (rs6000_call_template, rs6000_sibcall_template): Remove arg parameter, extract from second call operand instead. (rs6000_longcall_ref): Make static, localize vars. (rs6000_call_aix): Rename parameter to reflect new usage. Take tlsarg from global_tlsarg. Don't create unused rtl or nop insns. (rs6000_sibcall_aix): Rename parameter to reflect new usage. Take tlsarg from global_tlsarg. (rs6000_call_sysv): New function. * config/rs6000/rs6000.md: Adjust rs6000_call_template and rs6000_sibcall_template throughout. (tls_gd_aix, tls_gd_sysv, tls_gd_call_aix, tls_gd_call_sysv): Delete. (tls_ld_aix, tls_ld_sysv, tls_ld_call_aix, tls_ld_call_sysv): Delete. (tls_gdld_nomark): New insn. (tls_gd): Swap operand order. Simplify mode selection. (tls_gd_high, tls_gd_low): Swap operand order. (tls_ld): Remove const_int 0 vector element from UNSPEC_TLSLD. Simplify mode selection. (tls_ld_high, tls_ld_low): Similarly adjust UNSPEC_TLSLD. (call, call_value): Don't assert for second call operand. Use rs6000_call_sysv. From-SVN: r266604
Diffstat (limited to 'gcc/config/rs6000/rs6000-protos.h')
-rw-r--r--gcc/config/rs6000/rs6000-protos.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index f1a294a3617..dd930bb2da6 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -105,8 +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 const char *rs6000_call_template (rtx *, unsigned int);
+extern const char *rs6000_sibcall_template (rtx *, unsigned int);
extern const char *rs6000_indirect_call_template (rtx *, unsigned int);
extern const char *rs6000_indirect_sibcall_template (rtx *, unsigned int);
extern enum rtx_code rs6000_reverse_condition (machine_mode,
@@ -130,7 +130,6 @@ extern void rs6000_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
extern void rs6000_emit_swdiv (rtx, rtx, rtx, bool);
extern void rs6000_emit_swsqrt (rtx, rtx, bool);
extern void output_toc (FILE *, rtx, int, machine_mode);
-extern rtx rs6000_longcall_ref (rtx);
extern void rs6000_fatal_bad_address (rtx);
extern rtx create_TOC_reference (rtx, rtx);
extern void rs6000_split_multireg_move (rtx, rtx);
@@ -198,6 +197,7 @@ extern void rs6000_split_stack_space_check (rtx, rtx);
extern void rs6000_emit_eh_reg_restore (rtx, rtx);
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_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);