aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorAaron Sawdey <acsawdey@linux.ibm.com>2020-04-20 13:01:43 -0500
committerAaron Sawdey <acsawdey@linux.ibm.com>2020-04-22 12:19:33 -0500
commit3bcdb5dec72b6d7b197821c2b814bc9fc07f4628 (patch)
treefc0cf4cab07bd73a5607091c2c158aafbaf92652 /gcc/config
parent464092e0f1123878cda3e2fa37b1cdc6a26ebbd4 (diff)
downloadgcc-3bcdb5dec72b6d7b197821c2b814bc9fc07f4628.zip
gcc-3bcdb5dec72b6d7b197821c2b814bc9fc07f4628.tar.gz
gcc-3bcdb5dec72b6d7b197821c2b814bc9fc07f4628.tar.bz2
Use plq/pstq for atomic_{load,store}<mode>
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 <acsawdey@linux.ibm.com> PR target/94622 * config/rs6000/sync.md (load_quadpti): Add attr "prefixed" if TARGET_PREFIXED. (store_quadpti): Ditto. (atomic_load<mode>): Do not swap doublewords if TARGET_PREFIXED as plq will be used and doesn't need it. (atomic_store<mode>): Ditto, for pstq.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/rs6000/sync.md27
1 files changed, 22 insertions, 5 deletions
diff --git a/gcc/config/rs6000/sync.md b/gcc/config/rs6000/sync.md
index f27edc7..5ad8880 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<mode>"
[(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<mode>"
[(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
{