Hi! On Tue, Nov 13, 2018 at 11:22:43PM +1030, Alan Modra wrote: > Version 2. > > 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_aix, tls_gdld_sysv): New insns, replacing above. > (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.
> +/* Passes the tls arg value for global dynamic and local dynamic > + emit_library_call_value in rs6000_legitimize_Tls_address to > + rs6000_call_aix and rs6000_call_sysv. This is used to emit the > + marker relocs put on __tls_get_addr calls. */ > +static rtx global_tlsarg; Typo (s/_Tls/_tls/). > +(define_insn "*tls_gdld_aix<P:bits>" > + [(match_parallel 3 "" A match_parallel without predicate... Does this work?! Does this not accidentally pick up the wrong things? Do you think we should to deprecate -mtls-markers in GCC 9? Please test with -mtls-markers, too, if you can, and test on AIX. Looks fine. Thank you for the cleanup! Okay for trunk, but please do the extra testing. Segher