From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5248 invoked by alias); 20 Nov 2017 12:50:20 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 5193 invoked by uid 89); 20 Nov 2017 12:50:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_NUMSUBJECT,KB_WAM_FROM_NAME_SINGLEWORD,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=H*Ad:U*daniel, H*Ad:U*ebotcazou, 94531, symbol_ref X-HELO: bin-vsp-out-03.atm.binero.net Received: from vsp-unauthed02.binero.net (HELO bin-vsp-out-03.atm.binero.net) (195.74.38.227) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 20 Nov 2017 12:50:16 +0000 X-Halon-ID: 57252e77-cdf1-11e7-811b-0050569116f7 Authorized-sender: cederman@gaisler.com Received: from localhost.localdomain (unknown [81.170.187.120]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 57252e77-cdf1-11e7-811b-0050569116f7; Mon, 20 Nov 2017 13:50:10 +0100 (CET) From: Daniel Cederman To: gcc-patches@gcc.gnu.org Cc: ebotcazou@adacore.com, sebastian.huber@embedded-brains.de, daniel@gaisler.com Subject: [PATCH 1/4] [SPARC] Errata workaround for GRLIB-TN-0012 Date: Mon, 20 Nov 2017 12:50:00 -0000 Message-Id: <20171120125003.22670-2-cederman@gaisler.com> In-Reply-To: <20171120125003.22670-1-cederman@gaisler.com> References: <20171120125003.22670-1-cederman@gaisler.com> X-IsSubscribed: yes X-SW-Source: 2017-11/txt/msg01751.txt.bz2 This patch provides a workaround for the errata described in GRLIB-TN-0012. If the workaround is enabled it will: * Prevent any floating-point operation from being placed in the delay slot of an annulled integer branch. * Place a NOP at the branch target of an integer branch if it is a floating-point operation or a floating-point branch. It is applicable to GR712RC. gcc/ChangeLog: 2017-11-17 Daniel Cederman * config/sparc/sparc.c (fpop_insn_p): New function. (sparc_do_work_around_errata): Insert NOP instructions to prevent sequences that could trigger the TN-0012 errata for GR712RC. (pass_work_around_errata::gate): Also test sparc_fix_gr712rc. * config/sparc/sparc.md (fix_gr712rc): New attribute. (in_branch_annul_delay): Prevent floating-point instructions in delay slot of annulled integer branch. --- gcc/config/sparc/sparc.c | 50 +++++++++++++++++++++++++++++++++++++++++++++-- gcc/config/sparc/sparc.md | 17 ++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index a9945e2..8f6eb48 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -945,6 +945,31 @@ mem_ref (rtx x) return NULL_RTX; } +/* True if floating-point instruction. */ + +static int +fpop_insn_p (rtx_insn *insn) +{ + if ( GET_CODE (PATTERN (insn)) != SET) + return false; + + switch (get_attr_type (insn)) + { + case TYPE_FPMOVE: + case TYPE_FPCMOVE: + case TYPE_FP: + case TYPE_FPCMP: + case TYPE_FPMUL: + case TYPE_FPDIVS: + case TYPE_FPSQRTS: + case TYPE_FPDIVD: + case TYPE_FPSQRTD: + return true; + default: + return false; + } +} + /* We use a machine specific pass to enable workarounds for errata. We need to have the (essentially) final form of the insn stream in order @@ -970,11 +995,31 @@ sparc_do_work_around_errata (void) { bool insert_nop = false; rtx set; + rtx_insn *jump = 0; /* Look into the instruction in a delay slot. */ if (NONJUMP_INSN_P (insn)) if (rtx_sequence *seq = dyn_cast (PATTERN (insn))) - insn = seq->insn (1); + { + jump = seq->insn (0); + insn = seq->insn (1); + } + + /* Place a NOP at the branch target of an integer branch if it is + a floating-point operation or a floating-point branch. */ + if (sparc_fix_gr712rc + && (JUMP_P (insn) || jump) + && get_attr_branch_type (jump ? jump : insn) == BRANCH_TYPE_ICC) + { + rtx_insn *target; + + target = next_active_insn (JUMP_LABEL_AS_INSN (jump ? jump : insn)); + if (target + && (fpop_insn_p (target) + || ((JUMP_P (target) + && get_attr_branch_type (target) == BRANCH_TYPE_FCC)))) + emit_insn_before (gen_nop (), target); + } /* Look for either of these two sequences: @@ -1303,7 +1348,8 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { - return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst; + return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst + || sparc_fix_gr712rc; } virtual unsigned int execute (function *) diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index d9cbd4f..ef789e2 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -430,6 +430,10 @@ (symbol_ref "(sparc_fix_b2bst != 0 ? FIX_B2BST_TRUE : FIX_B2BST_FALSE)")) +(define_attr "fix_gr712rc" "false,true" + (symbol_ref "(sparc_fix_gr712rc != 0 + ? FIX_GR712RC_TRUE : FIX_GR712RC_FALSE)")) + ;; Length (in # of insns). ;; Beware that setting a length greater or equal to 3 for conditional branches ;; has a side-effect (see output_cbranch and output_v9branch). @@ -590,6 +594,15 @@ (const_string "true") ] (const_string "false"))) +(define_attr "in_branch_annul_delay" "false,true" + (cond[(and (eq_attr "fix_gr712rc" "true") + (eq_attr "type" "fp,fpcmp,fpmove,fpcmove,fpmul, + fpdivs,fpsqrts,fpdivd,fpsqrtd")) + (const_string "false") + (eq_attr "in_branch_delay" "true") + (const_string "true") + ] (const_string "false"))) + (define_delay (eq_attr "type" "call") [(eq_attr "in_call_delay" "true") (nil) (nil)]) @@ -602,6 +615,10 @@ (define_delay (eq_attr "type" "branch") [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")]) +(define_delay (and (eq_attr "type" "branch") (eq_attr "branch_type" "icc")) + [(eq_attr "in_branch_delay" "true") (nil) + (eq_attr "in_branch_annul_delay" "true")]) + (define_delay (eq_attr "type" "uncond_branch") [(eq_attr "in_branch_delay" "true") (nil) (nil)]) -- 2.9.3