From 3bcdb5dec72b6d7b197821c2b814bc9fc07f4628 Mon Sep 17 00:00:00 2001 From: Aaron Sawdey Date: Mon, 20 Apr 2020 13:01:43 -0500 Subject: [PATCH] Use plq/pstq for atomic_{load,store} For future architecture with prefix instructions, always use plq/pstq rather than lq/stq for atomic load of quadword. Then we never have to do the doubleword swap on little endian. Before this fix, -mno-pcrel would generate lq with the doubleword swap (which was ok) and -mpcrel would generate plq, also with the doubleword swap, which was wrong. 2020-04-20 Aaron Sawdey PR target/94622 * config/rs6000/sync.md (load_quadpti): Add attr "prefixed" if TARGET_PREFIXED. (store_quadpti): Ditto. (atomic_load): Do not swap doublewords if TARGET_PREFIXED as plq will be used and doesn't need it. (atomic_store): Ditto, for pstq. --- gcc/ChangeLog | 10 ++++++++++ gcc/config/rs6000/sync.md | 27 ++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d647ab315a6..d4cc33e3acc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2020-04-20 Aaron Sawdey + + PR target/94622 + * config/rs6000/sync.md (load_quadpti): Add attr "prefixed" + if TARGET_PREFIXED. + (store_quadpti): Ditto. + (atomic_load): Do not swap doublewords if TARGET_PREFIXED as + plq will be used and doesn't need it. + (atomic_store): Ditto, for pstq. + 2020-04-22 Erick Ochoa * doc/invoke.texi: Update flags turned on by -O3. diff --git a/gcc/config/rs6000/sync.md b/gcc/config/rs6000/sync.md index f27edc77b6a..5ad88806818 100644 --- a/gcc/config/rs6000/sync.md +++ b/gcc/config/rs6000/sync.md @@ -122,6 +122,7 @@ [(set_attr "type" "isync") (set_attr "length" "12")]) +;; If TARGET_PREFIXED, always use plq rather than lq. (define_insn "load_quadpti" [(set (match_operand:PTI 0 "quad_int_reg_operand" "=&r") (unspec:PTI @@ -129,8 +130,18 @@ "TARGET_SYNC_TI && !reg_mentioned_p (operands[0], operands[1])" "lq %0,%1" - [(set_attr "type" "load")]) - + [(set_attr "type" "load") + (set (attr "prefixed") (if_then_else (match_test "TARGET_PREFIXED") + (const_string "yes") + (const_string "no")))]) + +;; Pattern load_quadpti will always use plq for atomic TImode if +;; TARGET_PREFIXED. It has the correct doubleword ordering on either LE +;; or BE, so we can just move the result into the output register and +;; do not need to do the doubleword swap for LE. Also this avoids any +;; confusion about whether the lq vs plq might be used based on whether +;; op1 has PC-relative addressing. We could potentially allow BE to +;; use lq because it doesn't have the doubleword ordering problem. (define_expand "atomic_load" [(set (match_operand:AINT 0 "register_operand") ;; output (match_operand:AINT 1 "memory_operand")) ;; memory @@ -162,7 +173,7 @@ emit_insn (gen_load_quadpti (pti_reg, op1)); - if (WORDS_BIG_ENDIAN) + if (WORDS_BIG_ENDIAN || TARGET_PREFIXED) emit_move_insn (op0, gen_lowpart (TImode, pti_reg)); else { @@ -186,14 +197,20 @@ DONE; }) +;; If TARGET_PREFIXED, always use pstq rather than stq. (define_insn "store_quadpti" [(set (match_operand:PTI 0 "quad_memory_operand" "=wQ") (unspec:PTI [(match_operand:PTI 1 "quad_int_reg_operand" "r")] UNSPEC_LSQ))] "TARGET_SYNC_TI" "stq %1,%0" - [(set_attr "type" "store")]) + [(set_attr "type" "store") + (set (attr "prefixed") (if_then_else (match_test "TARGET_PREFIXED") + (const_string "yes") + (const_string "no")))]) +;; Pattern store_quadpti will always use pstq if TARGET_PREFIXED, +;; so the doubleword swap is never needed in that case. (define_expand "atomic_store" [(set (match_operand:AINT 0 "memory_operand") ;; memory (match_operand:AINT 1 "register_operand")) ;; input @@ -232,7 +249,7 @@ operands[0] = op0 = replace_equiv_address (op0, new_addr); } - if (WORDS_BIG_ENDIAN) + if (WORDS_BIG_ENDIAN || TARGET_PREFIXED) emit_move_insn (pti_reg, gen_lowpart (PTImode, op1)); else { -- 2.30.2