summaryrefslogtreecommitdiff
path: root/gcc/config/pa/pa.md
diff options
context:
space:
mode:
authorJohn David Anglin <danglin@gcc.gnu.org>2019-11-08 00:27:06 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2019-11-08 00:27:06 +0000
commit6a9c4224e411c625e326927ebf75e27b8fe2d26b (patch)
tree79c457b7370f75030fe8b6df6056141e3f50d378 /gcc/config/pa/pa.md
parentfe335098d55e9efd933ec8f56b07752048454092 (diff)
downloadgcc-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.md52
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")])