From: Alan Modra Date: Thu, 29 Nov 2018 04:41:06 +0000 (+1030) Subject: [RS6000] rs6000_call_template for external call insn assembly output X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=75a0b80599ca4326da8a203e042cb9db6c27ab08;p=gcc.git [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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 98f4f3fe3a8..0186a40e45b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2018-11-29 Alan Modra + + * 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 * config/rs6000/rs6000-string.c (expand_block_clear): Change how diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 6e58ce78d08..bdb2a595a4f 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -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 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 965488caabf..7c7117c5d1e 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index f2b10afe35b..fd0ae586070 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -9439,10 +9439,11 @@ "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) @@ -9471,15 +9472,8 @@ (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) @@ -9544,7 +9538,9 @@ (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")]) @@ -9557,13 +9553,7 @@ (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")]) @@ -9577,10 +9567,11 @@ "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) @@ -9607,15 +9598,8 @@ (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) @@ -9676,7 +9660,9 @@ (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")]) @@ -9688,13 +9674,7 @@ (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")]) @@ -10580,15 +10560,9 @@ 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 @@ -10621,13 +10595,7 @@ 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")]) @@ -10683,15 +10651,9 @@ 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 @@ -10726,10 +10688,7 @@ 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")]) @@ -10762,7 +10721,9 @@ (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")]) @@ -10772,7 +10733,9 @@ (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")]) @@ -11049,13 +11012,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" @@ -11094,13 +11052,8 @@ /* 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" @@ -11122,9 +11075,12 @@ (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" @@ -11133,9 +11089,12 @@ (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"