From patchwork Wed Nov 7 05:37:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 994100 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-489202-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="ClCqPLRp"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="mNbOZlgX"; 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 42qZvM735kz9s8T for ; Wed, 7 Nov 2018 16:38:07 +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=VWJqe8ZP2ER6G+NHU 4aas4w9ON89Z77B1FXo54N4YFnp1uv2AdzU47nelFUImCH7A5qAYLUgPOviiSGYj lrBXHy6XoVUJay+gx0P7vUCH3vkoccwRgsPWx6gC6huiHsU++iKL7O46BY3/QpzW eTWssI2uO45P8wqDLyjxEjjqe8= 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=4S66SQ71czgrxsaBl6LuD5T p31Y=; b=ClCqPLRpZVnEvqxOmsga19ORfuXVqOHmaGlBf9xFylPVoE8vI9h/9uy Yy9SIoXBtCkG+bB1o9GOCB7Ae4w9osdOSArqSBEq5mydr4A5S6RF1U7XFqfT1g56 zI58NkjgjzejcrwSAZ8aw8qJ6IEyntRE7vfmx7F0niu5rWLPB9Q4= Received: (qmail 73896 invoked by alias); 7 Nov 2018 05:38:00 -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 73873 invoked by uid 89); 7 Nov 2018 05:37:59 -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=barrier, memory_operand X-HELO: mail-pg1-f178.google.com Received: from mail-pg1-f178.google.com (HELO mail-pg1-f178.google.com) (209.85.215.178) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 07 Nov 2018 05:37:57 +0000 Received: by mail-pg1-f178.google.com with SMTP id y4so6429969pgc.12 for ; Tue, 06 Nov 2018 21:37:57 -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=xt71rLKKrQorPR3Zj+DBGwrjgkHJbHduF///FwbLf9s=; b=mNbOZlgXgX88aihCd0+skhOHVphvadVmYRnAEXrI6+KeDVjJX56EvPNCB7DfqQ0BFs iMXPVraPNRVlDbtuFXnty7K9r0jvaiAdIxbMXNumR5Yk0IFtUuNiHxhjejrydwY/3MTN tyU4K+qrAXls54O9eWEvDUrNK3AQIskoKCYQE/yMFlzK6uxEOApUF5AJ0NiKve/8YAp2 hS8l1BVouXmDxgpvu5At/T5hAn9GvZM+C7JFmss3UwYSlarHXLoHC8S3BhdZRpfaE+zE vY+cDX2IWBDwMYzZptdrj6FkP03a1WEfa98GEfWcsrRStqbOBh2V5sfmENnfMEQCkbA0 +n9Q== Received: from bubble.grove.modra.org ([58.175.241.133]) by smtp.gmail.com with ESMTPSA id y123-v6sm2370431pfg.140.2018.11.06.21.37.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 06 Nov 2018 21:37:54 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 433ED8033C; Wed, 7 Nov 2018 16:07:51 +1030 (ACDT) Date: Wed, 7 Nov 2018 16:07:51 +1030 From: Alan Modra To: gcc-patches@gcc.gnu.org Cc: Segher Boessenkool Subject: [PATCH 2/6] [RS6000] rs6000_output_indirect_call Message-ID: <20181107053751.GO29482@bubble.grove.modra.org> References: <20181107053326.GM29482@bubble.grove.modra.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181107053326.GM29482@bubble.grove.modra.org> User-Agent: Mutt/1.9.4 (2018-02-28) X-IsSubscribed: yes 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_output_indirect_call): Declare. * config/rs6000/rs6000.c (rs6000_output_indirect_call): New function. * config/rs6000/rs6000.md (call_indirect_nonlocal_sysv): Use rs6000_output_indirect_call. (call_value_indirect_nonlocal_sysv, sibcall_nonlocal_sysv): Likewise. (call_indirect_aix, call_value_indirect_aix, 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 f1a421dde16..493cfe6ba2b 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -112,6 +112,7 @@ 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_output_call (rtx *, unsigned int, bool, const char *); +extern const char *rs6000_output_indirect_call (rtx *, unsigned int, bool); 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 b22cae55a0d..bf1551746d5 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -21411,6 +21411,69 @@ rs6000_output_call (rtx *operands, unsigned int fun, bool sibcall, return str; } +/* As above, for indirect calls. */ + +const char * +rs6000_output_indirect_call (rtx *operands, unsigned int fun, bool sibcall) +{ + /* -Wformat-overflow workaround, without which gcc thinks that %u + might produce 10 digits. FUN is 0 or 1 as of 2018-03. */ + gcc_assert (fun <= 6); + + static char str[144]; + const char *ptrload = TARGET_64BIT ? "d" : "wz"; + + bool speculate = (rs6000_speculate_indirect_jumps + || (REG_P (operands[fun]) + && REGNO (operands[fun]) == 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, fun + 2, fun, ptrload, fun + 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, fun + 2, fun, ptrload, fun + 3); + } + else if (DEFAULT_ABI == ABI_ELFv2) + { + if (speculate) + sprintf (str, + "b%%T%ul\n\t" + "l%s 2,%%%u(1)", + fun, ptrload, fun + 2); + else + sprintf (str, + "crset 2\n\t" + "beq%%T%ul-\n\t" + "l%s 2,%%%u(1)", + fun, ptrload, fun + 2); + } + else if (DEFAULT_ABI == ABI_V4) + { + if (speculate) + sprintf (str, + "b%%T%u%s", + fun, "l" + sibcall); + else + sprintf (str, + "crset 2\n\t" + "beq%%T%u%s-%s", + fun, "l" + sibcall, sibcall ? "\n\tb $" : ""); + } + else + gcc_unreachable (); + return str; +} + #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 52088fdfbdb..9d9e29d12eb 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -10540,11 +10540,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_output_indirect_call (operands, 0, false); } [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") (set_attr_alternative "length" @@ -10630,11 +10626,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_output_indirect_call (operands, 1, false); } [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") (set_attr_alternative "length" @@ -10765,21 +10757,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_output_indirect_call (operands, 0, false); +} [(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 "" "") @@ -10788,22 +10775,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_output_indirect_call (operands, 1, false); +} [(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 @@ -10814,21 +10795,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_output_indirect_call (operands, 0, false); +} [(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 "" "") @@ -10836,22 +10812,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_output_indirect_call (operands, 1, false); +} [(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" @@ -11020,13 +10990,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_output_indirect_call (operands, 0, true); else return rs6000_output_call (operands, 0, true, ""); }