diff options
author | Daniel Cederman <cederman@gaisler.com> | 2020-09-25 13:17:46 +0200 |
---|---|---|
committer | Daniel Hellstrom <daniel@gaisler.com> | 2021-09-16 13:05:47 +0200 |
commit | b4bbb373dfad830e8daa43e880e4f6536c868a53 (patch) | |
tree | 0b8cde799a46c98081b7fb309bcf5599549be1c9 /gcc | |
parent | b7e0dd61e4ffa8787ef8fe7449dde36cc970653f (diff) | |
download | gcc-b4bbb373dfad830e8daa43e880e4f6536c868a53.zip gcc-b4bbb373dfad830e8daa43e880e4f6536c868a53.tar.gz gcc-b4bbb373dfad830e8daa43e880e4f6536c868a53.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/sparc/sparc.c | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index d5a0ff7..49cee35 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; } } |