From patchwork Thu Jan 4 14:31:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Richard Earnshaw \(lists\)" X-Patchwork-Id: 123427 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp11499918qgn; Thu, 4 Jan 2018 06:32:36 -0800 (PST) X-Google-Smtp-Source: ACJfBoueWOd8nGinhHc9io6fa/JmFqZJ81MFTEoIIfiys2Zc5k5voiMigYk72KMB1JioKZiN5fXw X-Received: by 10.98.76.90 with SMTP id z87mr5011769pfa.194.1515076356185; Thu, 04 Jan 2018 06:32:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515076356; cv=none; d=google.com; s=arc-20160816; b=HHVAct9aSS0UCPB5JkB0MzX1F6mZRuv+6VBGwkquBhlmUzmNOwOT7m7znZAWRmDflt jaWCSXjXl//Bhy/dDtXI0nYXd56bmnJxuGMkvoMRXduDJ6caFmNoPNSoUV4ZFTCAF4x8 qTwmcP3U+Jat6pEH4nJUrOFiZiNwLh39YOwYFPUj/3dKF8gpyiy3RPdb9HPXzW5eje31 uU0QUlFkhtQQHJ/M3yiyZlKCoMLBB4pUibdufQN92qk6GT0EcP1T6pn3jBacMp4vrs2s N1I4IhOpHbb+g0JM06jS+RnO2gncxorzckZCSPm5gSdevzMhDBHt7HLl6oyXQ7Xv1sr7 fBhw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:references:in-reply-to:references:in-reply-to :message-id:date:subject:cc:to:from:delivered-to:sender:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=YCEZolzuI+9r4dQ9sdEHWvXAWpiLLoi3qeB7QITliyc=; b=ReCtgXA8jgVjo1KcAkURAlPO8lJzkIv0dcm94x8b8oIH0LplDYWuTC65HXgBt45VuE tpMqEgZuwhkRIWZlO0Zk9sLiWfzzKyCQhD/X9d5ICBv4kb1Z6obO3rqqYmJ5oGIuRUfG EX7NMsgqb2iii8mqtranP2ALJAF1BfluAurb3cmqgbZ1a4yGXpF12iAFY1QWLZ8h7zI6 /SnluVBFpIDObao8CkrrxfQ3+oSYFj8qdUzNYYWX3Yyfv4gG2ZDQ53bgdvp6OIWu9DrV Y0Xfe1VUBPEF4z0YEsBabtGPE142TFyr3JBDV2Bn0MqAFjimqNReg7+qnjqfXuj8+WhJ aTWQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=pU65Vfji; spf=pass (google.com: domain of gcc-patches-return-470141-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-470141-patch=linaro.org@gcc.gnu.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id h20si2123376pgv.201.2018.01.04.06.32.35 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 04 Jan 2018 06:32:36 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-470141-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=pU65Vfji; spf=pass (google.com: domain of gcc-patches-return-470141-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-470141-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references:mime-version:content-type; q=dns; s= default; b=XEG6XDaQ9MrKeBtENOEiF3b/Wtj2Ef6ce2Z91n4Xwn29T0mQbCfpc BgLlDEwsTBdUAPvvZSWmngHw2P/DskWdehs0COC7VOcf7aEx2foEFOJDaLWZF3W+ 4iUQoXVQqs+sgEtcJjOQvM4OqPHnBXj18rTQsxd3pZNVuA9reWr1Bk= 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:from :to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references:mime-version:content-type; s=default; bh=iFBDpW4qdzJxNNCFgo7NUARZKuM=; b=pU65VfjieD6Vqs8vsp9q3ZFPFFrV Vg0VD3QCfLvDB1JOCQJyi/l00k21E4ymAbOnYH4KjF9jh0yr2b/3NDRSgeS5qwGu qQowI9/d/BfuzklLfc/3QrWdeHRLXS2hSPBGQdwPDlFT6jN8DIFPd1UrO4ed2tBE LX7Juq+jDVa6sM4= Received: (qmail 100427 invoked by alias); 4 Jan 2018 14:32:12 -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 100266 invoked by uid 89); 4 Jan 2018 14:32:10 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy= X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 04 Jan 2018 14:32:08 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 95B4E15AD; Thu, 4 Jan 2018 06:32:07 -0800 (PST) Received: from e105689-lin.cambridge.arm.com (e105689-lin.cambridge.arm.com [10.2.207.32]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CD98E3F41F; Thu, 4 Jan 2018 06:32:06 -0800 (PST) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH 2/3] [gcc-7 backport] [aarch64] Implement support for __builtin_load_no_speculate. Date: Thu, 4 Jan 2018 14:31:54 +0000 Message-Id: In-Reply-To: References: In-Reply-To: References: MIME-Version: 1.0 This patch implements support for __builtin_load_no_speculate on AArch64. On this architecture we inhibit speclation by emitting a combination of CSEL and a hint instruction that ensures the CSEL is full resolved when the operands to the CSEL may involve a speculative load. * config/aarch64/aarch64.c (aarch64_print_operand): Handle zero passed to 'H' operand qualifier. (aarch64_inhibit_load_speculation): New function. (TARGET_INHIBIT_LOAD_SPECULATION): Redefine. * config/aarch64/aarch64.md (UNSPECV_NOSPECULATE): New unspec_volatile code. (nospeculate, nospeculateti): New patterns. --- gcc/config/aarch64/aarch64.c | 91 +++++++++++++++++++++++++++++++++++++++++++ gcc/config/aarch64/aarch64.md | 28 +++++++++++++ 2 files changed, 119 insertions(+) diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 436091a..4a000b0 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -4987,6 +4987,13 @@ aarch64_print_operand (FILE *f, rtx x, int code) case 'H': /* Print the higher numbered register of a pair (TImode) of regs. */ + if (x == const0_rtx + || (CONST_DOUBLE_P (x) && aarch64_float_const_zero_rtx_p (x))) + { + asm_fprintf (f, "xzr"); + break; + } + if (!REG_P (x) || !GP_REGNUM_P (REGNO (x) + 1)) { output_operand_lossage ("invalid operand for '%%%c'", code); @@ -14708,6 +14715,87 @@ aarch64_sched_can_speculate_insn (rtx_insn *insn) } } +static rtx +aarch64_inhibit_load_speculation (machine_mode mode, rtx result, rtx mem, + rtx lower_bound, rtx upper_bound, + rtx fail_result, rtx cmpptr) +{ + rtx cond, comparison; + rtx target = gen_reg_rtx (mode); + rtx tgt2 = result; + + if (!register_operand (cmpptr, ptr_mode)) + cmpptr = force_reg (ptr_mode, cmpptr); + + if (!register_operand (tgt2, mode)) + tgt2 = gen_reg_rtx (mode); + + if (upper_bound == NULL) + { + if (!register_operand (lower_bound, ptr_mode)) + lower_bound = force_reg (ptr_mode, lower_bound); + + cond = aarch64_gen_compare_reg (LTU, cmpptr, lower_bound); + comparison = gen_rtx_LTU (VOIDmode, cond, const0_rtx); + } + else if (lower_bound == NULL) + { + if (!register_operand (upper_bound, ptr_mode)) + upper_bound = force_reg (ptr_mode, upper_bound); + + cond = aarch64_gen_compare_reg (GEU, cmpptr, upper_bound); + comparison = gen_rtx_GEU (VOIDmode, cond, const0_rtx); + } + else + { + if (!register_operand (lower_bound, ptr_mode)) + lower_bound = force_reg (ptr_mode, lower_bound); + + if (!register_operand (upper_bound, ptr_mode)) + upper_bound = force_reg (ptr_mode, upper_bound); + + rtx cond1 = aarch64_gen_compare_reg (GEU, cmpptr, lower_bound); + rtx comparison1 = gen_rtx_GEU (ptr_mode, cond1, const0_rtx); + rtx failcond = GEN_INT (aarch64_get_condition_code (comparison1)^1); + cond = gen_rtx_REG (CCmode, CC_REGNUM); + if (ptr_mode == SImode) + emit_insn (gen_ccmpsi (cond1, cond, cmpptr, upper_bound, comparison1, + failcond)); + else + emit_insn (gen_ccmpdi (cond1, cond, cmpptr, upper_bound, comparison1, + failcond)); + comparison = gen_rtx_GEU (VOIDmode, cond, const0_rtx); + } + + rtx_code_label *label = gen_label_rtx (); + emit_jump_insn (gen_condjump (comparison, cond, label)); + emit_move_insn (target, mem); + emit_label (label); + + insn_code icode; + + switch (mode) + { + case QImode: icode = CODE_FOR_nospeculateqi; break; + case HImode: icode = CODE_FOR_nospeculatehi; break; + case SImode: icode = CODE_FOR_nospeculatesi; break; + case DImode: icode = CODE_FOR_nospeculatedi; break; + case TImode: icode = CODE_FOR_nospeculateti; break; + default: + gcc_unreachable (); + } + + if (! insn_operand_matches (icode, 4, fail_result)) + fail_result = force_reg (mode, fail_result); + + emit_insn (GEN_FCN (icode) (tgt2, comparison, cond, target, fail_result)); + + if (tgt2 != result) + emit_move_insn (result, tgt2); + + return result; +} + /* Target-specific selftests. */ #if CHECKING_P @@ -15136,6 +15224,9 @@ aarch64_libgcc_floating_mode_supported_p #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 4 +#undef TARGET_INHIBIT_LOAD_SPECULATION +#define TARGET_INHIBIT_LOAD_SPECULATION aarch64_inhibit_load_speculation + #if CHECKING_P #undef TARGET_RUN_TARGET_SELFTESTS #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 51368e2..ca91147 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -150,6 +150,7 @@ UNSPECV_SET_FPSR ; Represent assign of FPSR content. UNSPECV_BLOCKAGE ; Represent a blockage UNSPECV_PROBE_STACK_RANGE ; Represent stack range probing. + UNSPECV_NOSPECULATE ; Inhibit speculation ] ) @@ -5564,6 +5565,33 @@ DONE; }) +(define_insn "nospeculate" + [(set (match_operand:ALLI 0 "register_operand" "=r") + (unspec_volatile:ALLI + [(match_operator 1 "aarch64_comparison_operator" + [(match_operand 2 "cc_register" "") (const_int 0)]) + (match_operand:ALLI 3 "register_operand" "r") + (match_operand:ALLI 4 "aarch64_reg_or_zero" "rZ")] + UNSPECV_NOSPECULATE))] + "" + "csel\\t%0, %3, %4, %M1\;hint\t#0x14\t// CSDB" + [(set_attr "type" "csel") + (set_attr "length" "8")] +) + +(define_insn "nospeculateti" + [(set (match_operand:TI 0 "register_operand" "=r") + (unspec_volatile:TI + [(match_operator 1 "aarch64_comparison_operator" + [(match_operand 2 "cc_register" "") (const_int 0)]) + (match_operand:TI 3 "register_operand" "r") + (match_operand:TI 4 "aarch64_reg_or_zero" "rZ")] + UNSPECV_NOSPECULATE))] + "" + "csel\\t%x0, %x3, %x4, %M1\;csel\\t%H0, %H3, %H4, %M1\;hint\t#0x14\t// CSDB" + [(set_attr "type" "csel") + (set_attr "length" "12")] +) ;; AdvSIMD Stuff (include "aarch64-simd.md")