From patchwork Tue Nov 13 12:47:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 997081 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-489876-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="SHXr5YAS"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="NJEBUr+y"; 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 42vSB36Pv7z9s9G for ; Tue, 13 Nov 2018 23:49:13 +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=qPcDNdy8fi8c3Y5US s0wIqgF0fDbfkcVnGhvVunLv48GLs7EzBaJj7vUWmj+J3mMNqjTkoK9w8G1Dd9+v lLQMthzqVx3aL0j3X5XAuOM2k8dBHDBpnQuM52980UBLTVvQxlWpIZHY/CXylgEt 72H7VupHKgsO/JyMvTOiaxpwFg= 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=XBIfsxPo6eFjyW7FHtxwc60 MUlY=; b=SHXr5YASDc9J26cd9K7UrY6AjTE1ZaKM9tgPE2olk9pwJymN50uDSoI fMbfh1c2lOGhPIvltuwP8bArx54dEc5K/s5sqS5tl6lemhNiTnyj2pFN5GcWqtnD CrvUqPNlBbeAH0z5PfjydeU3lphoVTLKIG01AKz8erdvpcZwX6b4= Received: (qmail 60466 invoked by alias); 13 Nov 2018 12:48:48 -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 59298 invoked by uid 89); 13 Nov 2018 12:48:05 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=230, 7 X-HELO: mail-pg1-f181.google.com Received: from mail-pg1-f181.google.com (HELO mail-pg1-f181.google.com) (209.85.215.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Nov 2018 12:48:02 +0000 Received: by mail-pg1-f181.google.com with SMTP id z17-v6so5653826pgv.3 for ; Tue, 13 Nov 2018 04:48:02 -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=1tiUwyIOOPbyj5WwD4iwaHGrSpV9/yQrTP/6VpweVu8=; b=NJEBUr+y7Chq1121sYLbpo42bdwR8WHd5HtvqcUcvv74XcB4IEE39toLZwz7XApoRo Fa16J70flBnFJA/Cv6cQ7unqMMJfuTFmnVIWeU69+NpTzhH2dQzbVD4O7A1gO5Wc+jIp mTj2csMkRlefjX4b7UkXwzqMoXPaY3kye7gjBSLLRNdAVESs3iv5KM6OZSb4FzbACaBh kXPe6jKkCUMjPmbAJdahDQfQw97iSK20pcQKdFS7xS/o2BCgKLHVjQSbZUydfRMBXDJs OsRQVLrnYpSIdwFkKgIroKUpTJMc4I4ZsONiuLpk5NTk9vCLo5zSNnBv91OHw1hlbnO0 ZrLQ== Received: from bubble.grove.modra.org ([58.175.241.133]) by smtp.gmail.com with ESMTPSA id i62sm3108303pge.44.2018.11.13.04.47.58 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Nov 2018 04:47:59 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 7F256805EE; Tue, 13 Nov 2018 23:17:55 +1030 (ACDT) Date: Tue, 13 Nov 2018 23:17:55 +1030 From: Alan Modra To: Segher Boessenkool Cc: gcc-patches@gcc.gnu.org Subject: [PATCH 1/6] [RS6000] rs6000_call_template for external call insn assembly output Message-ID: <20181113124755.GQ29784@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. 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. diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index fb69019c47c..303ba7b91c3 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -111,6 +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 enum rtx_code rs6000_reverse_condition (machine_mode, enum rtx_code); extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx); @@ -228,7 +230,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 516e69724cc..6e84f5053c2 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -21372,6 +21372,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. */ @@ -32810,8 +32854,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 65f5fa6e66b..db9cfe92c72 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -9453,10 +9453,11 @@ (define_insn_and_split "tls_gd_aix" "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) @@ -9485,15 +9486,8 @@ (define_insn_and_split "tls_gd_sysv" (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) @@ -9558,7 +9552,9 @@ (define_insn "*tls_gd_call_aix" (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")]) @@ -9571,13 +9567,7 @@ (define_insn "*tls_gd_call_sysv" (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")]) @@ -9591,10 +9581,11 @@ (define_insn_and_split "tls_ld_aix" "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) @@ -9621,15 +9612,8 @@ (define_insn_and_split "tls_ld_sysv" (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) @@ -9690,7 +9674,9 @@ (define_insn "*tls_ld_call_aix" (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")]) @@ -9702,13 +9688,7 @@ (define_insn "*tls_ld_call_sysv" (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")]) @@ -10594,15 +10574,9 @@ (define_insn_and_split "*call_nonlocal_sysv" 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 @@ -10635,13 +10609,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); - 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")]) @@ -10697,15 +10665,9 @@ (define_insn_and_split "*call_value_nonlocal_sysv" 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 @@ -10740,10 +10702,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); - 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")]) @@ -10776,7 +10735,9 @@ (define_insn "*call_nonlocal_aix" (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")]) @@ -10786,7 +10747,9 @@ (define_insn "*call_value_nonlocal_aix" (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")]) @@ -11063,13 +11026,8 @@ (define_insn "*sibcall_nonlocal_sysv" /* 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" @@ -11108,13 +11066,8 @@ (define_insn "*sibcall_value_nonlocal_sysv" /* 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" @@ -11136,9 +11089,12 @@ (define_insn "*sibcall_aix" (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" @@ -11147,9 +11103,12 @@ (define_insn "*sibcall_value_aix" (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" From patchwork Tue Nov 13 12:49:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 997082 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-489877-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="Idg0cN5m"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Gd//YrDB"; 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 42vSBJ0wX4z9s9G for ; Tue, 13 Nov 2018 23:49:27 +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=IT7ObivLCfoN35uhL zjgt2EbUusZFGqJ/19vITUyrbD5Fzy3MODQeoXMJVJN3vAJHT+9LiVblGheaMnpt e5ZS7JfLIcVm0E6aiZzJPs3V/WREEE/hBOG/XATSxkCJYxymyDOjYPN1C8nZ6Vto lKVwztAPb4h82Y9jxNGy7tc2Og= 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=NddRMurPv8Cd9SxjujwkW9G qukg=; b=Idg0cN5mD7CpiVMa+FNkc80Y1EQjSqfRQfUGX8VJnugsRLsIixmFtlp rgW21wzBqVFkSZr+HqcRz2E76NbmHM/+39HxSKy1xv8PzOW99W4UerBZFvbMdhbe j9WpjrtjzgYFrYbL+Tjcwygr0LgovmXX27noH0gg8XpZKDt2DFKY= Received: (qmail 61873 invoked by alias); 13 Nov 2018 12:49:14 -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 61686 invoked by uid 89); 13 Nov 2018 12:49:12 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-pf1-f176.google.com Received: from mail-pf1-f176.google.com (HELO mail-pf1-f176.google.com) (209.85.210.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Nov 2018 12:49:09 +0000 Received: by mail-pf1-f176.google.com with SMTP id g7-v6so5997499pfo.10 for ; Tue, 13 Nov 2018 04:49:09 -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=6mL0Z7X2Z8n+yREa+z//UumMa+dCn8q8nhLGr9ANpzE=; b=Gd//YrDBmzLwx9uDJiIpSCOBYihY9KHJAPYRNhbH30jAHEQPKGhVnATSbPd1GrLyRB w3/g/4yC5ua0+vtnQQSeB2ru1kbuRtDmmNzSY1k/uZeWCxL5Xs0hHsTMr4k8YlypAktN BXtit5uHAB5onN/wMf2Y6uu6NVGyq/YWMhR7C3rRDgCZ+MtvwJIOurpYBk/T7Tap/B4Z cRAbq5OLTTxsaq9SLRlJIKi0r+HxraikJCy0Yx0qMIT1i1xFo2VTE421Sr/dRRvJbuOA 24wmbkom+Oyopt7319y6aWmiiaKzuUGJ4os8skUNkW5wTvTeAxbkxheoiZ1CKTjdjnHS rr3g== Received: from bubble.grove.modra.org ([58.175.241.133]) by smtp.gmail.com with ESMTPSA id z30-v6sm10496607pfg.41.2018.11.13.04.49.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Nov 2018 04:49:07 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 49E52805EE; Tue, 13 Nov 2018 23:19:03 +1030 (ACDT) Date: Tue, 13 Nov 2018 23:19:03 +1030 From: Alan Modra To: Segher Boessenkool Cc: gcc-patches@gcc.gnu.org Subject: [PATCH 2/6] [RS6000] rs6000_indirect_call_template Message-ID: <20181113124903.GR29784@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. Like the last patch for external calls, now handle most assembly code for indirect calls in one place. The patch also merges some insns, correcting some !rs6000_speculate_indirect_jumps cases branching to LR, which don't require a speculation barrier. * config/rs6000/rs6000-protos.h (rs6000_indirect_call_template), (rs6000_indirect_sibcall_template): Declare. * config/rs6000/rs6000.c (rs6000_indirect_call_template_1), (rs6000_indirect_call_template, rs6000_indirect_sibcall_template): New functions. * config/rs6000/rs6000.md (call_indirect_nonlocal_sysv), (call_value_indirect_nonlocal_sysv, sibcall_nonlocal_sysv), (call_indirect_aix, call_value_indirect_aix): Use rs6000_indirect_call_template and rs6000_indirect_sibcall_template. call_indirect_elfv2, call_value_indirect_elfv2): Likewise, and handle both speculation and non-speculation cases. (call_indirect_aix_nospec, call_value_indirect_aix_nospec): Delete. (call_indirect_elfv2_nospec, call_value_indirect_elfv2_nospec): Delete. diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 303ba7b91c3..967f65e2d94 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -113,6 +113,8 @@ 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_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, enum rtx_code); extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6e84f5053c2..cd1ab95166e 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -21416,6 +21416,83 @@ rs6000_sibcall_template (rtx *operands, unsigned int funop, const char *arg) return rs6000_call_template_1 (operands, funop, true, arg); } +/* As above, for indirect calls. */ + +static const char * +rs6000_indirect_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); + + static char str[144]; + const char *ptrload = TARGET_64BIT ? "d" : "wz"; + + /* We don't need the extra code to stop indirect call speculation if + calling via LR. */ + bool speculate = (TARGET_MACHO + || rs6000_speculate_indirect_jumps + || (REG_P (operands[funop]) + && REGNO (operands[funop]) == LR_REGNO)); + + if (DEFAULT_ABI == ABI_AIX) + { + if (speculate) + sprintf (str, + "l%s 2,%%%u\n\t" + "b%%T%ul\n\t" + "l%s 2,%%%u(1)", + ptrload, funop + 2, funop, ptrload, funop + 3); + else + sprintf (str, + "crset 2\n\t" + "l%s 2,%%%u\n\t" + "beq%%T%ul-\n\t" + "l%s 2,%%%u(1)", + ptrload, funop + 2, funop, ptrload, funop + 3); + } + else if (DEFAULT_ABI == ABI_ELFv2) + { + if (speculate) + sprintf (str, + "b%%T%ul\n\t" + "l%s 2,%%%u(1)", + funop, ptrload, funop + 2); + else + sprintf (str, + "crset 2\n\t" + "beq%%T%ul-\n\t" + "l%s 2,%%%u(1)", + funop, ptrload, funop + 2); + } + else + { + if (speculate) + sprintf (str, + "b%%T%u%s", + funop, sibcall ? "" : "l"); + else + sprintf (str, + "crset 2\n\t" + "beq%%T%u%s-%s", + funop, sibcall ? "" : "l", sibcall ? "\n\tb $" : ""); + } + return str; +} + +const char * +rs6000_indirect_call_template (rtx *operands, unsigned int funop) +{ + return rs6000_indirect_call_template_1 (operands, funop, false); +} + +const char * +rs6000_indirect_sibcall_template (rtx *operands, unsigned int funop) +{ + return rs6000_indirect_call_template_1 (operands, funop, true); +} + #if defined (HAVE_GAS_HIDDEN) && !TARGET_MACHO /* Emit an assembler directive to set symbol visibility for DECL to VISIBILITY_TYPE. */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index db9cfe92c72..fe904b1966b 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -10539,11 +10539,7 @@ (define_insn "*call_indirect_nonlocal_sysv" else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn ("creqv 6,6,6", operands); - if (rs6000_speculate_indirect_jumps - || which_alternative == 1 || which_alternative == 3) - return "b%T0l"; - else - return "crset 2\;beq%T0l-"; + return rs6000_indirect_call_template (operands, 0); } [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") (set_attr_alternative "length" @@ -10629,11 +10625,7 @@ (define_insn "*call_value_indirect_nonlocal_sysv" else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn ("creqv 6,6,6", operands); - if (rs6000_speculate_indirect_jumps - || which_alternative == 1 || which_alternative == 3) - return "b%T1l"; - else - return "crset 2\;beq%T1l-"; + return rs6000_indirect_call_template (operands, 1); } [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") (set_attr_alternative "length" @@ -10764,21 +10756,16 @@ (define_insn "*call_indirect_aix" (use (match_operand:P 2 "memory_operand" ",")) (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps" - " 2,%2\;b%T0l\; 2,%3(1)" - [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) - -(define_insn "*call_indirect_aix_nospec" - [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) - (match_operand 1 "" "g,g")) - (use (match_operand:P 2 "memory_operand" ",")) - (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps" - "crset 2\; 2,%2\;beq%T0l-\; 2,%3(1)" + "DEFAULT_ABI == ABI_AIX" +{ + return rs6000_indirect_call_template (operands, 0); +} [(set_attr "type" "jmpreg") - (set_attr "length" "16")]) + (set (attr "length") + (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (const_string "16") + (const_string "12")))]) (define_insn "*call_value_indirect_aix" [(set (match_operand 0 "" "") @@ -10787,22 +10774,16 @@ (define_insn "*call_value_indirect_aix" (use (match_operand:P 3 "memory_operand" ",")) (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps" - " 2,%3\;b%T1l\; 2,%4(1)" - [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) - -(define_insn "*call_value_indirect_aix_nospec" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) - (match_operand 2 "" "g,g"))) - (use (match_operand:P 3 "memory_operand" ",")) - (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps" - "crset 2\; 2,%3\;beq%T1l-\; 2,%4(1)" + "DEFAULT_ABI == ABI_AIX" +{ + return rs6000_indirect_call_template (operands, 1); +} [(set_attr "type" "jmpreg") - (set_attr "length" "16")]) + (set (attr "length") + (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (const_string "16") + (const_string "12")))]) ;; Call to indirect functions with the ELFv2 ABI. ;; Operand0 is the addresss of the function to call @@ -10813,21 +10794,16 @@ (define_insn "*call_indirect_elfv2" (match_operand 1 "" "g,g")) (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps" - "b%T0l\; 2,%2(1)" - [(set_attr "type" "jmpreg") - (set_attr "length" "8")]) - -;; Variant with deliberate misprediction. -(define_insn "*call_indirect_elfv2_nospec" - [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) - (match_operand 1 "" "g,g")) - (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps" - "crset 2\;beq%T0l-\; 2,%2(1)" + "DEFAULT_ABI == ABI_ELFv2" +{ + return rs6000_indirect_call_template (operands, 0); +} [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) + (set (attr "length") + (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (const_string "12") + (const_string "8")))]) (define_insn "*call_value_indirect_elfv2" [(set (match_operand 0 "" "") @@ -10835,22 +10811,16 @@ (define_insn "*call_value_indirect_elfv2" (match_operand 2 "" "g,g"))) (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps" - "b%T1l\; 2,%3(1)" - [(set_attr "type" "jmpreg") - (set_attr "length" "8")]) - -; Variant with deliberate misprediction. -(define_insn "*call_value_indirect_elfv2_nospec" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) - (match_operand 2 "" "g,g"))) - (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps" - "crset 2\;beq%T1l-\; 2,%3(1)" + "DEFAULT_ABI == ABI_ELFv2" +{ + return rs6000_indirect_call_template (operands, 1); +} [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) + (set (attr "length") + (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (const_string "12") + (const_string "8")))]) ;; Call subroutine returning any type. (define_expand "untyped_call" @@ -11019,13 +10989,7 @@ (define_insn "*sibcall_nonlocal_sysv" output_asm_insn ("creqv 6,6,6", operands); if (which_alternative >= 2) - { - if (rs6000_speculate_indirect_jumps) - return "b%T0"; - else - /* Can use CR0 since it is volatile across sibcalls. */ - return "crset 2\;beq%T0-\;b $"; - } + return rs6000_indirect_sibcall_template (operands, 0); else return rs6000_sibcall_template (operands, 0, ""); } From patchwork Tue Nov 13 12:50:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 997083 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-489878-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="mYgHZH8h"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="XHrQC9Hl"; 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 42vSCV4Xrfz9s9G for ; Tue, 13 Nov 2018 23:50:30 +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=lTM5cGVqMhra3uptV u6L50IxuYtnzyFkOojUOnqk6aDVdXmKnPNdy4T/36cE4XLWm6f2O/jHN4+FYBBVt bW1AVx8HgbpN7JDRvgK/iBPjhvQmqnuoqyLmp3pDZkdsx+38AobIIbGKJsNIQgoX +pRgiHDzrRNoSuEtqpY7ndGnPI= 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=SSnTdHtp8EdlWWiqFV6cKFz C88I=; b=mYgHZH8hUA63v7Jhn2m0gVT6CLnEwmKtNYw7r9RUWeZbpQpIUZB3EzG uopIMRDoRPlq0fnj9mbaJztToUluc7ivpcM32RZitlQedrjRoMPk386pZqrnNX8E 8qL263XDWUmktk2lmuoj2Xj8AQ6brJ/H+tkCXQ43p2n1dtDuq9yM= Received: (qmail 66214 invoked by alias); 13 Nov 2018 12:50:22 -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 66193 invoked by uid 89); 13 Nov 2018 12:50:21 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=HX-Received:sk:b34-v6m, HX-Received:4025 X-HELO: mail-pl1-f173.google.com Received: from mail-pl1-f173.google.com (HELO mail-pl1-f173.google.com) (209.85.214.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Nov 2018 12:50:16 +0000 Received: by mail-pl1-f173.google.com with SMTP id w24-v6so5984553plq.3 for ; Tue, 13 Nov 2018 04:50:15 -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=vuCD/H47WHfTZ2MAbmqzmaC8Hk4GYWPMsKOW/qjHKO4=; b=XHrQC9HlUZp+ziTesr6CzzOIjL5Ipswr+TF9DKwpiedjr2W8m+8R1AFe1BFScYoy3m myFnQ4iLR275veYoVQqJwavO6RtoB1PH+eztn1iycs306FpKo1GJVBAArpMgfPf+HXtv 8wwPgIDQ9fevvjanwAWsNZDdzcps77mgYn8avo6su6GElPW4HKdJaI8N2g2tWtwc22Y1 miHqrBQqLS7pjN+1ylKMpkbXvSnGOMT4mKmjncuV68EV49OBus4kOmjXmAShWm1eJJjQ vZKQvQMqpoEvotzEa0NdZd1XjnEtoayqn9Kl55mJw/a06Cd/ezFrgA/LWhgq325/yXD0 ukOA== Received: from bubble.grove.modra.org ([58.175.241.133]) by smtp.gmail.com with ESMTPSA id x63-v6sm26616378pfk.14.2018.11.13.04.50.11 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Nov 2018 04:50:12 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id D60C9805EE; Tue, 13 Nov 2018 23:20:08 +1030 (ACDT) Date: Tue, 13 Nov 2018 23:20:08 +1030 From: Alan Modra To: Segher Boessenkool Cc: gcc-patches@gcc.gnu.org Subject: [PATCH 3/6] [RS6000] Replace TLSmode with P, and correct tls call mems Message-ID: <20181113125008.GS29784@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. There is really no need to define a TLSmode mode iterator that is identical (since !TARGET_64BIT == TARGET_32BIT) to the much used P mode iterator. It's nonsense to think we might ever want to support 32-bit TLS on 64-bit or vice versa! The patch also fixes a minor error in the call mems. All other direct calls use (call (mem:SI ..)). * config/rs6000/rs6000.md (TLSmode): Delete mode iterator. Replace with P throughout except for call mems which should use SI. (tls_abi_suffix, tls_sysv_suffix, tls_insn_suffix): Delete mode iterators. Replace with bits, mode and ptrload respectively. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index fe904b1966b..793a0a9d840 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -9436,19 +9436,13 @@ (define_peephole2 ;; TLS support. -;; Mode attributes for different ABIs. -(define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")]) -(define_mode_attr tls_abi_suffix [(SI "32") (DI "64")]) -(define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")]) -(define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")]) - -(define_insn_and_split "tls_gd_aix" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) +(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 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) + (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)" { @@ -9461,28 +9455,28 @@ (define_insn_and_split "tls_gd_aix" } "&& TARGET_TLS_MARKERS" [(set (match_dup 0) - (unspec:TLSmode [(match_dup 1) - (match_dup 2)] - UNSPEC_TLSGD)) + (unspec:P [(match_dup 1) + (match_dup 2)] + UNSPEC_TLSGD)) (parallel [(set (match_dup 0) - (call (mem:TLSmode (match_dup 3)) - (match_dup 4))) - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) + (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)))]) + (const_int 16) + (const_int 12)))]) -(define_insn_and_split "tls_gd_sysv" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) +(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 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) + (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" { @@ -9491,64 +9485,64 @@ (define_insn_and_split "tls_gd_sysv" } "&& TARGET_TLS_MARKERS" [(set (match_dup 0) - (unspec:TLSmode [(match_dup 1) - (match_dup 2)] - UNSPEC_TLSGD)) + (unspec:P [(match_dup 1) + (match_dup 2)] + UNSPEC_TLSGD)) (parallel [(set (match_dup 0) - (call (mem:TLSmode (match_dup 3)) - (match_dup 4))) - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) + (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:TLSmode 0 "gpc_reg_operand" "=b") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD))] +(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_TLSGD))] "HAVE_AS_TLS && TARGET_TLS_MARKERS" "addi %0,%1,%2@got@tlsgd" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (high:TLSmode - (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) + (high:P + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) (set (match_dup 0) - (lo_sum:TLSmode (match_dup 3) - (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))] + (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); } [(set (attr "length") (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 8) - (const_int 4)))]) - -(define_insn "*tls_gd_high" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD)))] + (const_int 8) + (const_int 4)))]) + +(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_TLSGD)))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@tlsgd@ha") -(define_insn "*tls_gd_low" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD)))] +(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_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:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) +(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 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) + (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)" @@ -9558,12 +9552,12 @@ (define_insn "*tls_gd_call_aix" [(set_attr "type" "branch") (set_attr "length" "8")]) -(define_insn "*tls_gd_call_sysv" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) +(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 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) + (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" { @@ -9571,12 +9565,12 @@ (define_insn "*tls_gd_call_sysv" } [(set_attr "type" "branch")]) -(define_insn_and_split "tls_ld_aix" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) +(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 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] - UNSPEC_TLSLD) + (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)" { @@ -9589,26 +9583,26 @@ (define_insn_and_split "tls_ld_aix" } "&& TARGET_TLS_MARKERS" [(set (match_dup 0) - (unspec:TLSmode [(match_dup 1)] - UNSPEC_TLSLD)) + (unspec:P [(match_dup 1)] + UNSPEC_TLSLD)) (parallel [(set (match_dup 0) - (call (mem:TLSmode (match_dup 2)) - (match_dup 3))) - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) + (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)))]) + (const_int 16) + (const_int 12)))]) -(define_insn_and_split "tls_ld_sysv" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) +(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 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] - UNSPEC_TLSLD) + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] + UNSPEC_TLSLD) (clobber (reg:SI LR_REGNO))] "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" { @@ -9617,60 +9611,60 @@ (define_insn_and_split "tls_ld_sysv" } "&& TARGET_TLS_MARKERS" [(set (match_dup 0) - (unspec:TLSmode [(match_dup 1)] - UNSPEC_TLSLD)) + (unspec:P [(match_dup 1)] + UNSPEC_TLSLD)) (parallel [(set (match_dup 0) - (call (mem:TLSmode (match_dup 2)) - (match_dup 3))) - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) + (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:TLSmode 0 "gpc_reg_operand" "=b") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] - UNSPEC_TLSLD))] +(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")] + UNSPEC_TLSLD))] "HAVE_AS_TLS && TARGET_TLS_MARKERS" "addi %0,%1,%&@got@tlsld" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 2) - (high:TLSmode - (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD))) + (high:P + (unspec:P [(const_int 0) (match_dup 1)] UNSPEC_TLSLD))) (set (match_dup 0) - (lo_sum:TLSmode (match_dup 2) - (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))] + (lo_sum:P (match_dup 2) + (unspec:P [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))] { operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); } [(set (attr "length") (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 8) - (const_int 4)))]) - -(define_insn "*tls_ld_high" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (high:TLSmode - (unspec:TLSmode [(const_int 0) - (match_operand:TLSmode 1 "gpc_reg_operand" "b")] - UNSPEC_TLSLD)))] + (const_int 8) + (const_int 4)))]) + +(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_TLSLD)))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%&@got@tlsld@ha") -(define_insn "*tls_ld_low" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (unspec:TLSmode [(const_int 0) - (match_operand:TLSmode 2 "gpc_reg_operand" "b")] - UNSPEC_TLSLD)))] +(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_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:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) +(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 "" "g"))) - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) + (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)" @@ -9680,11 +9674,11 @@ (define_insn "*tls_ld_call_aix" [(set_attr "type" "branch") (set_attr "length" "8")]) -(define_insn "*tls_ld_call_sysv" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) +(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 "" "g"))) - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) + (unspec:P [(const_int 0)] UNSPEC_TLSLD) (clobber (reg:SI LR_REGNO))] "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" { @@ -9692,142 +9686,142 @@ (define_insn "*tls_ld_call_sysv" } [(set_attr "type" "branch")]) -(define_insn "tls_dtprel_" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSDTPREL))] +(define_insn "tls_dtprel_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPREL))] "HAVE_AS_TLS" "addi %0,%1,%2@dtprel") -(define_insn "tls_dtprel_ha_" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSDTPRELHA))] +(define_insn "tls_dtprel_ha_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPRELHA))] "HAVE_AS_TLS" "addis %0,%1,%2@dtprel@ha") -(define_insn "tls_dtprel_lo_" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSDTPRELLO))] +(define_insn "tls_dtprel_lo_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPRELLO))] "HAVE_AS_TLS" "addi %0,%1,%2@dtprel@l") -(define_insn_and_split "tls_got_dtprel_" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTDTPREL))] +(define_insn_and_split "tls_got_dtprel_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTDTPREL))] "HAVE_AS_TLS" - "l %0,%2@got@dtprel(%1)" + " %0,%2@got@dtprel(%1)" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (high:TLSmode - (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) + (high:P + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) (set (match_dup 0) - (lo_sum:TLSmode (match_dup 3) - (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))] + (lo_sum:P (match_dup 3) + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))] { operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); } [(set (attr "length") (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 8) - (const_int 4)))]) - -(define_insn "*tls_got_dtprel_high" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTDTPREL)))] + (const_int 8) + (const_int 4)))]) + +(define_insn "*tls_got_dtprel_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_TLSGOTDTPREL)))] "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@dtprel@ha") -(define_insn "*tls_got_dtprel_low" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTDTPREL)))] +(define_insn "*tls_got_dtprel_low" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (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_TLSGOTDTPREL)))] "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" - "l %0,%2@got@dtprel@l(%1)") + " %0,%2@got@dtprel@l(%1)") -(define_insn "tls_tprel_" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSTPREL))] +(define_insn "tls_tprel_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPREL))] "HAVE_AS_TLS" "addi %0,%1,%2@tprel") -(define_insn "tls_tprel_ha_" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSTPRELHA))] +(define_insn "tls_tprel_ha_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPRELHA))] "HAVE_AS_TLS" "addis %0,%1,%2@tprel@ha") -(define_insn "tls_tprel_lo_" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSTPRELLO))] +(define_insn "tls_tprel_lo_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPRELLO))] "HAVE_AS_TLS" "addi %0,%1,%2@tprel@l") ;; "b" output constraint here and on tls_tls input to support linker tls ;; optimization. The linker may edit the instructions emitted by a ;; tls_got_tprel/tls_tls pair to addis,addi. -(define_insn_and_split "tls_got_tprel_" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTTPREL))] +(define_insn_and_split "tls_got_tprel_" + [(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_TLSGOTTPREL))] "HAVE_AS_TLS" - "l %0,%2@got@tprel(%1)" + " %0,%2@got@tprel(%1)" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (high:TLSmode - (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) + (high:P + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) (set (match_dup 0) - (lo_sum:TLSmode (match_dup 3) - (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))] + (lo_sum:P (match_dup 3) + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))] { operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); } [(set (attr "length") (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 8) - (const_int 4)))]) - -(define_insn "*tls_got_tprel_high" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTTPREL)))] + (const_int 8) + (const_int 4)))]) + +(define_insn "*tls_got_tprel_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_TLSGOTTPREL)))] "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@tprel@ha") -(define_insn "*tls_got_tprel_low" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTTPREL)))] +(define_insn "*tls_got_tprel_low" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (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_TLSGOTTPREL)))] "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" - "l %0,%2@got@tprel@l(%1)") + " %0,%2@got@tprel@l(%1)") -(define_insn "tls_tls_" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSTLS))] +(define_insn "tls_tls_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTLS))] "TARGET_ELF && HAVE_AS_TLS" "add %0,%1,%2@tls") From patchwork Tue Nov 13 12:51:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 997084 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-489879-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="jY+nVL/7"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="rbq6M9p9"; 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 42vSF10CWWz9s9G for ; Tue, 13 Nov 2018 23:51:48 +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=dXSf7wjcRBVwQu+/g 0w2lG1HIWmhSJ2DH72myXE0GCR4ifttf5pBPFUf4x86z2v8Pd6/w7eeH7gAPVoCR pKhhWZL/NfpRcyBZRc/zL8kZ2HYVhEj+WypjSJxQ/a9kbKIjnsWCxd/vnJ+xoVyt V3UegYK4zwYLrG9dtYLvxXdcqw= 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=CxMfuayqCMrsMroCErR/kki CmIU=; b=jY+nVL/7WaJ4vCNMO3YqYlb/MJ7ElmwN8Xt3esxJchWamASv+B8YYCJ MBWBMeyc47mHcZwfYJsTWmT4R6ZTwxpOADuBywht2lQQojVW4rLxVBPpo1qgDh2J +PhQUa8QRxB8P+7pR6614/j0/xarXNXlQhg9fBy2Ruiu+0hqdX04= Received: (qmail 70605 invoked by alias); 13 Nov 2018 12:51:41 -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 70595 invoked by uid 89); 13 Nov 2018 12:51:39 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=ss, rr, sc X-HELO: mail-pl1-f182.google.com Received: from mail-pl1-f182.google.com (HELO mail-pl1-f182.google.com) (209.85.214.182) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Nov 2018 12:51:37 +0000 Received: by mail-pl1-f182.google.com with SMTP id p6-v6so5979052pll.4 for ; Tue, 13 Nov 2018 04:51:36 -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=FEr2bx4RyMwGVKG67a31iXaIQjE/PSbNYAydn1fl55w=; b=rbq6M9p97re9/oprj4o1k4+ye7keUqsK2TLhCZJ9eXsEH3tvLl7RQklBb1WfTxKUCL KC7+vY+QjpOn3/8tjCw8hVmwBdASSxPynJIjxjEnpncQ00BCVnkxadLs8fK5JfvI1W8P 02P5JAkTyyOHsTWf77uZ+8azcpV3JBPhxY+A8YYO+Osn3bRHSJ8/HWNuJiEH6dJIqJfI 5zK02utCOp/ohrmXeRX5uHh4HgNop1kk5/J1jYMCV0yg4zVI6NGqpLpxoE3WScyQYTNl K/grpDaBw7GQPhFGm5hv1oohq7Xgl0pwps9YQnSRkYbyDw+SjWIxIzQLHY5sGL4vV+Pz V0Hw== Received: from bubble.grove.modra.org ([58.175.241.133]) by smtp.gmail.com with ESMTPSA id k70-v6sm22926634pfc.76.2018.11.13.04.51.33 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Nov 2018 04:51:34 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id AC172805EE; Tue, 13 Nov 2018 23:21:30 +1030 (ACDT) Date: Tue, 13 Nov 2018 23:21:30 +1030 From: Alan Modra To: Segher Boessenkool Cc: gcc-patches@gcc.gnu.org Subject: [PATCH 4/6] [RS6000] Remove constraints on call rounded_stack_size_rtx arg Message-ID: <20181113125130.GT29784@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. (Same as before, here for completeness.) This call arg is unused on rs6000. * config/rs6000/darwin.md (call_indirect_nonlocal_darwin64), (call_nonlocal_darwin64, call_value_indirect_nonlocal_darwin64), (call_value_nonlocal_darwin64): Remove constraints from second call arg, the rounded_stack_size_rtx arg. * 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_local32, call_local64, call_value_local32), (call_value_local64, call_indirect_nonlocal_sysv), (call_nonlocal_sysv, call_nonlocal_sysv_secure), (call_value_indirect_nonlocal_sysv, call_value_nonlocal_sysv), (call_value_nonlocal_sysv_secure, call_local_aix), (call_value_local_aix, call_nonlocal_aix, call_value_nonlocal_aix), (call_indirect_aix, call_value_indirect_aix, call_indirect_elfv2), (call_value_indirect_elfv2, sibcall_local32, sibcall_local64), (sibcall_value_local32, sibcall_value_local64, sibcall_aix), (sibcall_value_aix): Likewise. diff --git a/gcc/config/rs6000/darwin.md b/gcc/config/rs6000/darwin.md index 2d6d1ca57dd..a1c07702d6f 100644 --- a/gcc/config/rs6000/darwin.md +++ b/gcc/config/rs6000/darwin.md @@ -302,7 +302,7 @@ (define_insn "macho_correct_pic_di" (define_insn "*call_indirect_nonlocal_darwin64" [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l,c,*l")) - (match_operand 1 "" "g,g,g,g")) + (match_operand 1)) (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) (clobber (reg:SI LR_REGNO))] "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT" @@ -314,7 +314,7 @@ (define_insn "*call_indirect_nonlocal_darwin64" (define_insn "*call_nonlocal_darwin64" [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s")) - (match_operand 1 "" "g,g")) + (match_operand 1)) (use (match_operand:SI 2 "immediate_operand" "O,n")) (clobber (reg:SI LR_REGNO))] "(DEFAULT_ABI == ABI_DARWIN) @@ -332,7 +332,7 @@ (define_insn "*call_nonlocal_darwin64" (define_insn "*call_value_indirect_nonlocal_darwin64" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:DI 1 "register_operand" "c,*l,c,*l")) - (match_operand 2 "" "g,g,g,g"))) + (match_operand 2))) (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) (clobber (reg:SI LR_REGNO))] "DEFAULT_ABI == ABI_DARWIN" @@ -345,7 +345,7 @@ (define_insn "*call_value_indirect_nonlocal_darwin64" (define_insn "*call_value_nonlocal_darwin64" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s")) - (match_operand 2 "" "g,g"))) + (match_operand 2))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (clobber (reg:SI LR_REGNO))] "(DEFAULT_ABI == ABI_DARWIN) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 793a0a9d840..c261c8bb9c1 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -9439,7 +9439,7 @@ (define_peephole2 (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 "" "g"))) + (match_operand 4))) (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") (match_operand:P 2 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSGD) @@ -9473,7 +9473,7 @@ (define_insn_and_split "tls_gd_aix" (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 "" "g"))) + (match_operand 4))) (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") (match_operand:P 2 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSGD) @@ -9540,7 +9540,7 @@ (define_insn "*tls_gd_low" (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 "" "g"))) + (match_operand 2))) (unspec:P [(match_operand:P 3 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSGD) (clobber (reg:SI LR_REGNO))] @@ -9555,7 +9555,7 @@ (define_insn "*tls_gd_call_aix" (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 "" "g"))) + (match_operand 2))) (unspec:P [(match_operand:P 3 "rs6000_tls_symbol_ref" "")] UNSPEC_TLSGD) (clobber (reg:SI LR_REGNO))] @@ -9568,7 +9568,7 @@ (define_insn "*tls_gd_call_sysv" (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 "" "g"))) + (match_operand 3))) (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] UNSPEC_TLSLD) (clobber (reg:SI LR_REGNO))] @@ -9600,7 +9600,7 @@ (define_insn_and_split "tls_ld_aix" (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 "" "g"))) + (match_operand 3))) (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] UNSPEC_TLSLD) (clobber (reg:SI LR_REGNO))] @@ -9663,7 +9663,7 @@ (define_insn "*tls_ld_low" (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 "" "g"))) + (match_operand 2))) (unspec:P [(const_int 0)] UNSPEC_TLSLD) (clobber (reg:SI LR_REGNO))] "HAVE_AS_TLS && TARGET_TLS_MARKERS @@ -9677,7 +9677,7 @@ (define_insn "*tls_ld_call_aix" (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 "" "g"))) + (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" @@ -10439,7 +10439,7 @@ (define_expand "call_value" (define_insn "*call_local32" [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) - (match_operand 1 "" "g,g")) + (match_operand 1)) (use (match_operand:SI 2 "immediate_operand" "O,n")) (clobber (reg:SI LR_REGNO))] "(INTVAL (operands[2]) & CALL_LONG) == 0" @@ -10457,7 +10457,7 @@ (define_insn "*call_local32" (define_insn "*call_local64" [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) - (match_operand 1 "" "g,g")) + (match_operand 1)) (use (match_operand:SI 2 "immediate_operand" "O,n")) (clobber (reg:SI LR_REGNO))] "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" @@ -10476,7 +10476,7 @@ (define_insn "*call_local64" (define_insn "*call_value_local32" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) - (match_operand 2 "" "g,g"))) + (match_operand 2))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (clobber (reg:SI LR_REGNO))] "(INTVAL (operands[3]) & CALL_LONG) == 0" @@ -10496,7 +10496,7 @@ (define_insn "*call_value_local32" (define_insn "*call_value_local64" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) - (match_operand 2 "" "g,g"))) + (match_operand 2))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (clobber (reg:SI LR_REGNO))] "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" @@ -10521,7 +10521,7 @@ (define_insn "*call_value_local64" (define_insn "*call_indirect_nonlocal_sysv" [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l")) - (match_operand 1 "" "g,g,g,g")) + (match_operand 1)) (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) (clobber (reg:SI LR_REGNO))] "DEFAULT_ABI == ABI_V4 @@ -10550,7 +10550,7 @@ (define_insn "*call_indirect_nonlocal_sysv" (define_insn_and_split "*call_nonlocal_sysv" [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) - (match_operand 1 "" "g,g")) + (match_operand 1)) (use (match_operand:SI 2 "immediate_operand" "O,n")) (clobber (reg:SI LR_REGNO))] "(DEFAULT_ABI == ABI_DARWIN @@ -10585,7 +10585,7 @@ (define_insn_and_split "*call_nonlocal_sysv" (define_insn "*call_nonlocal_sysv_secure" [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) - (match_operand 1 "" "g,g")) + (match_operand 1)) (use (match_operand:SI 2 "immediate_operand" "O,n")) (use (match_operand:SI 3 "register_operand" "r,r")) (clobber (reg:SI LR_REGNO))] @@ -10607,7 +10607,7 @@ (define_insn "*call_nonlocal_sysv_secure" (define_insn "*call_value_indirect_nonlocal_sysv" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l")) - (match_operand 2 "" "g,g,g,g"))) + (match_operand 2))) (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) (clobber (reg:SI LR_REGNO))] "DEFAULT_ABI == ABI_V4 @@ -10637,7 +10637,7 @@ (define_insn "*call_value_indirect_nonlocal_sysv" (define_insn_and_split "*call_value_nonlocal_sysv" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) - (match_operand 2 "" "g,g"))) + (match_operand 2))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (clobber (reg:SI LR_REGNO))] "(DEFAULT_ABI == ABI_DARWIN @@ -10674,7 +10674,7 @@ (define_insn_and_split "*call_value_nonlocal_sysv" (define_insn "*call_value_nonlocal_sysv_secure" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) - (match_operand 2 "" "g,g"))) + (match_operand 2))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (use (match_operand:SI 4 "register_operand" "r,r")) (clobber (reg:SI LR_REGNO))] @@ -10698,7 +10698,7 @@ (define_insn "*call_value_nonlocal_sysv_secure" (define_insn "*call_local_aix" [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s")) - (match_operand 1 "" "g")) + (match_operand 1)) (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" "bl %z0" @@ -10707,7 +10707,7 @@ (define_insn "*call_local_aix" (define_insn "*call_value_local_aix" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s")) - (match_operand 2 "" "g"))) + (match_operand 2))) (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" "bl %z1" @@ -10718,7 +10718,7 @@ (define_insn "*call_value_local_aix" (define_insn "*call_nonlocal_aix" [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s")) - (match_operand 1 "" "g")) + (match_operand 1)) (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" { @@ -10730,7 +10730,7 @@ (define_insn "*call_nonlocal_aix" (define_insn "*call_value_nonlocal_aix" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) - (match_operand 2 "" "g"))) + (match_operand 2))) (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" { @@ -10746,7 +10746,7 @@ (define_insn "*call_value_nonlocal_aix" (define_insn "*call_indirect_aix" [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) - (match_operand 1 "" "g,g")) + (match_operand 1)) (use (match_operand:P 2 "memory_operand" ",")) (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] @@ -10764,7 +10764,7 @@ (define_insn "*call_indirect_aix" (define_insn "*call_value_indirect_aix" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) - (match_operand 2 "" "g,g"))) + (match_operand 2))) (use (match_operand:P 3 "memory_operand" ",")) (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] @@ -10785,7 +10785,7 @@ (define_insn "*call_value_indirect_aix" (define_insn "*call_indirect_elfv2" [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) - (match_operand 1 "" "g,g")) + (match_operand 1)) (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_ELFv2" @@ -10802,7 +10802,7 @@ (define_insn "*call_indirect_elfv2" (define_insn "*call_value_indirect_elfv2" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) - (match_operand 2 "" "g,g"))) + (match_operand 2))) (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_ELFv2" @@ -10895,7 +10895,7 @@ (define_expand "sibcall_value" (define_insn "*sibcall_local32" [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) - (match_operand 1 "" "g,g")) + (match_operand 1)) (use (match_operand:SI 2 "immediate_operand" "O,n")) (simple_return)] "(INTVAL (operands[2]) & CALL_LONG) == 0" @@ -10913,7 +10913,7 @@ (define_insn "*sibcall_local32" (define_insn "*sibcall_local64" [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) - (match_operand 1 "" "g,g")) + (match_operand 1)) (use (match_operand:SI 2 "immediate_operand" "O,n")) (simple_return)] "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" @@ -10932,7 +10932,7 @@ (define_insn "*sibcall_local64" (define_insn "*sibcall_value_local32" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) - (match_operand 2 "" "g,g"))) + (match_operand 2))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (simple_return)] "(INTVAL (operands[3]) & CALL_LONG) == 0" @@ -10951,7 +10951,7 @@ (define_insn "*sibcall_value_local32" (define_insn "*sibcall_value_local64" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) - (match_operand 2 "" "g,g"))) + (match_operand 2))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (simple_return)] "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" @@ -11044,7 +11044,7 @@ (define_insn "*sibcall_value_nonlocal_sysv" (define_insn "*sibcall_aix" [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) - (match_operand 1 "" "g,g")) + (match_operand 1)) (simple_return)] "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" { @@ -11058,7 +11058,7 @@ (define_insn "*sibcall_aix" (define_insn "*sibcall_value_aix" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) - (match_operand 2 "" "g,g"))) + (match_operand 2))) (simple_return)] "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" { 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"; } From patchwork Tue Nov 13 12:53: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: 997087 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-489881-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="niXLUvIk"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="PN1drWx4"; 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 42vSHf4532z9s9G for ; Tue, 13 Nov 2018 23:54:06 +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=D5TEJJCaPcFJjypEr kI9Zrrd263XOSS7v0XWmSTn/WnaehC+vhP4JNFeMEhOGjDugRURvqQ1Y6ESPOMkX yHf7xrkafTOw2fY9mXJVFfAtHMTRN77NbRt85BfoeOwUkL1pyBKH+9KqX8i2mEUp pzrow8p9k2cJJoRXF1I2rrPzIk= 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=OOH8suIJ9eykjoe6SizZlgB 1wLY=; b=niXLUvIksC63m+Z2weLRXs0hQ0Nkhl7AdKS+DssUMndj234rOLmHtSo PJ+mT/WmNovJqJhJStPbBuPPNb9Cdmwv78LyZja4qE3t5MXfMnWCL0uxIrLbT9wV Ywy/slPhthx4QSDzzcFNYRX/sY4w8ZNAaMSeV9eBaSXK77Scemko= Received: (qmail 75473 invoked by alias); 13 Nov 2018 12:53:58 -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 75455 invoked by uid 89); 13 Nov 2018 12:53:56 -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=WHICH X-HELO: mail-pg1-f180.google.com Received: from mail-pg1-f180.google.com (HELO mail-pg1-f180.google.com) (209.85.215.180) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Nov 2018 12:53:51 +0000 Received: by mail-pg1-f180.google.com with SMTP id w7so5642555pgp.13 for ; Tue, 13 Nov 2018 04:53: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=RThaw8BOE3jFf1fXmlq+L/xwFHFhYP58ib4onEyUECk=; b=PN1drWx4ypErn2r1N0qBewd1+O12Pxzo0WQpKh9Tt8EYDVflWgNRB5UmD2iUd8XAOw soZeWpQyz4TyNlZOjycRl0GG1bT9KnDZpr1U6IZZMrqB7uLNAFx//cWQtx660bzB7HyE kTz4XI9FMO4Ui5VfxiTC6dItkfS7k/U/ROMRtWaLnims5CdXK89D7Xn8Lj5VlOpu79Bz ygbrxlwig7RDMQpxESK29/9IkWjoaDsL1LCMsLTkpSSws9S7BF3eEjhkWUxs5C2rhEJD i/l5S5CW5plkYFRS8iW2/AOE500PefGxoij7eDap1EY5j8tXIEAGTJ3YznbxRk+kWiRM Zgww== Received: from bubble.grove.modra.org ([58.175.241.133]) by smtp.gmail.com with ESMTPSA id l2-v6sm17932741pgp.20.2018.11.13.04.53.46 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 13 Nov 2018 04:53:47 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id EEF99805EE; Tue, 13 Nov 2018 23:23:43 +1030 (ACDT) Date: Tue, 13 Nov 2018 23:23:43 +1030 From: Alan Modra To: Segher Boessenkool Cc: gcc-patches@gcc.gnu.org Subject: [PATCH 6/6] [RS6000] inline plt call sequences Message-ID: <20181113125343.GV29784@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. Finally, the point of the previous patches in this series, support for inline PLT calls, keyed off -fno-plt. This emits code using new relocations that tie all insns in the sequence together, so that the linker can edit the sequence back to a direct call should the call target turn out to be local. An example of ELFv2 code to call puts is as follows: .reloc .,R_PPC64_PLTSEQ,puts std 2,24(1) .reloc .,R_PPC64_PLT16_HA,puts addis 12,2,0 .reloc .,R_PPC64_PLT16_LO_DS,puts ld 12,0(12) .reloc .,R_PPC64_PLTSEQ,puts mtctr 12 .reloc .,R_PPC64_PLTCALL,puts bctrl ld 2,24(1) "addis 12,2,puts@plt@ha" and "ld 12,puts@plt@l(12)" are also supported by the assembler. gcc instead uses the explicit R_PPC64_PLT16_HA and R_PPC64_PLT16_LO_DS relocs because when the call is to __tls_get_addr an extra reloc is emitted at every place where one is shown above, to specify the __tls_get_addr arg. The linker expects the extra reloc to come first. .reloc enforces that ordering. The patch also changes code emitted for longcalls if the assembler supports the new marker relocs, so that these too can be edited. One side effect of longcalls using PLT16 relocs is that they can now be resolved lazily by ld.so. I don't support lazy inline PLT calls for ELFv1, because ELFv1 would need barriers to reliably load both the function address and toc pointer from the PLT. ELFv1 -fno-plt uses the longcall sequence instead, which isn't edited by GNU ld. * config.in (HAVE_AS_PLTSEQ): Add. * config/rs6000/predicates.md (indirect_call_operand): New. * config/rs6000/rs6000-protos.h (rs6000_pltseq_template), (rs6000_sibcall_sysv): Declare. * config/rs6000/rs6000.c (init_cumulative_args): Set cookie CALL_LONG for -fno-plt. (print_operand ): Handle UNSPEC_PLTSEQ. (rs6000_indirect_call_template_1): Emit .reloc directives for UNSPEC_PLTSEQ calls. (rs6000_pltseq_template): New function. (rs6000_longcall_ref): Add arg parameter. Use PLT16 insns if relocs supported by assembler. Move SYMBOL_REF test to callers. (rs6000_call_aix): Adjust rs6000_longcall_ref call. Package insns in UNSPEC_PLTSEQ, preserving original func_desc. (rs6000_call_sysv): Likewise. (rs6000_sibcall_sysv): New function. * config/rs6000/rs6000.h (HAVE_AS_PLTSEQ): Provide default. * config/rs6000/rs6000.md (UNSPEC_PLTSEQ, UNSPEC_PLT16_HA, UNSPEC_PLT16_LO): New. (pltseq_tocsave, pltseq_plt16_ha, pltseq_plt16_lo, pltseq_mtctr): New. (call_indirect_nonlocal_sysv): Don't differentiate zero from non-zero cookie in constraints. Test explicitly for flags in length attr. Handle unspec operand 1. (call_value_indirect_nonlocal_sysv): Likewise. (call_indirect_aix, call_value_indirect_aix): Handle unspec operand 1. (call_indirect_elfv2, call_value_indirect_elfv2): Likewise. (sibcall, sibcall_value): Use rs6000_sibcall_sysv. (sibcall_indirect_nonlocal_sysv): New pattern. (sibcall_value_indirect_nonlocal_sysv): Likewise. (sibcall_nonlocal_sysv, sibcall_value_nonlocal_sysv): Remove indirect call alternatives. * configure.ac: Check for gas plt sequence marker support. * configure: Regenerate. diff --git a/gcc/config.in b/gcc/config.in index 67a1e6cfc4c..86ff5e8636b 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -577,6 +577,12 @@ #endif +/* Define if your assembler supports R_PPC*_PLTSEQ relocations. */ +#ifndef USED_FOR_TARGET +#undef HAVE_AS_PLTSEQ +#endif + + /* Define if your assembler supports .ref */ #ifndef USED_FOR_TARGET #undef HAVE_AS_REF diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 7e45d2f0371..1af01935b5e 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1055,6 +1055,24 @@ (define_predicate "call_operand" || REGNO (op) >= FIRST_PSEUDO_REGISTER") (match_code "symbol_ref"))) +;; Return 1 if the operand, used inside a MEM, is a valid first argument +;; to an indirect CALL. This is LR, CTR, or a PLTSEQ unspec using CTR. +(define_predicate "indirect_call_operand" + (match_code "reg,unspec") +{ + if (REG_P (op)) + return (REGNO (op) == LR_REGNO + || REGNO (op) == CTR_REGNO); + if (GET_CODE (op) == UNSPEC) + { + if (XINT (op, 1) != UNSPEC_PLTSEQ) + return false; + op = XVECEXP (op, 0, 0); + return REG_P (op) && REGNO (op) == CTR_REGNO; + } + return false; +}) + ;; Return 1 if the operand is a SYMBOL_REF for a function known to be in ;; this file. (define_predicate "current_file_function_operand" diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 3fd89dc20db..35209d4525d 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -115,6 +115,7 @@ 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 const char *rs6000_pltseq_template (rtx *, int); extern enum rtx_code rs6000_reverse_condition (machine_mode, enum rtx_code); extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx); @@ -204,6 +205,7 @@ 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_sibcall_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 5fd6e17bdda..c4008a87ed7 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -10706,7 +10706,7 @@ void init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname ATTRIBUTE_UNUSED, int incoming, int libcall, int n_named_args, - tree fndecl ATTRIBUTE_UNUSED, + tree fndecl, machine_mode return_mode ATTRIBUTE_UNUSED) { static CUMULATIVE_ARGS zero_cumulative; @@ -10727,10 +10727,20 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, cum->nargs_prototype = n_named_args; /* Check for a longcall attribute. */ - if ((!fntype && rs6000_default_long_calls) - || (fntype - && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)) - && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))) + if (((!fntype && rs6000_default_long_calls) + || (fntype + && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)) + && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))) + || (DEFAULT_ABI != ABI_DARWIN + && !(fndecl + && !DECL_EXTERNAL (fndecl) + && !DECL_WEAK (fndecl) + && (*targetm.binds_local_p) (fndecl)) + && (flag_plt + ? (fntype + && lookup_attribute ("noplt", TYPE_ATTRIBUTES (fntype))) + : !(fntype + && lookup_attribute ("plt", TYPE_ATTRIBUTES (fntype)))))) cum->call_cookie |= CALL_LONG; if (TARGET_DEBUG_ARG) @@ -20955,6 +20965,8 @@ print_operand (FILE *file, rtx x, int code) case 'T': /* Print the symbolic name of a branch target register. */ + if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PLTSEQ) + x = XVECEXP (x, 0, 0); if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO && REGNO (x) != CTR_REGNO)) output_operand_lossage ("invalid %%T value"); @@ -21098,6 +21110,8 @@ print_operand (FILE *file, rtx x, int code) return; case 'z': + if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PLTSEQ) + x = XVECEXP (x, 0, 1); /* X is a SYMBOL_REF. Write out the name preceded by a period and without any trailing data in brackets. Used for function names. If we are configured for System V (or the embedded ABI) on @@ -21213,6 +21227,8 @@ print_operand (FILE *file, rtx x, int code) 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 (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PLTSEQ) + output_addr_const (file, XVECEXP (x, 0, 1)); else output_addr_const (file, x); return; @@ -21462,9 +21478,15 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop, might produce 10 digits. */ gcc_assert (funop <= MAX_RECOG_OPERANDS); - static char str[144]; + static char str[144]; /* 1 spare */ + char *s = str; const char *ptrload = TARGET_64BIT ? "d" : "wz"; + if (DEFAULT_ABI == ABI_AIX) + s += sprintf (s, + "l%s 2,%%%u\n\t", + ptrload, funop + 2); + /* We don't need the extra code to stop indirect call speculation if calling via LR. */ bool speculate = (TARGET_MACHO @@ -21472,32 +21494,61 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop, || (REG_P (operands[funop]) && REGNO (operands[funop]) == LR_REGNO)); + if (!TARGET_MACHO && HAVE_AS_PLTSEQ && GET_CODE (operands[funop]) == UNSPEC) + { + const char *rel64 = TARGET_64BIT ? "64" : ""; + char tls[29]; + tls[0] = 0; + if (GET_CODE (operands[funop + 1]) == UNSPEC) + { + if (XINT (operands[funop + 1], 1) == UNSPEC_TLSGD) + sprintf (tls, ".reloc .,R_PPC%s_TLSGD,%%%u\n\t", + rel64, funop + 1); + else if (XINT (operands[funop + 1], 1) == UNSPEC_TLSLD) + sprintf (tls, ".reloc .,R_PPC%s_TLSLD,%%&\n\t", + rel64); + else + gcc_unreachable (); + } + + const char *addend = (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT + && flag_pic == 2 ? "+32768" : ""); + if (!speculate) + { + s += sprintf (s, + "%s.reloc .,R_PPC%s_PLTSEQ,%%z%u%s\n\t", + tls, rel64, funop, addend); + s += sprintf (s, "crset 2\n\t"); + } + s += sprintf (s, + "%s.reloc .,R_PPC%s_PLTCALL,%%z%u%s\n\t", + tls, rel64, funop, addend); + } + else if (!speculate) + s += sprintf (s, "crset 2\n\t"); + if (DEFAULT_ABI == ABI_AIX) { if (speculate) - sprintf (str, - "l%s 2,%%%u\n\t" + sprintf (s, "b%%T%ul\n\t" "l%s 2,%%%u(1)", - ptrload, funop + 2, funop, ptrload, funop + 3); + funop, ptrload, funop + 3); else - sprintf (str, - "crset 2\n\t" - "l%s 2,%%%u\n\t" + sprintf (s, "beq%%T%ul-\n\t" "l%s 2,%%%u(1)", - ptrload, funop + 2, funop, ptrload, funop + 3); + funop, ptrload, funop + 3); } else if (DEFAULT_ABI == ABI_ELFv2) { if (speculate) - sprintf (str, + sprintf (s, "b%%T%ul\n\t" "l%s 2,%%%u(1)", funop, ptrload, funop + 2); else - sprintf (str, - "crset 2\n\t" + sprintf (s, "beq%%T%ul-\n\t" "l%s 2,%%%u(1)", funop, ptrload, funop + 2); @@ -21505,12 +21556,11 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop, else { if (speculate) - sprintf (str, + sprintf (s, "b%%T%u%s", funop, sibcall ? "" : "l"); else - sprintf (str, - "crset 2\n\t" + sprintf (s, "beq%%T%u%s-%s", funop, sibcall ? "" : "l", sibcall ? "\n\tb $" : ""); } @@ -21529,6 +21579,72 @@ rs6000_indirect_sibcall_template (rtx *operands, unsigned int funop) return rs6000_indirect_call_template_1 (operands, funop, true); } +#if HAVE_AS_PLTSEQ +/* Output indirect call insns. + WHICH is 0 for tocsave, 1 for plt16_ha, 2 for plt16_lo, 3 for mtctr. */ +const char * +rs6000_pltseq_template (rtx *operands, int which) +{ + const char *rel64 = TARGET_64BIT ? "64" : ""; + char tls[28]; + tls[0] = 0; + if (GET_CODE (operands[3]) == UNSPEC) + { + if (XINT (operands[3], 1) == UNSPEC_TLSGD) + sprintf (tls, ".reloc .,R_PPC%s_TLSGD,%%3\n\t", + rel64); + else if (XINT (operands[3], 1) == UNSPEC_TLSLD) + sprintf (tls, ".reloc .,R_PPC%s_TLSLD,%%&\n\t", + rel64); + else + gcc_unreachable (); + } + + gcc_assert (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4); + static char str[96]; /* 15 spare */ + const char *off = WORDS_BIG_ENDIAN ? "+2" : ""; + const char *addend = (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT + && flag_pic == 2 ? "+32768" : ""); + switch (which) + { + case 0: + sprintf (str, + "%s.reloc .,R_PPC%s_PLTSEQ,%%z2\n\t" + "st%s", + tls, rel64, TARGET_64BIT ? "d 2,24(1)" : "w 2,12(1)"); + break; + case 1: + if (DEFAULT_ABI == ABI_V4 && !flag_pic) + sprintf (str, + "%s.reloc .%s,R_PPC%s_PLT16_HA,%%z2\n\t" + "lis %%0,0", + tls, off, rel64); + else + sprintf (str, + "%s.reloc .%s,R_PPC%s_PLT16_HA,%%z2%s\n\t" + "addis %%0,%%1,0", + tls, off, rel64, addend); + break; + case 2: + sprintf (str, + "%s.reloc .%s,R_PPC%s_PLT16_LO%s,%%z2%s\n\t" + "l%s %%0,0(%%1)", + tls, off, rel64, TARGET_64BIT ? "_DS" : "", addend, + TARGET_64BIT ? "d" : "wz"); + break; + case 3: + sprintf (str, + "%s.reloc .,R_PPC%s_PLTSEQ,%%z2%s\n\t" + "mtctr %%1", + tls, rel64, addend); + break; + default: + gcc_unreachable (); + } + return str; +} +#endif + #if defined (HAVE_GAS_HIDDEN) && !TARGET_MACHO /* Emit an assembler directive to set symbol visibility for DECL to VISIBILITY_TYPE. */ @@ -32540,11 +32656,8 @@ rs6000_set_default_type_attributes (tree type) longcall attribute. */ static rtx -rs6000_longcall_ref (rtx call_ref) +rs6000_longcall_ref (rtx call_ref, rtx arg) { - if (GET_CODE (call_ref) != SYMBOL_REF) - return call_ref; - /* System V adds '.' to the internal name, so skip them. */ const char *call_name = XSTR (call_ref, 0); if (*call_name == '.') @@ -32556,6 +32669,36 @@ rs6000_longcall_ref (rtx call_ref) call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node)); } + if (HAVE_AS_PLTSEQ + && TARGET_TLS_MARKERS + && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)) + { + rtx base = const0_rtx; + int regno; + if (DEFAULT_ABI == ABI_ELFv2) + { + base = gen_rtx_REG (Pmode, TOC_REGISTER); + regno = 12; + } + else + { + if (flag_pic) + base = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); + regno = 11; + } + /* Reg must match that used by linker PLT stubs. For ELFv2, r12 + may be used by a function global entry point. For SysV4, r11 + is used by __glink_PLTresolve lazy resolver entry. */ + rtx reg = gen_rtx_REG (Pmode, regno); + rtx hi = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, base, call_ref, arg), + UNSPEC_PLT16_HA); + rtx lo = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, reg, call_ref, arg), + UNSPEC_PLT16_LO); + emit_insn (gen_rtx_SET (reg, hi)); + emit_insn (gen_rtx_SET (reg, lo)); + return reg; + } + return force_reg (Pmode, call_ref); } @@ -37526,8 +37669,7 @@ chain_already_loaded (rtx_insn *last) void 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); + rtx func = func_desc; rtx toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM); rtx toc_load = NULL_RTX; rtx toc_restore = NULL_RTX; @@ -37541,12 +37683,13 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) tlsarg = global_tlsarg; /* Handle longcall attributes. */ - if (INTVAL (cookie) & CALL_LONG) - func_desc = rs6000_longcall_ref (func_desc); + if ((INTVAL (cookie) & CALL_LONG) != 0 + && GET_CODE (func_desc) == SYMBOL_REF) + func = rs6000_longcall_ref (func_desc, tlsarg); /* Handle indirect calls. */ - if (GET_CODE (func_desc) != SYMBOL_REF - || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (func_desc))) + if (GET_CODE (func) != SYMBOL_REF + || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (func))) { /* Save the TOC into its reserved slot before the call, and prepare to restore it after the call. */ @@ -37567,7 +37710,17 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) gen_rtx_PLUS (Pmode, stack_ptr, stack_toc_offset)); MEM_VOLATILE_P (stack_toc_mem) = 1; - emit_move_insn (stack_toc_mem, toc_reg); + if (HAVE_AS_PLTSEQ + && TARGET_TLS_MARKERS + && DEFAULT_ABI == ABI_ELFv2 + && GET_CODE (func_desc) == SYMBOL_REF) + { + rtvec v = gen_rtvec (3, toc_reg, func_desc, tlsarg); + rtx mark_toc_reg = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ); + emit_insn (gen_rtx_SET (stack_toc_mem, mark_toc_reg)); + } + else + emit_move_insn (stack_toc_mem, toc_reg); } if (DEFAULT_ABI == ABI_ELFv2) @@ -37575,9 +37728,25 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, 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); - if (!rtx_equal_p (func_addr, func_desc)) - emit_move_insn (func_addr, func_desc); + if (!rtx_equal_p (func_addr, func)) + emit_move_insn (func_addr, func); abi_reg = func_addr; + /* Indirect calls via CTR are strongly preferred over indirect + calls via LR, so move the address there. Needed to mark + this insn for linker plt sequence editing too. */ + func_addr = gen_rtx_REG (Pmode, CTR_REGNO); + if (HAVE_AS_PLTSEQ + && TARGET_TLS_MARKERS + && GET_CODE (func_desc) == SYMBOL_REF) + { + rtvec v = gen_rtvec (3, abi_reg, func_desc, tlsarg); + rtx mark_func = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ); + emit_insn (gen_rtx_SET (func_addr, mark_func)); + v = gen_rtvec (2, func_addr, func_desc); + func_addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ); + } + else + emit_move_insn (func_addr, abi_reg); } else { @@ -37589,9 +37758,15 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) not have any executable code. */ /* Load up address of the actual function. */ - func_desc = force_reg (Pmode, func_desc); + func = force_reg (Pmode, func); func_addr = gen_reg_rtx (Pmode); - emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func_desc)); + emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func)); + + /* Indirect calls via CTR are strongly preferred over indirect + calls via LR, so move the address there. */ + rtx ctr_reg = gen_rtx_REG (Pmode, CTR_REGNO); + emit_move_insn (ctr_reg, func_addr); + func_addr = ctr_reg; /* Prepare to load the TOC of the called function. Note that the TOC load must happen immediately before the actual call so @@ -37599,7 +37774,7 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) comment in frob_update_context. */ rtx func_toc_offset = GEN_INT (GET_MODE_SIZE (Pmode)); rtx func_toc_mem = gen_rtx_MEM (Pmode, - gen_rtx_PLUS (Pmode, func_desc, + gen_rtx_PLUS (Pmode, func, func_toc_offset)); toc_load = gen_rtx_USE (VOIDmode, func_toc_mem); @@ -37607,14 +37782,15 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) originally direct, the 3rd word has not been written since no trampoline has been built, so we ought not to load it, lest we override a static chain value. */ - if (!direct_call_p + if (!(GET_CODE (func_desc) == SYMBOL_REF + && SYMBOL_REF_FUNCTION_P (func_desc)) && TARGET_POINTERS_TO_NESTED_FUNCTIONS && !chain_already_loaded (get_current_sequence ()->next->last)) { rtx sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM); rtx func_sc_offset = GEN_INT (2 * GET_MODE_SIZE (Pmode)); rtx func_sc_mem = gen_rtx_MEM (Pmode, - gen_rtx_PLUS (Pmode, func_desc, + gen_rtx_PLUS (Pmode, func, func_sc_offset)); emit_move_insn (sc_reg, func_sc_mem); abi_reg = sc_reg; @@ -37627,7 +37803,7 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) assume the TOC register is set; for non-local calls, the PLT stub needs the TOC register. */ abi_reg = toc_reg; - func_addr = func_desc; + func_addr = func; } /* Create the call. */ @@ -37682,22 +37858,51 @@ rs6000_sibcall_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) /* Expand code to perform a call under the SYSV4 ABI. */ void -rs6000_call_sysv (rtx value, rtx func, rtx tlsarg, rtx cookie) +rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) { + rtx func = func_desc; rtx func_addr; rtx call[3]; rtx insn; + rtx abi_reg = NULL_RTX; if (global_tlsarg) tlsarg = global_tlsarg; /* Handle longcall attributes. */ - if (INTVAL (cookie) & CALL_LONG) - func = rs6000_longcall_ref (func); + if ((INTVAL (cookie) & CALL_LONG) != 0 + && GET_CODE (func_desc) == SYMBOL_REF) + { + func = rs6000_longcall_ref (func_desc, tlsarg); + /* If the longcall was implemented using PLT16 relocs, then r11 + needs to be valid at the call for lazy linking. */ + if (HAVE_AS_PLTSEQ + && TARGET_TLS_MARKERS) + abi_reg = func; + } /* Handle indirect calls. */ if (GET_CODE (func) != SYMBOL_REF) - func_addr = force_reg (Pmode, func); + { + func = force_reg (Pmode, func); + + /* Indirect calls via CTR are strongly preferred over indirect + calls via LR, so move the address there. Needed to mark + this insn for linker plt sequence editing too. */ + func_addr = gen_rtx_REG (Pmode, CTR_REGNO); + if (HAVE_AS_PLTSEQ + && TARGET_TLS_MARKERS + && GET_CODE (func_desc) == SYMBOL_REF) + { + rtvec v = gen_rtvec (3, func, func_desc, tlsarg); + rtx mark_func = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ); + emit_insn (gen_rtx_SET (func_addr, mark_func)); + v = gen_rtvec (2, func_addr, func_desc); + func_addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ); + } + else + emit_move_insn (func_addr, func); + } else func_addr = func; @@ -37713,6 +37918,73 @@ rs6000_call_sysv (rtx value, rtx func, rtx tlsarg, rtx cookie) insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call)); insn = emit_call_insn (insn); + if (abi_reg) + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), abi_reg); +} + +/* Expand code to perform a sibling call under the SysV4 ABI. */ + +void +rs6000_sibcall_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) +{ + rtx func = func_desc; + rtx func_addr; + rtx call[3]; + rtx insn; + rtx abi_reg = NULL_RTX; + + if (global_tlsarg) + tlsarg = global_tlsarg; + + /* Handle longcall attributes. */ + if ((INTVAL (cookie) & CALL_LONG) != 0 + && GET_CODE (func_desc) == SYMBOL_REF) + { + func = rs6000_longcall_ref (func_desc, tlsarg); + /* If the longcall was implemented using PLT16 relocs, then r11 + needs to be valid at the call for lazy linking. */ + if (HAVE_AS_PLTSEQ + && TARGET_TLS_MARKERS) + abi_reg = func; + } + + /* Handle indirect calls. */ + if (GET_CODE (func) != SYMBOL_REF) + { + func = force_reg (Pmode, func); + + /* Indirect sibcalls must go via CTR. Needed to mark + this insn for linker plt sequence editing too. */ + func_addr = gen_rtx_REG (Pmode, CTR_REGNO); + if (HAVE_AS_PLTSEQ + && TARGET_TLS_MARKERS + && GET_CODE (func_desc) == SYMBOL_REF) + { + rtvec v = gen_rtvec (3, func, func_desc, tlsarg); + rtx mark_func = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ); + emit_insn (gen_rtx_SET (func_addr, mark_func)); + v = gen_rtvec (2, func_addr, func_desc); + func_addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ); + } + else + emit_move_insn (func_addr, 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] = simple_return_rtx; + + insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call)); + insn = emit_call_insn (insn); + if (abi_reg) + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), abi_reg); } /* Return whether we need to always update the saved TOC pointer when we update diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index f59c0b6b685..c7934c601ed 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -224,6 +224,10 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #define HAVE_AS_TLS 0 #endif +#ifndef HAVE_AS_PLTSEQ +#define HAVE_AS_PLTSEQ 0 +#endif + #ifndef TARGET_LINK_STACK #define TARGET_LINK_STACK 0 #endif diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 336d42335cb..02f194c7d33 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -147,6 +147,9 @@ (define_c_enum "unspec" UNSPEC_SIGNBIT UNSPEC_SF_FROM_SI UNSPEC_SI_FROM_SF + UNSPEC_PLTSEQ + UNSPEC_PLT16_HA + UNSPEC_PLT16_LO ]) ;; @@ -10231,6 +10234,55 @@ (define_insn "elf_low" (match_operand 2 "" "")))] "TARGET_ELF && !TARGET_64BIT && !flag_pic" "la %0,%2@l(%1)") + +(define_insn "*pltseq_tocsave_" + [(set (match_operand:P 0 "memory_operand" "=m") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "symbol_ref_operand" "s") + (match_operand:P 3 "" "")] + UNSPEC_PLTSEQ))] + "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS + && DEFAULT_ABI == ABI_ELFv2" +{ + return rs6000_pltseq_template (operands, 0); +}) + +(define_insn "*pltseq_plt16_ha_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "" "") + (match_operand:P 2 "symbol_ref_operand" "s") + (match_operand:P 3 "" "")] + UNSPEC_PLT16_HA))] + "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS + && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)" +{ + return rs6000_pltseq_template (operands, 1); +}) + +(define_insn "*pltseq_plt16_lo_" + [(set (match_operand:P 0 "gpc_reg_operand" "=r") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") + (match_operand:P 2 "symbol_ref_operand" "s") + (match_operand:P 3 "" "")] + UNSPEC_PLT16_LO))] + "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS + && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)" +{ + return rs6000_pltseq_template (operands, 2); +} + [(set_attr "type" "load")]) + +(define_insn "*pltseq_mtctr_" + [(set (match_operand:P 0 "register_operand" "=c") + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") + (match_operand:P 2 "symbol_ref_operand" "s") + (match_operand:P 3 "" "")] + UNSPEC_PLTSEQ))] + "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS + && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)" +{ + return rs6000_pltseq_template (operands, 3); +}) ;; Call and call_value insns (define_expand "call" @@ -10387,9 +10439,9 @@ (define_insn "*call_value_local64" ;; which indicates how to set cr1 (define_insn "*call_indirect_nonlocal_sysv" - [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l")) + [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) (match_operand 1)) - (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) + (use (match_operand:SI 2 "immediate_operand" "n,n,n")) (clobber (reg:SI LR_REGNO))] "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN" @@ -10402,18 +10454,17 @@ (define_insn "*call_indirect_nonlocal_sysv" return rs6000_indirect_call_template (operands, 0); } - [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") - (set_attr_alternative "length" - [(if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") - (const_int 0)) - (const_string "8") - (const_string "4")) - (const_string "4") - (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") - (const_int 0)) - (const_string "12") - (const_string "8")) - (const_string "8")])]) + [(set_attr "type" "jmpreg") + (set (attr "length") + (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) + (const_string "12") + (ior (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) + (const_string "8")] + (const_string "4")))]) (define_insn_and_split "*call_nonlocal_sysv" [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) @@ -10473,9 +10524,9 @@ (define_insn "*call_nonlocal_sysv_secure" (define_insn "*call_value_indirect_nonlocal_sysv" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l")) + (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) (match_operand 2))) - (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) + (use (match_operand:SI 3 "immediate_operand" "n,n,n")) (clobber (reg:SI LR_REGNO))] "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN" @@ -10488,18 +10539,17 @@ (define_insn "*call_value_indirect_nonlocal_sysv" return rs6000_indirect_call_template (operands, 1); } - [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") - (set_attr_alternative "length" - [(if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") - (const_int 0)) - (const_string "8") - (const_string "4")) - (const_string "4") - (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") - (const_int 0)) - (const_string "12") - (const_string "8")) - (const_string "8")])]) + [(set_attr "type" "jmpreg") + (set (attr "length") + (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) + (const_string "12") + (ior (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) + (const_string "8")] + (const_string "4")))]) (define_insn_and_split "*call_value_nonlocal_sysv" [(set (match_operand 0 "" "") @@ -10612,10 +10662,10 @@ (define_insn "*call_value_nonlocal_aix" ;; Operand3 is the offset of the stack location holding the current TOC pointer (define_insn "*call_indirect_aix" - [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) + [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) (match_operand 1)) - (use (match_operand:P 2 "memory_operand" ",")) - (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) + (use (match_operand:P 2 "memory_operand" ",,")) + (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_AIX" { @@ -10630,10 +10680,10 @@ (define_insn "*call_indirect_aix" (define_insn "*call_value_indirect_aix" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) + (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) (match_operand 2))) - (use (match_operand:P 3 "memory_operand" ",")) - (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) + (use (match_operand:P 3 "memory_operand" ",,")) + (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_AIX" { @@ -10651,9 +10701,9 @@ (define_insn "*call_value_indirect_aix" ;; Operand2 is the offset of the stack location holding the current TOC pointer (define_insn "*call_indirect_elfv2" - [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) + [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) (match_operand 1)) - (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) + (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_ELFv2" { @@ -10668,9 +10718,9 @@ (define_insn "*call_indirect_elfv2" (define_insn "*call_value_indirect_elfv2" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) + (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) (match_operand 2))) - (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) + (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT)) (clobber (reg:P LR_REGNO))] "DEFAULT_ABI == ABI_ELFv2" { @@ -10733,6 +10783,12 @@ (define_expand "sibcall" rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); DONE; } + + if (DEFAULT_ABI == ABI_V4) + { + rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]); + DONE; + } }) (define_expand "sibcall_value" @@ -10758,6 +10814,12 @@ (define_expand "sibcall_value" rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]); DONE; } + + if (DEFAULT_ABI == ABI_V4) + { + rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]); + DONE; + } }) (define_insn "*sibcall_local32" @@ -10834,10 +10896,38 @@ (define_insn "*sibcall_value_local64" [(set_attr "type" "branch") (set_attr "length" "4,8")]) +(define_insn "*sibcall_indirect_nonlocal_sysv" + [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) + (match_operand 1)) + (use (match_operand:SI 2 "immediate_operand" "n,n,n")) + (simple_return)] + "DEFAULT_ABI == ABI_V4 + || DEFAULT_ABI == ABI_DARWIN" +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + + return rs6000_indirect_sibcall_template (operands, 0); +} + [(set_attr "type" "jmpreg") + (set (attr "length") + (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) + (const_string "12") + (ior (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) + (const_string "8")] + (const_string "4")))]) + (define_insn "*sibcall_nonlocal_sysv" - [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c")) - (match_operand 1 "" "")) - (use (match_operand 2 "immediate_operand" "O,n,O,n")) + [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) + (match_operand 1)) + (use (match_operand 2 "immediate_operand" "O,n")) (simple_return)] "(DEFAULT_ABI == ABI_DARWIN || DEFAULT_ABI == ABI_V4) @@ -10849,29 +10939,45 @@ (define_insn "*sibcall_nonlocal_sysv" else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn ("creqv 6,6,6", operands); - 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" - [(const_string "4") - (const_string "8") - (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") - (const_int 0)) - (const_string "12") - (const_string "4")) - (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") - (const_int 0)) - (const_string "16") - (const_string "8"))])]) + (set_attr "length" "4,8")]) + +(define_insn "*sibcall_value_indirect_nonlocal_sysv" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) + (match_operand 2))) + (use (match_operand:SI 3 "immediate_operand" "n,n,n")) + (simple_return)] + "DEFAULT_ABI == ABI_V4 + || DEFAULT_ABI == ABI_DARWIN" +{ + if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + + return rs6000_indirect_sibcall_template (operands, 1); +} + [(set_attr "type" "jmpreg") + (set (attr "length") + (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) + (const_string "12") + (ior (and (match_test "!rs6000_speculate_indirect_jumps") + (match_test "which_alternative != 1")) + (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) + (const_string "8")] + (const_string "4")))]) (define_insn "*sibcall_value_nonlocal_sysv" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c")) - (match_operand 2 "" ""))) - (use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) + (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) + (match_operand 2))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) (simple_return)] "(DEFAULT_ABI == ABI_DARWIN || DEFAULT_ABI == ABI_V4) @@ -10883,29 +10989,10 @@ (define_insn "*sibcall_value_nonlocal_sysv" else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn ("creqv 6,6,6", operands); - if (which_alternative >= 2) - { - if (rs6000_speculate_indirect_jumps) - return "b%T1"; - else - /* Can use CR0 since it is volatile across sibcalls. */ - 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" - [(const_string "4") - (const_string "8") - (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") - (const_int 0)) - (const_string "12") - (const_string "4")) - (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") - (const_int 0)) - (const_string "16") - (const_string "8"))])]) + (set_attr "length" "4,8")]) ;; AIX ABI sibling call patterns. diff --git a/gcc/configure.ac b/gcc/configure.ac index 260d987dadd..c0043469aeb 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -4648,6 +4648,12 @@ LCF0: [AC_DEFINE(HAVE_AS_ENTRY_MARKERS, 1, [Define if your assembler supports the R_PPC64_ENTRY relocation.])]) + gcc_GAS_CHECK_FEATURE([plt sequence marker support], + gcc_cv_as_powerpc_pltseq_markers, [2,31,0],-a32 --fatal-warnings, + [ .reloc .,R_PPC_PLTSEQ; nop],, + [AC_DEFINE(HAVE_AS_PLTSEQ, 1, + [Define if your assembler supports R_PPC*_PLTSEQ relocations.])]) + case $target in *-*-aix*) gcc_GAS_CHECK_FEATURE([AIX .ref support],