diff options
author | John David Anglin <danglin@gcc.gnu.org> | 2019-11-08 00:27:06 +0000 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2019-11-08 00:27:06 +0000 |
commit | 6a9c4224e411c625e326927ebf75e27b8fe2d26b (patch) | |
tree | 79c457b7370f75030fe8b6df6056141e3f50d378 /gcc/config/pa/pa.md | |
parent | fe335098d55e9efd933ec8f56b07752048454092 (diff) | |
download | gcc-6a9c4224e411c625e326927ebf75e27b8fe2d26b.tar.gz |
pa.md (memory_barrier): Revise to use ldcw barriers.
* config/pa/pa.md (memory_barrier): Revise to use ldcw barriers.
Enhance comment.
(memory_barrier_coherent, memory_barrier_64, memory_barrier_32): New
insn patterns using ldcw instruction.
(memory_barrier): Remove insn pattern using sync instruction.
* config/pa/pa.opt (coherent-ldcw): New option.
(ordered): New option.
From-SVN: r277941
Diffstat (limited to 'gcc/config/pa/pa.md')
-rw-r--r-- | gcc/config/pa/pa.md | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 3867a55bca8..723ba137538 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -10086,23 +10086,55 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" (set_attr "length" "4,16")]) ;; PA 2.0 hardware supports out-of-order execution of loads and stores, so -;; we need a memory barrier to enforce program order for memory references. -;; Since we want PA 1.x code to be PA 2.0 compatible, we also need the -;; barrier when generating PA 1.x code. +;; we need memory barriers to enforce program order for memory references +;; when the TLB and PSW O bits are not set. We assume all PA 2.0 systems +;; are weakly ordered since neither HP-UX or Linux set the PSW O bit. Since +;; we want PA 1.x code to be PA 2.0 compatible, we also need barriers when +;; generating PA 1.x code even though all PA 1.x systems are strongly ordered. + +;; When barriers are needed, we use a strongly ordered ldcw instruction as +;; the barrier. Most PA 2.0 targets are cache coherent. In that case, we +;; can use the coherent cache control hint and avoid aligning the ldcw +;; address. In spite of its description, it is not clear that the sync +;; instruction works as a barrier. (define_expand "memory_barrier" - [(set (match_dup 0) - (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))] + [(parallel + [(set (match_dup 0) (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER)) + (clobber (match_dup 1))])] "" { - operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + /* We don't need a barrier if the target uses ordered memory references. */ + if (TARGET_ORDERED) + FAIL; + operands[1] = gen_reg_rtx (Pmode); + operands[0] = gen_rtx_MEM (BLKmode, operands[1]); MEM_VOLATILE_P (operands[0]) = 1; }) -(define_insn "*memory_barrier" +(define_insn "*memory_barrier_coherent" [(set (match_operand:BLK 0 "" "") - (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))] - "" - "sync" + (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER)) + (clobber (match_operand 1 "pmode_register_operand" "=r"))] + "TARGET_PA_20 && TARGET_COHERENT_LDCW" + "ldcw,co 0(%%sp),%1" [(set_attr "type" "binary") (set_attr "length" "4")]) + +(define_insn "*memory_barrier_64" + [(set (match_operand:BLK 0 "" "") + (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER)) + (clobber (match_operand 1 "pmode_register_operand" "=&r"))] + "TARGET_64BIT" + "ldo 15(%%sp),%1\n\tdepd %%r0,63,3,%1\n\tldcw 0(%1),%1" + [(set_attr "type" "binary") + (set_attr "length" "12")]) + +(define_insn "*memory_barrier_32" + [(set (match_operand:BLK 0 "" "") + (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER)) + (clobber (match_operand 1 "pmode_register_operand" "=&r"))] + "" + "ldo 15(%%sp),%1\n\t{dep|depw} %%r0,31,3,%1\n\tldcw 0(%1),%1" + [(set_attr "type" "binary") + (set_attr "length" "12")]) |