From patchwork Tue Nov 13 12:52:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 997086 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-489880-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="szZwlWKL"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="nkgWjFMR"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42vSGT1Flpz9rxp for ; Tue, 13 Nov 2018 23:53:04 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=VyItNracA2kuUrDPi DZn0CjurbkOQgeOsyf1AB7cDy83QPlNlz7jZKJQej1P+9AVUtGjt5QsFITT2KAaI KFK4SMR14T20MvdGrd6olNyUmmMahzYMGY1xiBpQDIitB2q5skqLpOSvoDoh5854 1ORgODm39nY4KH3MLDT+AZr9j8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=bIUagoDU2VjlL/AESMRIZ2I snQk=; b=szZwlWKLyGoEaqaTt/U8JpRyDngJt9AbPs4f3ia/Md/MjAn02X1v6if SILMMmTIMpuwONOoRM4PcpsMciwFUUK18iqlR2PEnJmQPVV6L5PkzAyrBDaL0a7N 73pU8zchD/hl19SvtlYQYsaueppH4Sbrxf+/QIsXUBNTkhTXnRKg= Received: (qmail 73599 invoked by alias); 13 Nov 2018 12:52:56 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 73589 invoked by uid 89); 13 Nov 2018 12:52:55 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-pf1-f174.google.com Received: from mail-pf1-f174.google.com (HELO mail-pf1-f174.google.com) (209.85.210.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Nov 2018 12:52:50 +0000 Received: by mail-pf1-f174.google.com with SMTP id c72so1328871pfc.6 for ; Tue, 13 Nov 2018 04:52:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=O9+nz/LNmBAPDXG/StwcqtZqiKPKTbQd+gKtkpjkt78=; b=nkgWjFMRUT6rKFvxWXdOqAkaV0DH1FKHpHRHAfeDSycsOQDe6r9SeRrpV27U3kSaI9 HfMA+V5xoFrhQ3s/j5w5kKMGAJMt/b8TUSBug+MEGk7QPzYf8Vvhlww/BAlGjBsXubSH uga3UlEzBYxI48f1vDRdz9qOU7ewlHldd7q6XURiFWZ526cZpNvP7O0oh7tnwbtxBIr/ xb8fntvVC6f6Mw5ksW8wgSV3MjLBN556QpNgrqf0fFRs6HoBH2CN+sC/7A3KL1KgCoWc r+GjgkJTcNx4qFJo8JghMejfmauSclbcQZUQKM5I3J0LB8odfa0KKBMfcU2g9YP2oGfA lVRg== Received: from bubble.grove.modra.org ([58.175.241.133]) by smtp.gmail.com with ESMTPSA id h17-v6sm28285454pfj.125.2018.11.13.04.52.46 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Nov 2018 04:52:47 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 66ABC805EE; Tue, 13 Nov 2018 23:22:43 +1030 (ACDT) Date: Tue, 13 Nov 2018 23:22:43 +1030 From: Alan Modra To: Segher Boessenkool Cc: gcc-patches@gcc.gnu.org Subject: [PATCH 5/6] [RS6000] Use standard call patterns for __tls_get_addr calls Message-ID: <20181113125243.GU29784@bubble.grove.modra.org> References: <20181107053326.GM29482@bubble.grove.modra.org> <20181107053751.GO29482@bubble.grove.modra.org> <2c5b2155-b4ce-b95a-8848-121c4398fb67@linux.ibm.com> <20181113001424.GD29784@bubble.grove.modra.org> <20181113111407.GP23873@gate.crashing.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181113111407.GP23873@gate.crashing.org> User-Agent: Mutt/1.9.4 (2018-02-28) X-IsSubscribed: yes 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. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index b80c278d742..7e45d2f0371 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1039,6 +1039,13 @@ (define_predicate "rs6000_tls_symbol_ref" (and (match_code "symbol_ref") (match_test "RS6000_SYMBOL_REF_TLS_P (op)"))) +;; Return 1 for the UNSPEC used in TLS call operands +(define_predicate "unspec_tls" + (match_code "unspec") +{ + return XINT (op, 1) == UNSPEC_TLSGD || XINT (op, 1) == UNSPEC_TLSLD; +}) + ;; Return 1 if the operand, used inside a MEM, is a valid first argument ;; to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. (define_predicate "call_operand" diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 967f65e2d94..3fd89dc20db 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -111,8 +111,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, @@ -136,7 +136,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); @@ -204,6 +203,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); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index cd1ab95166e..5fd6e17bdda 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -8583,6 +8583,43 @@ rs6000_legitimize_tls_address_aix (rtx addr, enum tls_model model) return dest; } +/* Mess with a call, to make it look like the tls_gdld insns when + !TARGET_TLS_MARKERS. These insns have an extra unspec to + differentiate them from standard calls, because they need to emit + the arg setup insns as well as the actual call. That keeps the + arg setup insns immediately adjacent to the branch and link. */ + +static void +edit_tls_call_insn (rtx arg) +{ + rtx call_insn = last_call_insn (); + if (!TARGET_TLS_MARKERS) + { + rtx patt = PATTERN (call_insn); + gcc_assert (GET_CODE (patt) == PARALLEL); + rtvec orig = XVEC (patt, 0); + rtvec v = rtvec_alloc (GET_NUM_ELEM (orig) + 1); + gcc_assert (GET_NUM_ELEM (orig) > 0); + /* The (set (..) (call (mem ..))). */ + RTVEC_ELT (v, 0) = RTVEC_ELT (orig, 0); + /* The extra unspec. */ + RTVEC_ELT (v, 1) = arg; + /* All other assorted call pattern pieces. */ + for (int i = 1; i < GET_NUM_ELEM (orig); i++) + RTVEC_ELT (v, i + 1) = RTVEC_ELT (orig, i); + XVEC (patt, 0) = v; + } + if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic) + use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), + pic_offset_table_rtx); +} + +/* 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; + /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute this (thread-local) address. */ @@ -8635,7 +8672,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model) } else { - rtx r3, got, tga, tmp1, tmp2, call_insn; + rtx got, tga, tmp1, tmp2; /* We currently use relocations like @got@tlsgd for tls, which means the linker will handle allocation of tls entries, placing @@ -8675,52 +8712,42 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model) if (model == TLS_MODEL_GLOBAL_DYNAMIC) { + rtx arg = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addr, got), + UNSPEC_TLSGD); + global_tlsarg = arg; + rtx argreg = const0_rtx; + if (TARGET_TLS_MARKERS) + { + argreg = gen_rtx_REG (Pmode, 3); + emit_insn (gen_rtx_SET (argreg, arg)); + } + tga = rs6000_tls_get_addr (); emit_library_call_value (tga, dest, LCT_CONST, Pmode, - const0_rtx, Pmode); + argreg, Pmode); + global_tlsarg = NULL_RTX; - r3 = gen_rtx_REG (Pmode, 3); - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) - { - if (TARGET_64BIT) - insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx); - else - insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx); - } - else if (DEFAULT_ABI == ABI_V4) - insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx); - else - gcc_unreachable (); - call_insn = last_call_insn (); - PATTERN (call_insn) = insn; - if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic) - use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), - pic_offset_table_rtx); + edit_tls_call_insn (arg); } else if (model == TLS_MODEL_LOCAL_DYNAMIC) { + rtx arg = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got), + UNSPEC_TLSLD); + global_tlsarg = arg; + rtx argreg = const0_rtx; + if (TARGET_TLS_MARKERS) + { + argreg = gen_rtx_REG (Pmode, 3); + emit_insn (gen_rtx_SET (argreg, arg)); + } + tga = rs6000_tls_get_addr (); tmp1 = gen_reg_rtx (Pmode); emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, - const0_rtx, Pmode); + argreg, Pmode); + global_tlsarg = NULL_RTX; - r3 = gen_rtx_REG (Pmode, 3); - if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) - { - if (TARGET_64BIT) - insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx); - else - insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx); - } - else if (DEFAULT_ABI == ABI_V4) - insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx); - else - gcc_unreachable (); - call_insn = last_call_insn (); - PATTERN (call_insn) = insn; - if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic) - use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), - pic_offset_table_rtx); + edit_tls_call_insn (arg); if (rs6000_tls_size == 16) { @@ -21175,19 +21202,19 @@ print_operand (FILE *file, rtx x, int code) else output_address (GET_MODE (x), XEXP (x, 0)); } + else if (toc_relative_expr_p (x, false, + &tocrel_base_oac, &tocrel_offset_oac)) + /* This hack along with a corresponding hack in + rs6000_output_addr_const_extra arranges to output addends + where the assembler expects to find them. eg. + (plus (unspec [(symbol_ref ("x")) (reg 2)] tocrel) 4) + without this hack would be output as "x@toc+4". We + want "x+4@toc". */ + output_addr_const (file, CONST_CAST_RTX (tocrel_base_oac)); + else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD) + output_addr_const (file, XVECEXP (x, 0, 0)); else - { - if (toc_relative_expr_p (x, false, &tocrel_base_oac, &tocrel_offset_oac)) - /* This hack along with a corresponding hack in - rs6000_output_addr_const_extra arranges to output addends - where the assembler expects to find them. eg. - (plus (unspec [(symbol_ref ("x")) (reg 2)] tocrel) 4) - without this hack would be output as "x@toc+4". We - want "x+4@toc". */ - output_addr_const (file, CONST_CAST_RTX (tocrel_base_oac)); - else - output_addr_const (file, x); - } + output_addr_const (file, x); return; case '&': @@ -21373,18 +21400,27 @@ rs6000_assemble_integer (rtx x, unsigned int size, int 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. */ + external call. FUNOP is the call mem argument operand number. */ static const char * -rs6000_call_template_1 (rtx *operands ATTRIBUTE_UNUSED, unsigned int funop, - bool sibcall, const char *arg) +rs6000_call_template_1 (rtx *operands, unsigned int funop, bool sibcall) { /* -Wformat-overflow workaround, without which gcc thinks that %u might produce 10 digits. */ gcc_assert (funop <= MAX_RECOG_OPERANDS); + char arg[12]; + arg[0] = 0; + if (GET_CODE (operands[funop + 1]) == UNSPEC) + { + if (XINT (operands[funop + 1], 1) == UNSPEC_TLSGD) + sprintf (arg, "(%%%u@tlsgd)", funop + 1); + else if (XINT (operands[funop + 1], 1) == UNSPEC_TLSLD) + sprintf (arg, "(%%&@tlsld)"); + else + gcc_unreachable (); + } + /* 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]; @@ -21392,7 +21428,7 @@ rs6000_call_template_1 (rtx *operands ATTRIBUTE_UNUSED, unsigned int funop, (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic == 2 ? "+32768" : "")); - static char str[32]; /* 4 spare */ + static char str[32]; /* 2 spare */ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg, sibcall ? "" : "\n\tnop"); @@ -21405,15 +21441,15 @@ rs6000_call_template_1 (rtx *operands ATTRIBUTE_UNUSED, unsigned int funop, } const char * -rs6000_call_template (rtx *operands, unsigned int funop, const char *arg) +rs6000_call_template (rtx *operands, unsigned int funop) { - return rs6000_call_template_1 (operands, funop, false, arg); + return rs6000_call_template_1 (operands, funop, false); } const char * -rs6000_sibcall_template (rtx *operands, unsigned int funop, const char *arg) +rs6000_sibcall_template (rtx *operands, unsigned int funop) { - return rs6000_call_template_1 (operands, funop, true, arg); + return rs6000_call_template_1 (operands, funop, true); } /* As above, for indirect calls. */ @@ -32503,23 +32539,20 @@ rs6000_set_default_type_attributes (tree type) /* Return a reference suitable for calling a function with the longcall attribute. */ -rtx +static rtx rs6000_longcall_ref (rtx call_ref) { - const char *call_name; - tree node; - if (GET_CODE (call_ref) != SYMBOL_REF) return call_ref; /* System V adds '.' to the internal name, so skip them. */ - call_name = XSTR (call_ref, 0); + const char *call_name = XSTR (call_ref, 0); if (*call_name == '.') { while (*call_name == '.') call_name++; - node = get_identifier (call_name); + tree node = get_identifier (call_name); call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node)); } @@ -37491,7 +37524,7 @@ chain_already_loaded (rtx_insn *last) /* Expand code to perform a call under the AIX or ELFv2 ABI. */ void -rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) +rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) { const bool direct_call_p = GET_CODE (func_desc) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (func_desc); @@ -37504,6 +37537,9 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) int n_call; rtx insn; + if (global_tlsarg) + tlsarg = global_tlsarg; + /* Handle longcall attributes. */ if (INTVAL (cookie) & CALL_LONG) func_desc = rs6000_longcall_ref (func_desc); @@ -37514,11 +37550,7 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) { /* Save the TOC into its reserved slot before the call, and prepare to restore it after the call. */ - rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); rtx stack_toc_offset = GEN_INT (RS6000_TOC_SAVE_SLOT); - rtx stack_toc_mem = gen_frame_mem (Pmode, - gen_rtx_PLUS (Pmode, stack_ptr, - stack_toc_offset)); rtx stack_toc_unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, stack_toc_offset), UNSPEC_TOCSLOT); @@ -37530,6 +37562,10 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) cfun->machine->save_toc_in_prologue = true; else { + rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); + rtx stack_toc_mem = gen_frame_mem (Pmode, + gen_rtx_PLUS (Pmode, stack_ptr, + stack_toc_offset)); MEM_VOLATILE_P (stack_toc_mem) = 1; emit_move_insn (stack_toc_mem, toc_reg); } @@ -37539,7 +37575,8 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) /* A function pointer in the ELFv2 ABI is just a plain address, but the ABI requires it to be loaded into r12 before the call. */ func_addr = gen_rtx_REG (Pmode, 12); - emit_move_insn (func_addr, func_desc); + if (!rtx_equal_p (func_addr, func_desc)) + emit_move_insn (func_addr, func_desc); abi_reg = func_addr; } else @@ -37594,7 +37631,7 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) } /* Create the call. */ - call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), flag); + call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), tlsarg); if (value != NULL_RTX) call[0] = gen_rtx_SET (value, call[0]); n_call = 1; @@ -37618,15 +37655,18 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) /* Expand code to perform a sibling call under the AIX or ELFv2 ABI. */ void -rs6000_sibcall_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) +rs6000_sibcall_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) { rtx call[2]; rtx insn; gcc_assert (INTVAL (cookie) == 0); + if (global_tlsarg) + tlsarg = global_tlsarg; + /* Create the call. */ - call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_desc), flag); + call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_desc), tlsarg); if (value != NULL_RTX) call[0] = gen_rtx_SET (value, call[0]); @@ -37639,6 +37679,42 @@ rs6000_sibcall_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, TOC_REGNUM)); } +/* Expand code to perform a call under the SYSV4 ABI. */ + +void +rs6000_call_sysv (rtx value, rtx func, rtx tlsarg, rtx cookie) +{ + rtx func_addr; + rtx call[3]; + rtx insn; + + if (global_tlsarg) + tlsarg = global_tlsarg; + + /* Handle longcall attributes. */ + if (INTVAL (cookie) & CALL_LONG) + func = rs6000_longcall_ref (func); + + /* Handle indirect calls. */ + if (GET_CODE (func) != SYMBOL_REF) + func_addr = force_reg (Pmode, func); + else + func_addr = func; + + /* Create the call. */ + call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), tlsarg); + if (value != NULL_RTX) + call[0] = gen_rtx_SET (value, call[0]); + + unsigned int mask = CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS; + call[1] = gen_rtx_USE (VOIDmode, GEN_INT (INTVAL (cookie) & mask)); + + call[2] = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO)); + + insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call)); + insn = emit_call_insn (insn); +} + /* Return whether we need to always update the saved TOC pointer when we update the stack pointer. */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index c261c8bb9c1..336d42335cb 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -9436,74 +9436,73 @@ (define_peephole2 ;; TLS support. -(define_insn_and_split "tls_gd_aix" - [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (call (mem:SI (match_operand:P 3 "symbol_ref_operand" "s")) - (match_operand 4))) - (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") - (match_operand:P 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" +(define_insn "*tls_gdld_aix" + [(match_parallel 3 "" + [(set (match_operand:P 0 "gpc_reg_operand" "=b") + (call (mem:SI (match_operand:P 1)) + (match_operand:P 2 "unspec_tls"))) + (match_dup 2)])] + "HAVE_AS_TLS && !TARGET_TLS_MARKERS + && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" { - if (TARGET_CMODEL != CMODEL_SMALL) - output_asm_insn ("addis %0,%1,%2@got@tlsgd@ha\;" - "addi %0,%0,%2@got@tlsgd@l", operands); + rtx op[3]; + op[0] = operands[0]; + op[1] = XVECEXP (operands[2], 0, 0); + if (XINT (operands[2], 1) == UNSPEC_TLSGD) + { + op[2] = XVECEXP (operands[2], 0, 1); + if (TARGET_CMODEL != CMODEL_SMALL) + output_asm_insn ("addis %0,%2,%1@got@tlsgd@ha\;" + "addi %0,%0,%1@got@tlsgd@l", op); + else + output_asm_insn ("addi %0,%2,%1@got@tlsgd", op); + } else - output_asm_insn ("addi %0,%1,%2@got@tlsgd", operands); - return rs6000_call_template (operands, 3, ""); + { + if (TARGET_CMODEL != CMODEL_SMALL) + output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\;" + "addi %0,%0,%&@got@tlsld@l", op); + else + output_asm_insn ("addi %0,%1,%&@got@tlsld", op); + } + return rs6000_call_template (operands, 1); } - "&& TARGET_TLS_MARKERS" - [(set (match_dup 0) - (unspec:P [(match_dup 1) - (match_dup 2)] - UNSPEC_TLSGD)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 3)) - (match_dup 4))) - (unspec:P [(match_dup 2)] UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))])] - "" [(set_attr "type" "two") (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) (const_int 16) (const_int 12)))]) -(define_insn_and_split "tls_gd_sysv" - [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (call (mem:SI (match_operand:P 3 "symbol_ref_operand" "s")) - (match_operand 4))) - (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") - (match_operand:P 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" +(define_insn "*tls_gdld_sysv" + [(match_parallel 3 "" + [(set (match_operand:P 0 "gpc_reg_operand" "=b") + (call (mem:SI (match_operand:P 1)) + (match_operand:P 2 "unspec_tls"))) + (match_dup 2)])] + "HAVE_AS_TLS && !TARGET_TLS_MARKERS && DEFAULT_ABI == ABI_V4" { - output_asm_insn ("addi %0,%1,%2@got@tlsgd", operands); - return rs6000_call_template (operands, 3, ""); + rtx op[3]; + op[0] = operands[0]; + op[1] = XVECEXP (operands[2], 0, 0); + if (XINT (operands[2], 1) == UNSPEC_TLSGD) + { + op[2] = XVECEXP (operands[2], 0, 1); + output_asm_insn ("addi %0,%2,%1@got@tlsgd", op); + } + else + output_asm_insn ("addi %0,%1,%&@got@tlsld", op); + return rs6000_call_template (operands, 1); } - "&& TARGET_TLS_MARKERS" - [(set (match_dup 0) - (unspec:P [(match_dup 1) - (match_dup 2)] - UNSPEC_TLSGD)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 3)) - (match_dup 4))) - (unspec:P [(match_dup 2)] UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))])] - "" [(set_attr "type" "two") (set_attr "length" "8")]) (define_insn_and_split "*tls_gd" [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") - (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") + (match_operand:P 2 "gpc_reg_operand" "b")] UNSPEC_TLSGD))] "HAVE_AS_TLS && TARGET_TLS_MARKERS" - "addi %0,%1,%2@got@tlsgd" + "addi %0,%2,%1@got@tlsgd" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) (high:P @@ -9512,7 +9511,7 @@ (define_insn_and_split "*tls_gd" (lo_sum:P (match_dup 3) (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))] { - operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); + operands[3] = gen_reg_rtx (mode); } [(set (attr "length") (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) @@ -9522,105 +9521,21 @@ (define_insn_and_split "*tls_gd" (define_insn "*tls_gd_high" [(set (match_operand:P 0 "gpc_reg_operand" "=b") (high:P - (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") - (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") + (match_operand:P 2 "gpc_reg_operand" "b")] UNSPEC_TLSGD)))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" - "addis %0,%1,%2@got@tlsgd@ha") + "addis %0,%2,%1@got@tlsgd@ha") (define_insn "*tls_gd_low" [(set (match_operand:P 0 "gpc_reg_operand" "=b") (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") - (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b") - (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "") + (match_operand:P 3 "gpc_reg_operand" "b")] UNSPEC_TLSGD)))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addi %0,%1,%2@got@tlsgd@l") -(define_insn "*tls_gd_call_aix" - [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) - (match_operand 2))) - (unspec:P [(match_operand:P 3 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && TARGET_TLS_MARKERS - && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" -{ - return rs6000_call_template (operands, 1, "(%3@tlsgd)"); -} - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*tls_gd_call_sysv" - [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) - (match_operand 2))) - (unspec:P [(match_operand:P 3 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" -{ - return rs6000_call_template (operands, 1, "(%3@tlsgd)"); -} - [(set_attr "type" "branch")]) - -(define_insn_and_split "tls_ld_aix" - [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (call (mem:SI (match_operand:P 2 "symbol_ref_operand" "s")) - (match_operand 3))) - (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] - UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" -{ - if (TARGET_CMODEL != CMODEL_SMALL) - output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\;" - "addi %0,%0,%&@got@tlsld@l", operands); - else - output_asm_insn ("addi %0,%1,%&@got@tlsld", operands); - return rs6000_call_template (operands, 2, ""); -} - "&& TARGET_TLS_MARKERS" - [(set (match_dup 0) - (unspec:P [(match_dup 1)] - UNSPEC_TLSLD)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 2)) - (match_dup 3))) - (unspec:P [(const_int 0)] UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))])] - "" - [(set_attr "type" "two") - (set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 16) - (const_int 12)))]) - -(define_insn_and_split "tls_ld_sysv" - [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (call (mem:SI (match_operand:P 2 "symbol_ref_operand" "s")) - (match_operand 3))) - (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] - UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" -{ - output_asm_insn ("addi %0,%1,%&@got@tlsld", operands); - return rs6000_call_template (operands, 2, ""); -} - "&& TARGET_TLS_MARKERS" - [(set (match_dup 0) - (unspec:P [(match_dup 1)] - UNSPEC_TLSLD)) - (parallel [(set (match_dup 0) - (call (mem:SI (match_dup 2)) - (match_dup 3))) - (unspec:P [(const_int 0)] UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))])] - "" - [(set_attr "length" "8")]) - (define_insn_and_split "*tls_ld" [(set (match_operand:P 0 "gpc_reg_operand" "=b") (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] @@ -9630,12 +9545,12 @@ (define_insn_and_split "*tls_ld" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 2) (high:P - (unspec:P [(const_int 0) (match_dup 1)] UNSPEC_TLSLD))) + (unspec:P [(match_dup 1)] UNSPEC_TLSLD))) (set (match_dup 0) (lo_sum:P (match_dup 2) - (unspec:P [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))] + (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))] { - operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); + operands[2] = gen_reg_rtx (mode); } [(set (attr "length") (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) @@ -9645,8 +9560,7 @@ (define_insn_and_split "*tls_ld" (define_insn "*tls_ld_high" [(set (match_operand:P 0 "gpc_reg_operand" "=b") (high:P - (unspec:P [(const_int 0) - (match_operand:P 1 "gpc_reg_operand" "b")] + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] UNSPEC_TLSLD)))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%&@got@tlsld@ha") @@ -9654,38 +9568,11 @@ (define_insn "*tls_ld_high" (define_insn "*tls_ld_low" [(set (match_operand:P 0 "gpc_reg_operand" "=b") (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") - (unspec:P [(const_int 0) - (match_operand:P 2 "gpc_reg_operand" "b")] + (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")] UNSPEC_TLSLD)))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addi %0,%1,%&@got@tlsld@l") -(define_insn "*tls_ld_call_aix" - [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) - (match_operand 2))) - (unspec:P [(const_int 0)] UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && TARGET_TLS_MARKERS - && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" -{ - return rs6000_call_template (operands, 1, "(%&@tlsld)"); -} - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*tls_ld_call_sysv" - [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) - (match_operand 2))) - (unspec:P [(const_int 0)] UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" -{ - return rs6000_call_template (operands, 1, "(%&@tlsld)"); -} - [(set_attr "type" "branch")]) - (define_insn "tls_dtprel_" [(set (match_operand:P 0 "gpc_reg_operand" "=r") (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") @@ -10359,7 +10246,6 @@ (define_expand "call" #endif gcc_assert (GET_CODE (operands[0]) == MEM); - gcc_assert (GET_CODE (operands[1]) == CONST_INT); operands[0] = XEXP (operands[0], 0); @@ -10369,23 +10255,14 @@ (define_expand "call" DONE; } - if (GET_CODE (operands[0]) != SYMBOL_REF - || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0)) + if (DEFAULT_ABI == ABI_V4) { - if (INTVAL (operands[2]) & CALL_LONG) - operands[0] = rs6000_longcall_ref (operands[0]); - - switch (DEFAULT_ABI) - { - case ABI_V4: - case ABI_DARWIN: - operands[0] = force_reg (Pmode, operands[0]); - break; - - default: - gcc_unreachable (); - } + rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]); + DONE; } + + if (GET_CODE (operands[0]) != SYMBOL_REF) + operands[0] = force_reg (Pmode, operands[0]); }) (define_expand "call_value" @@ -10402,7 +10279,6 @@ (define_expand "call_value" #endif gcc_assert (GET_CODE (operands[1]) == MEM); - gcc_assert (GET_CODE (operands[2]) == CONST_INT); operands[1] = XEXP (operands[1], 0); @@ -10412,23 +10288,14 @@ (define_expand "call_value" DONE; } - if (GET_CODE (operands[1]) != SYMBOL_REF - || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0)) + if (DEFAULT_ABI == ABI_V4) { - if (INTVAL (operands[3]) & CALL_LONG) - operands[1] = rs6000_longcall_ref (operands[1]); - - switch (DEFAULT_ABI) - { - case ABI_V4: - case ABI_DARWIN: - operands[1] = force_reg (Pmode, operands[1]); - break; - - default: - gcc_unreachable (); - } + rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]); + DONE; } + + if (GET_CODE (operands[1]) != SYMBOL_REF) + operands[1] = force_reg (Pmode, operands[1]); }) ;; Call to function in current module. No TOC pointer reload needed. @@ -10515,7 +10382,7 @@ (define_insn "*call_value_local64" ;; A function pointer under System V is just a normal pointer ;; operands[0] is the function pointer -;; operands[1] is the stack size to clean up +;; operands[1] is the tls call arg ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument ;; which indicates how to set cr1 @@ -10566,7 +10433,7 @@ (define_insn_and_split "*call_nonlocal_sysv" #if TARGET_MACHO return macho_call_template (insn, operands, 0, 2); #else - return rs6000_call_template (operands, 0, ""); + return rs6000_call_template (operands, 0); #endif } "DEFAULT_ABI == ABI_V4 @@ -10599,7 +10466,7 @@ (define_insn "*call_nonlocal_sysv_secure" else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn ("creqv 6,6,6", operands); - return rs6000_call_template (operands, 0, ""); + return rs6000_call_template (operands, 0); } [(set_attr "type" "branch,branch") (set_attr "length" "4,8")]) @@ -10653,7 +10520,7 @@ (define_insn_and_split "*call_value_nonlocal_sysv" #if TARGET_MACHO return macho_call_template (insn, operands, 1, 3); #else - return rs6000_call_template (operands, 1, ""); + return rs6000_call_template (operands, 1); #endif } "DEFAULT_ABI == ABI_V4 @@ -10688,7 +10555,7 @@ (define_insn "*call_value_nonlocal_sysv_secure" else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn ("creqv 6,6,6", operands); - return rs6000_call_template (operands, 1, ""); + return rs6000_call_template (operands, 1); } [(set_attr "type" "branch,branch") (set_attr "length" "4,8")]) @@ -10722,7 +10589,7 @@ (define_insn "*call_nonlocal_aix" (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" { - return rs6000_call_template (operands, 0, ""); + return rs6000_call_template (operands, 0); } [(set_attr "type" "branch") (set_attr "length" "8")]) @@ -10734,7 +10601,7 @@ (define_insn "*call_value_nonlocal_aix" (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" { - return rs6000_call_template (operands, 1, ""); + return rs6000_call_template (operands, 1); } [(set_attr "type" "branch") (set_attr "length" "8")]) @@ -10985,7 +10852,7 @@ (define_insn "*sibcall_nonlocal_sysv" if (which_alternative >= 2) return rs6000_indirect_sibcall_template (operands, 0); else - return rs6000_sibcall_template (operands, 0, ""); + return rs6000_sibcall_template (operands, 0); } [(set_attr "type" "branch") (set_attr_alternative "length" @@ -11025,7 +10892,7 @@ (define_insn "*sibcall_value_nonlocal_sysv" return "crset 2\;beq%T1-\;b $"; } else - return rs6000_sibcall_template (operands, 1, ""); + return rs6000_sibcall_template (operands, 1); } [(set_attr "type" "branch") (set_attr_alternative "length" @@ -11049,7 +10916,7 @@ (define_insn "*sibcall_aix" "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" { if (which_alternative == 0) - return rs6000_sibcall_template (operands, 0, ""); + return rs6000_sibcall_template (operands, 0); else return "b%T0"; } @@ -11063,7 +10930,7 @@ (define_insn "*sibcall_value_aix" "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" { if (which_alternative == 0) - return rs6000_sibcall_template (operands, 1, ""); + return rs6000_sibcall_template (operands, 1); else return "b%T1"; }