Commit a4caec93 authored by pthaugen's avatar pthaugen

* config/rs6000/sync.md (AINT mode_iterator): Move definition.

	(loadsync_<mode>): Change mode.
	(load_quadpti, store_quadpti): New.
	(atomic_load<mode>, atomic_store<mode>): Add support for TI mode.
	* config/rs6000/rs6000.md (unspec enum): Add UNSPEC_LSQ.



git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@209876 138bc75d-0d04-0410-961f-82ee72b054a4
parent 18b1e6ba
2014-04-28 Pat Haugen <pthaugen@us.ibm.com>
* config/rs6000/sync.md (AINT mode_iterator): Move definition.
(loadsync_<mode>): Change mode.
(load_quadpti, store_quadpti): New.
(atomic_load<mode>, atomic_store<mode>): Add support for TI mode.
* config/rs6000/rs6000.md (unspec enum): Add UNSPEC_LSQ.
2014-04-28 Eric Botcazou <ebotcazou@adacore.com>
* configure.ac: Tweak GAS check for LEON instructions on SPARC.
......
......@@ -624,14 +624,14 @@
(match_test "offsettable_nonstrict_memref_p (op)")))
;; Return 1 if the operand is suitable for load/store quad memory.
;; This predicate only checks for non-atomic loads/stores.
;; This predicate only checks for non-atomic loads/stores (not lqarx/stqcx).
(define_predicate "quad_memory_operand"
(match_code "mem")
{
rtx addr, op0, op1;
int ret;
if (!TARGET_QUAD_MEMORY)
if (!TARGET_QUAD_MEMORY && !TARGET_SYNC_TI)
ret = 0;
else if (!memory_operand (op, mode))
......
......@@ -125,6 +125,7 @@
UNSPEC_P8V_MTVSRD
UNSPEC_P8V_XXPERMDI
UNSPEC_P8V_RELOAD_FROM_VSX
UNSPEC_LSQ
])
;;
......
......@@ -107,10 +107,17 @@
"isync"
[(set_attr "type" "isync")])
;; Types that we should provide atomic instructions for.
(define_mode_iterator AINT [QI
HI
SI
(DI "TARGET_POWERPC64")
(TI "TARGET_SYNC_TI")])
;; The control dependency used for load dependency described
;; in B.2.3 of the Power ISA 2.06B.
(define_insn "loadsync_<mode>"
[(unspec_volatile:BLK [(match_operand:INT1 0 "register_operand" "r")]
[(unspec_volatile:BLK [(match_operand:AINT 0 "register_operand" "r")]
UNSPECV_ISYNC)
(clobber (match_scratch:CC 1 "=y"))]
""
......@@ -118,18 +125,56 @@
[(set_attr "type" "isync")
(set_attr "length" "12")])
(define_insn "load_quadpti"
[(set (match_operand:PTI 0 "quad_int_reg_operand" "=&r")
(unspec:PTI
[(match_operand:TI 1 "quad_memory_operand" "wQ")] UNSPEC_LSQ))]
"TARGET_SYNC_TI
&& !reg_mentioned_p (operands[0], operands[1])"
"lq %0,%1"
[(set_attr "type" "load")
(set_attr "length" "4")])
(define_expand "atomic_load<mode>"
[(set (match_operand:INT1 0 "register_operand" "") ;; output
(match_operand:INT1 1 "memory_operand" "")) ;; memory
[(set (match_operand:AINT 0 "register_operand" "") ;; output
(match_operand:AINT 1 "memory_operand" "")) ;; memory
(use (match_operand:SI 2 "const_int_operand" ""))] ;; model
""
{
if (<MODE>mode == TImode && !TARGET_SYNC_TI)
FAIL;
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
if (model == MEMMODEL_SEQ_CST)
emit_insn (gen_hwsync ());
emit_move_insn (operands[0], operands[1]);
if (<MODE>mode != TImode)
emit_move_insn (operands[0], operands[1]);
else
{
rtx op0 = operands[0];
rtx op1 = operands[1];
rtx pti_reg = gen_reg_rtx (PTImode);
// Can't have indexed address for 'lq'
if (indexed_address (XEXP (op1, 0), TImode))
{
rtx old_addr = XEXP (op1, 0);
rtx new_addr = force_reg (Pmode, old_addr);
operands[1] = op1 = replace_equiv_address (op1, new_addr);
}
emit_insn (gen_load_quadpti (pti_reg, op1));
if (WORDS_BIG_ENDIAN)
emit_move_insn (op0, gen_lowpart (TImode, pti_reg));
else
{
emit_move_insn (gen_lowpart (DImode, op0), gen_highpart (DImode, pti_reg));
emit_move_insn (gen_highpart (DImode, op0), gen_lowpart (DImode, pti_reg));
}
}
switch (model)
{
......@@ -146,12 +191,24 @@
DONE;
})
(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 "length" "4")])
(define_expand "atomic_store<mode>"
[(set (match_operand:INT1 0 "memory_operand" "") ;; memory
(match_operand:INT1 1 "register_operand" "")) ;; input
[(set (match_operand:AINT 0 "memory_operand" "") ;; memory
(match_operand:AINT 1 "register_operand" "")) ;; input
(use (match_operand:SI 2 "const_int_operand" ""))] ;; model
""
{
if (<MODE>mode == TImode && !TARGET_SYNC_TI)
FAIL;
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
switch (model)
{
......@@ -166,7 +223,33 @@
default:
gcc_unreachable ();
}
emit_move_insn (operands[0], operands[1]);
if (<MODE>mode != TImode)
emit_move_insn (operands[0], operands[1]);
else
{
rtx op0 = operands[0];
rtx op1 = operands[1];
rtx pti_reg = gen_reg_rtx (PTImode);
// Can't have indexed address for 'stq'
if (indexed_address (XEXP (op0, 0), TImode))
{
rtx old_addr = XEXP (op0, 0);
rtx new_addr = force_reg (Pmode, old_addr);
operands[0] = op0 = replace_equiv_address (op0, new_addr);
}
if (WORDS_BIG_ENDIAN)
emit_move_insn (pti_reg, gen_lowpart (PTImode, op1));
else
{
emit_move_insn (gen_lowpart (DImode, pti_reg), gen_highpart (DImode, op1));
emit_move_insn (gen_highpart (DImode, pti_reg), gen_lowpart (DImode, op1));
}
emit_insn (gen_store_quadpti (gen_lowpart (PTImode, op0), pti_reg));
}
DONE;
})
......@@ -180,14 +263,6 @@
SI
(DI "TARGET_POWERPC64")])
;; Types that we should provide atomic instructions for.
(define_mode_iterator AINT [QI
HI
SI
(DI "TARGET_POWERPC64")
(TI "TARGET_SYNC_TI")])
(define_insn "load_locked<mode>"
[(set (match_operand:ATOMIC 0 "int_reg_operand" "=r")
(unspec_volatile:ATOMIC
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment