;;- Machine description for HP PA-RISC architecture for GCC compiler
-;; Copyright (C) 1992-2019 Free Software Foundation, Inc.
+;; Copyright (C) 1992-2020 Free Software Foundation, Inc.
;; Contributed by the Center for Software Science at the University
;; of Utah.
;; The definition of this insn does not really explain what it does,
;; but it should suffice that anything generated as this insn will be
-;; recognized as a movmemsi operation, and that it will not successfully
+;; recognized as a cpymemsi operation, and that it will not successfully
;; combine with anything.
-(define_expand "movmemsi"
+(define_expand "cpymemsi"
[(parallel [(set (match_operand:BLK 0 "" "")
(match_operand:BLK 1 "" ""))
(clobber (match_dup 4))
;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are
;; forced to internally copy operands 0 and 1 to operands 7 and 8,
;; respectively. We then split or peephole optimize after reload.
-(define_insn "movmemsi_prereload"
+(define_insn "cpymemsi_prereload"
[(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
(mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
(clobber (match_operand:SI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
}
}")
-(define_insn "movmemsi_postreload"
+(define_insn "cpymemsi_postreload"
[(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
(mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
(clobber (match_operand:SI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
"* return pa_output_block_move (operands, !which_alternative);"
[(set_attr "type" "multi,multi")])
-(define_expand "movmemdi"
+(define_expand "cpymemdi"
[(parallel [(set (match_operand:BLK 0 "" "")
(match_operand:BLK 1 "" ""))
(clobber (match_dup 4))
;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are
;; forced to internally copy operands 0 and 1 to operands 7 and 8,
;; respectively. We then split or peephole optimize after reload.
-(define_insn "movmemdi_prereload"
+(define_insn "cpymemdi_prereload"
[(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
(mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
(clobber (match_operand:DI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
}
}")
-(define_insn "movmemdi_postreload"
+(define_insn "cpymemdi_postreload"
[(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
(mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
(clobber (match_operand:DI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
lab = copy_to_reg (lab);
- /* Restore the stack and frame pointers. The virtual_stack_vars_rtx
- is saved instead of the hard_frame_pointer_rtx in the save area.
- As a result, an extra instruction is needed to adjust for the offset
- of the virtual stack variables and the hard frame pointer. */
+ /* Restore the stack and frame pointers. */
fp = copy_to_reg (fp);
emit_stack_restore (SAVE_NONLOCAL, stack);
emit_insn (gen_blockage ());
emit_clobber (hard_frame_pointer_rtx);
emit_clobber (frame_pointer_rtx);
- emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
+ emit_move_insn (hard_frame_pointer_rtx, fp);
emit_use (hard_frame_pointer_rtx);
emit_use (stack_pointer_rtx);
restoring the gp. */
emit_move_insn (pv, lab);
- /* Restore the stack and frame pointers. The virtual_stack_vars_rtx
- is saved instead of the hard_frame_pointer_rtx in the save area.
- We need to adjust for the offset between these two values. */
+ /* Restore the stack and frame pointers. */
fp = copy_to_reg (fp);
emit_stack_restore (SAVE_NONLOCAL, stack);
emit_insn (gen_blockage ());
emit_clobber (hard_frame_pointer_rtx);
emit_clobber (frame_pointer_rtx);
- emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
+ emit_move_insn (hard_frame_pointer_rtx, fp);
emit_use (hard_frame_pointer_rtx);
emit_use (stack_pointer_rtx);
(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")])