From b4bbb373dfad830e8daa43e880e4f6536c868a53 Mon Sep 17 00:00:00 2001 From: Daniel Cederman <cederman@gaisler.com> Date: Fri, 25 Sep 2020 13:17:46 +0200 Subject: [PATCH] sparc: Treat more instructions as load or store in errata workarounds Check the attribute of instruction to determine if it performs a store or load operation. This more generic approach sees the last instruction in the GOTdata_op model as a potential load and treats the memory barrier as a potential store instruction. gcc/ChangeLog: * config/sparc/sparc.c (store_insn_p): Add predicate for store attributes. (load_insn_p): Add predicate for load attributes. (sparc_do_work_around_errata): Use new predicates. --- gcc/config/sparc/sparc.c | 49 +++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index d5a0ff7d4ea0..49cee356a836 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -1045,6 +1045,43 @@ atomic_insn_for_leon3_p (rtx_insn *insn) } } +/* True if INSN is a store instruction. */ + +static bool +store_insn_p (rtx_insn *insn) +{ + if (GET_CODE (PATTERN (insn)) != SET) + return false; + + switch (get_attr_type (insn)) + { + case TYPE_STORE: + case TYPE_FPSTORE: + return true; + default: + return false; + } +} + +/* True if INSN is a load instruction. */ + +static bool +load_insn_p (rtx_insn *insn) +{ + if (GET_CODE (PATTERN (insn)) != SET) + return false; + + switch (get_attr_type (insn)) + { + case TYPE_LOAD: + case TYPE_SLOAD: + case TYPE_FPLOAD: + 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 @@ -1105,9 +1142,7 @@ sparc_do_work_around_errata (void) instruction at branch target. */ if (sparc_fix_ut700 && NONJUMP_INSN_P (insn) - && (set = single_set (insn)) != NULL_RTX - && mem_ref (SET_SRC (set)) - && REG_P (SET_DEST (set))) + && load_insn_p (insn)) { if (jump && jump_to_label_p (jump)) { @@ -1212,7 +1247,7 @@ sparc_do_work_around_errata (void) if (sparc_fix_b2bst && NONJUMP_INSN_P (insn) && (set = single_set (insn)) != NULL_RTX - && MEM_P (SET_DEST (set))) + && store_insn_p (insn)) { /* Sequence B begins with a double-word store. */ bool seq_b = GET_MODE_SIZE (GET_MODE (SET_DEST (set))) == 8; @@ -1245,8 +1280,7 @@ sparc_do_work_around_errata (void) if (seq_b) { /* Add NOP if followed by a store. */ - if ((set = single_set (after)) != NULL_RTX - && MEM_P (SET_DEST (set))) + if (store_insn_p (after)) insert_nop = true; /* Otherwise it is ok. */ @@ -1268,8 +1302,7 @@ sparc_do_work_around_errata (void) /* Add NOP if third instruction is a store. */ if (i == 1 - && (set = single_set (after)) != NULL_RTX - && MEM_P (SET_DEST (set))) + && store_insn_p (after)) insert_nop = true; } } -- GitLab