re PR target/64660 ([SH] Convert atomic_fetch_<op> to atomic_<op>_fetch)

gcc/
	PR target/64660
	* config/sh/sync.md (atomic_<fetchop_name><mode>_hard,
	atomic_not<mode>_hard, atomic_<fetchop_name><mode>_soft_tcb,
	atomic_not<mode>_soft_tcb, atomic_nand<mode>_hard,
	atomic_nand<mode>_soft_tcb): New insns.
	(atomic_fetch_<fetchop_name>si_hard): Convert to insn_and_split.
	Split into atomic_<fetchop_name>_fetchsi_hard if operands[0] is unused.
	(define_insn "atomic_fetch_notsi_hard): Convert to insn_and_split.
	Split into atomic_not_fetchsi_hard if operands[0] is unused.
	(atomic_fetch_<fetchop_name><mode>_hard): Convert to insn_and_split.
	Split into atomic_<fetchop_name><mode>_hard if operands[0] is unused.
	(atomic_fetch_not<mode>_hard): Convert to insn_and_split.  Split into
	atomic_not<mode>_hard if operands[0] is unused.
	(atomic_fetch_<fetchop_name><mode>_soft_gusa): Convert to
	insn_and_split.  Split into atomic_<fetchop_name>_fetch<mode>_soft_gusa
	if operands[0] is unused.
	(atomic_fetch_not<mode>_soft_gusa): Convert to insn_and_split.  Split
	into atomic_not_fetch<mode>_soft_gusa if operands[0] is unused.
	(atomic_fetch_<fetchop_name><mode>_soft_tcb): Convert to insn_and_split.
	Split into atomic_<fetchop_name><mode>_soft_tcb if operands[0] is
	unused.
	(atomic_fetch_not<mode>_soft_tcb): Convert to insn_and_split.  Split
	into atomic_not<mode>_soft_tcb if operands[0] is unused.
	(atomic_fetch_<fetchop_name><mode>_soft_imask): Convert to
	insn_and_split.  Split into atomic_<fetchop_name>_fetch<mode>_soft_imask
	if operands[0] is unused.
	(atomic_fetch_not<mode>_soft_imask): Convert to insn_and_split.  Split
	into atomic_not_fetch<mode>_soft_imask is operands[0] is unused.
	(atomic_fetch_nandsi_hard): Convert to insn_and_split.  Split into
	atomic_nand_fetchsi_hard if operands[0] is unused.
	(atomic_fetch_nand<mode>_hard): Convert to insn_and_split.  Split into
	atomic_nand<mode>_hard if operands[0] is unused.
	(atomic_fetch_nand<mode>_soft_gusa): Convert to insn_and_split.  Split
	into atomic_nand_fetch<mode>_soft_gusa if operands[0] is unused.
	(atomic_fetch_nand<mode>_soft_tcb): Convert to insn_and_split.  Split
	into atomic_nand<mode>_soft_tcb if operands[0] is unused.
	(atomic_fetch_nand<mode>_soft_imask): Convert to insn_and_split.  Split
	into atomic_nand_fetch<mode>_soft_imask if operands[0] is unused.
	(atomic_<fetchop_name>_fetch<mode>_hard): Convert to insn_and_split.
	Split into atomic_<fetchop_name><mode>_hard if operands[0] is unused.
	(atomic_not_fetch<mode>_hard): Convert to insn_and_split.  Split into
	atomic_not<mode>_hard if operands[0] is unused.
	(atomic_<fetchop_name>_fetch<mode>_soft_tcb): Convert to insn_and_split.
	Split into atomic_<fetchop_name><mode>_soft_tcb if operands[0] is
	unused.
	(atomic_not_fetch<mode>_soft_tcb): Convert to insn_and_split.  Split
	into atomic_not<mode>_soft_tcb if operands[0] is unused.
	(atomic_nand_fetch<mode>_hard): Convert to insn_and_split.  Split into
	atomic_nand<mode>_hard if operands[0] is unused.
	(atomic_nand_fetch<mode>_soft_tcb): Convert to insn_and_split.  Split
	into atomic_nand<mode>_soft_tcb if operands[0] is unused.

gcc/testsuite/
	PR target/64660
	* gcc.target/sh/pr64660-0.h: New.
	* gcc.target/sh/pr64660-1.c: New.
	* gcc.target/sh/pr64660-2.c: New.
	* gcc.target/sh/pr64660-3.c: New.
	* gcc.target/sh/pr64660-4.c: New.

From-SVN: r220376
This commit is contained in:
Oleg Endo 2015-02-03 20:24:13 +00:00
parent 0ed4f01761
commit 3548abca02
8 changed files with 473 additions and 21 deletions

View File

@ -1,3 +1,57 @@
2015-02-03 Oleg Endo <olegendo@gcc.gnu.org>
PR target/64660
* config/sh/sync.md (atomic_<fetchop_name><mode>_hard,
atomic_not<mode>_hard, atomic_<fetchop_name><mode>_soft_tcb,
atomic_not<mode>_soft_tcb, atomic_nand<mode>_hard,
atomic_nand<mode>_soft_tcb): New insns.
(atomic_fetch_<fetchop_name>si_hard): Convert to insn_and_split.
Split into atomic_<fetchop_name>_fetchsi_hard if operands[0] is unused.
(define_insn "atomic_fetch_notsi_hard): Convert to insn_and_split.
Split into atomic_not_fetchsi_hard if operands[0] is unused.
(atomic_fetch_<fetchop_name><mode>_hard): Convert to insn_and_split.
Split into atomic_<fetchop_name><mode>_hard if operands[0] is unused.
(atomic_fetch_not<mode>_hard): Convert to insn_and_split. Split into
atomic_not<mode>_hard if operands[0] is unused.
(atomic_fetch_<fetchop_name><mode>_soft_gusa): Convert to
insn_and_split. Split into atomic_<fetchop_name>_fetch<mode>_soft_gusa
if operands[0] is unused.
(atomic_fetch_not<mode>_soft_gusa): Convert to insn_and_split. Split
into atomic_not_fetch<mode>_soft_gusa if operands[0] is unused.
(atomic_fetch_<fetchop_name><mode>_soft_tcb): Convert to insn_and_split.
Split into atomic_<fetchop_name><mode>_soft_tcb if operands[0] is
unused.
(atomic_fetch_not<mode>_soft_tcb): Convert to insn_and_split. Split
into atomic_not<mode>_soft_tcb if operands[0] is unused.
(atomic_fetch_<fetchop_name><mode>_soft_imask): Convert to
insn_and_split. Split into atomic_<fetchop_name>_fetch<mode>_soft_imask
if operands[0] is unused.
(atomic_fetch_not<mode>_soft_imask): Convert to insn_and_split. Split
into atomic_not_fetch<mode>_soft_imask is operands[0] is unused.
(atomic_fetch_nandsi_hard): Convert to insn_and_split. Split into
atomic_nand_fetchsi_hard if operands[0] is unused.
(atomic_fetch_nand<mode>_hard): Convert to insn_and_split. Split into
atomic_nand<mode>_hard if operands[0] is unused.
(atomic_fetch_nand<mode>_soft_gusa): Convert to insn_and_split. Split
into atomic_nand_fetch<mode>_soft_gusa if operands[0] is unused.
(atomic_fetch_nand<mode>_soft_tcb): Convert to insn_and_split. Split
into atomic_nand<mode>_soft_tcb if operands[0] is unused.
(atomic_fetch_nand<mode>_soft_imask): Convert to insn_and_split. Split
into atomic_nand_fetch<mode>_soft_imask if operands[0] is unused.
(atomic_<fetchop_name>_fetch<mode>_hard): Convert to insn_and_split.
Split into atomic_<fetchop_name><mode>_hard if operands[0] is unused.
(atomic_not_fetch<mode>_hard): Convert to insn_and_split. Split into
atomic_not<mode>_hard if operands[0] is unused.
(atomic_<fetchop_name>_fetch<mode>_soft_tcb): Convert to insn_and_split.
Split into atomic_<fetchop_name><mode>_soft_tcb if operands[0] is
unused.
(atomic_not_fetch<mode>_soft_tcb): Convert to insn_and_split. Split
into atomic_not<mode>_soft_tcb if operands[0] is unused.
(atomic_nand_fetch<mode>_hard): Convert to insn_and_split. Split into
atomic_nand<mode>_hard if operands[0] is unused.
(atomic_nand_fetch<mode>_soft_tcb): Convert to insn_and_split. Split
into atomic_nand<mode>_soft_tcb if operands[0] is unused.
2015-02-03 David Malcolm <dmalcolm@redhat.com>
PR jit/64810

View File

@ -651,7 +651,7 @@
DONE;
})
(define_insn "atomic_fetch_<fetchop_name>si_hard"
(define_insn_and_split "atomic_fetch_<fetchop_name>si_hard"
[(set (match_operand:SI 0 "arith_reg_dest" "=&r")
(mem:SI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:SI (match_dup 1))
@ -670,11 +670,18 @@
" <fetchop_name> %2,r0" "\n"
" movco.l r0,@%1" "\n"
" bf 0b";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_<fetchop_name>_fetchsi_hard (gen_reg_rtx (SImode),
operands[1], operands[2]));
}
[(set_attr "length" "10")])
;; Combine pattern for xor (val, -1) / nand (val, -1).
(define_insn "atomic_fetch_notsi_hard"
(define_insn_and_split "atomic_fetch_notsi_hard"
[(set (match_operand:SI 0 "arith_reg_dest" "=&r")
(mem:SI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:SI (match_dup 1))
@ -689,10 +696,16 @@
" not r0,r0" "\n"
" movco.l r0,@%1" "\n"
" bf 0b";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_not_fetchsi_hard (gen_reg_rtx (SImode), operands[1]));
}
[(set_attr "length" "10")])
(define_insn "atomic_fetch_<fetchop_name><mode>_hard"
(define_insn_and_split "atomic_fetch_<fetchop_name><mode>_hard"
[(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
(mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:QIHI (match_dup 1))
@ -721,11 +734,46 @@
" mov.l @r15+,r0" "\n"
" movco.l r0,@%3" "\n"
" bf 0b";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_<fetchop_name><mode>_hard (operands[1], operands[2]));
}
[(set_attr "length" "28")])
(define_insn "atomic_<fetchop_name><mode>_hard"
[(set (mem:QIHI (match_operand:SI 0 "arith_reg_operand" "r"))
(unspec:QIHI
[(FETCHOP:QIHI (mem:QIHI (match_dup 0))
(match_operand:QIHI 1 "<fetchop_predicate_1>"
"<fetchop_constraint_1_llcs>"))]
UNSPEC_ATOMIC))
(set (reg:SI T_REG) (const_int 1))
(clobber (reg:SI R0_REG))
(clobber (match_scratch:SI 2 "=&r"))
(clobber (match_scratch:SI 3 "=0"))]
"TARGET_ATOMIC_HARD_LLCS"
{
return "\r mov #-4,%2" "\n"
" and %0,%2" "\n"
" xor %2,%0" "\n"
" add r15,%0" "\n"
" add #-4,%0" "\n"
"0: movli.l @%2,r0" "\n"
" mov.l r0,@-r15" "\n"
" mov.<bw> @%0,r0" "\n"
" <fetchop_name> %1,r0" "\n"
" mov.<bw> r0,@%0" "\n"
" mov.l @r15+,r0" "\n"
" movco.l r0,@%2" "\n"
" bf 0b";
}
[(set_attr "length" "26")])
;; Combine pattern for xor (val, -1) / nand (val, -1).
(define_insn "atomic_fetch_not<mode>_hard"
(define_insn_and_split "atomic_fetch_not<mode>_hard"
[(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
(mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:QIHI (match_dup 1))
@ -749,10 +797,41 @@
" mov.l @r15+,r0" "\n"
" movco.l r0,@%2" "\n"
" bf 0b";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_not<mode>_hard (operands[1]));
}
[(set_attr "length" "26")])
(define_insn "atomic_fetch_<fetchop_name><mode>_soft_gusa"
(define_insn "atomic_not<mode>_hard"
[(set (mem:QIHI (match_operand:SI 0 "arith_reg_operand" "r"))
(unspec:QIHI [(not:QIHI (mem:QIHI (match_dup 0)))] UNSPEC_ATOMIC))
(set (reg:SI T_REG) (const_int 1))
(clobber (reg:SI R0_REG))
(clobber (match_scratch:SI 1 "=&r"))
(clobber (match_scratch:SI 2 "=0"))]
"TARGET_ATOMIC_HARD_LLCS"
{
return "\r mov #-4,%1" "\n"
" and %0,%1" "\n"
" xor %1,%0" "\n"
" add r15,%0" "\n"
" add #-4,%0" "\n"
"0: movli.l @%1,r0" "\n"
" mov.l r0,@-r15" "\n"
" mov.<bw> @%0,r0" "\n"
" not r0,r0" "\n"
" mov.<bw> r0,@%0" "\n"
" mov.l @r15+,r0" "\n"
" movco.l r0,@%1" "\n"
" bf 0b";
}
[(set_attr "length" "26")])
(define_insn_and_split "atomic_fetch_<fetchop_name><mode>_soft_gusa"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u")
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u")))
(set (mem:QIHISI (match_dup 1))
@ -776,11 +855,18 @@
" <fetchop_name> %2,%3" "\n"
" mov.<bwl> %3,@%1" "\n"
"1: mov r1,r15";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_<fetchop_name>_fetch<mode>_soft_gusa (
gen_reg_rtx (<MODE>mode), operands[1], operands[2]));
}
[(set_attr "length" "18")])
;; Combine pattern for xor (val, -1) / nand (val, -1).
(define_insn "atomic_fetch_not<mode>_soft_gusa"
(define_insn_and_split "atomic_fetch_not<mode>_soft_gusa"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u")
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u")))
(set (mem:QIHISI (match_dup 1))
@ -798,10 +884,17 @@
" not %0,%2" "\n"
" mov.<bwl> %2,@%1" "\n"
"1: mov r1,r15";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_not_fetch<mode>_soft_gusa (gen_reg_rtx (<MODE>mode),
operands[1]));
}
[(set_attr "length" "16")])
(define_insn "atomic_fetch_<fetchop_name><mode>_soft_tcb"
(define_insn_and_split "atomic_fetch_<fetchop_name><mode>_soft_tcb"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:QIHISI (match_dup 1))
@ -826,11 +919,43 @@
" mov.<bwl> r0,@%1" "\n"
"1: mov #0,r0" "\n"
" mov.l r0,@(%O3,gbr)";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_<fetchop_name><mode>_soft_tcb (
operands[1], operands[2], operands[3]));
}
[(set_attr "length" "20")])
(define_insn "atomic_<fetchop_name><mode>_soft_tcb"
[(set (mem:QIHISI (match_operand:SI 0 "arith_reg_operand" "r"))
(unspec:QIHISI
[(FETCHOP:QIHISI
(mem:QIHISI (match_dup 0))
(match_operand:QIHISI 1 "<fetchop_predicate_1>"
"<fetchop_constraint_1_tcb>"))]
UNSPEC_ATOMIC))
(use (match_operand:SI 2 "gbr_displacement"))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))]
"TARGET_ATOMIC_SOFT_TCB"
{
return "\r mova 1f,r0" "\n"
" mov #(0f-1f),r1" "\n"
" .align 2" "\n"
" mov.l r0,@(%O2,gbr)" "\n"
"0: mov.<bwl> @%0,r0" "\n"
" <fetchop_name> %1,r0" "\n"
" mov.<bwl> r0,@%0" "\n"
"1: mov #0,r0" "\n"
" mov.l r0,@(%O2,gbr)";
}
[(set_attr "length" "18")])
;; Combine pattern for xor (val, -1) / nand (val, -1).
(define_insn "atomic_fetch_not<mode>_soft_tcb"
(define_insn_and_split "atomic_fetch_not<mode>_soft_tcb"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:QIHISI (match_dup 1))
@ -850,10 +975,36 @@
" mov.<bwl> r0,@%1" "\n"
"1: mov #0,r0" "\n"
" mov.l r0,@(%O2,gbr)";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_not<mode>_soft_tcb (operands[1], operands[2]));
}
[(set_attr "length" "20")])
(define_insn "atomic_fetch_<fetchop_name><mode>_soft_imask"
(define_insn "atomic_not<mode>_soft_tcb"
[(set (mem:QIHISI (match_operand:SI 0 "arith_reg_operand" "r"))
(unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 0)))] UNSPEC_ATOMIC))
(use (match_operand:SI 1 "gbr_displacement"))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))]
"TARGET_ATOMIC_SOFT_TCB"
{
return "\r mova 1f,r0" "\n"
" mov #(0f-1f),r1" "\n"
" .align 2" "\n"
" mov.l r0,@(%O1,gbr)" "\n"
"0: mov.<bwl> @%0,r0" "\n"
" not r0,r0" "\n"
" mov.<bwl> r0,@%0" "\n"
"1: mov #0,r0" "\n"
" mov.l r0,@(%O1,gbr)";
}
[(set_attr "length" "18")])
(define_insn_and_split "atomic_fetch_<fetchop_name><mode>_soft_imask"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:QIHISI (match_dup 1))
@ -876,11 +1027,18 @@
" <fetchop_name> %2,r0" "\n"
" mov.<bwl> r0,@%1" "\n"
" ldc %3,sr";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_<fetchop_name>_fetch<mode>_soft_imask (
gen_reg_rtx (<MODE>mode), operands[1], operands[2]));
}
[(set_attr "length" "18")])
;; Combine pattern for xor (val, -1) / nand (val, -1).
(define_insn "atomic_fetch_not<mode>_soft_imask"
(define_insn_and_split "atomic_fetch_not<mode>_soft_imask"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:QIHISI (match_dup 1))
@ -898,6 +1056,13 @@
" not r0,r0" "\n"
" mov.<bwl> r0,@%1" "\n"
" ldc %2,sr";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_not_fetch<mode>_soft_imask (gen_reg_rtx (<MODE>mode),
operands[1]));
}
[(set_attr "length" "18")])
@ -942,7 +1107,7 @@
DONE;
})
(define_insn "atomic_fetch_nandsi_hard"
(define_insn_and_split "atomic_fetch_nandsi_hard"
[(set (match_operand:SI 0 "arith_reg_dest" "=&r")
(mem:SI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:SI (match_dup 1))
@ -961,10 +1126,17 @@
" not r0,r0" "\n"
" movco.l r0,@%1" "\n"
" bf 0b";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_nand_fetchsi_hard (gen_reg_rtx (SImode), operands[1],
operands[2]));
}
[(set_attr "length" "12")])
(define_insn "atomic_fetch_nand<mode>_hard"
(define_insn_and_split "atomic_fetch_nand<mode>_hard"
[(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
(mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:QIHI (match_dup 1))
@ -993,10 +1165,45 @@
" mov.l @r15+,r0" "\n"
" movco.l r0,@%3" "\n"
" bf 0b";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_nand<mode>_hard (operands[1], operands[2]));
}
[(set_attr "length" "30")])
(define_insn "atomic_fetch_nand<mode>_soft_gusa"
(define_insn "atomic_nand<mode>_hard"
[(set (mem:QIHI (match_operand:SI 0 "arith_reg_operand" "r"))
(unspec:QIHI
[(not:QIHI (and:QIHI (mem:QIHI (match_dup 0))
(match_operand:QIHI 1 "logical_operand" "rK08")))]
UNSPEC_ATOMIC))
(set (reg:SI T_REG) (const_int 1))
(clobber (reg:SI R0_REG))
(clobber (match_scratch:SI 2 "=&r"))
(clobber (match_scratch:SI 3 "=0"))]
"TARGET_ATOMIC_HARD_LLCS"
{
return "\r mov #-4,%2" "\n"
" and %0,%2" "\n"
" xor %2,%0" "\n"
" add r15,%0" "\n"
" add #-4,%0" "\n"
"0: movli.l @%2,r0" "\n"
" mov.l r0,@-r15" "\n"
" mov.<bw> @%0,r0" "\n"
" and %1,r0" "\n"
" not r0,r0" "\n"
" mov.<bw> r0,@%0" "\n"
" mov.l @r15+,r0" "\n"
" movco.l r0,@%2" "\n"
" bf 0b";
}
[(set_attr "length" "28")])
(define_insn_and_split "atomic_fetch_nand<mode>_soft_gusa"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u")
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u")))
(set (mem:QIHISI (match_dup 1))
@ -1020,10 +1227,17 @@
" not %3,%3" "\n"
" mov.<bwl> %3,@%1" "\n"
"1: mov r1,r15";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_nand_fetch<mode>_soft_gusa (gen_reg_rtx (<MODE>mode),
operands[1], operands[2]));
}
[(set_attr "length" "20")])
(define_insn "atomic_fetch_nand<mode>_soft_tcb"
(define_insn_and_split "atomic_fetch_nand<mode>_soft_tcb"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:QIHISI (match_dup 1))
@ -1048,10 +1262,42 @@
" mov.<bwl> r0,@%1" "\n"
"1: mov #0,r0" "\n"
" mov.l r0,@(%O3,gbr)";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_nand<mode>_soft_tcb (operands[1], operands[2],
operands[3]));
}
[(set_attr "length" "22")])
(define_insn "atomic_fetch_nand<mode>_soft_imask"
(define_insn "atomic_nand<mode>_soft_tcb"
[(set (mem:QIHISI (match_operand:SI 0 "arith_reg_operand" "r"))
(unspec:QIHISI
[(not:QIHISI
(and:QIHISI (mem:QIHISI (match_dup 0))
(match_operand:QIHISI 1 "logical_operand" "rK08")))]
UNSPEC_ATOMIC))
(use (match_operand:SI 2 "gbr_displacement"))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))]
"TARGET_ATOMIC_SOFT_TCB"
{
return "\r mova 1f,r0" "\n"
" .align 2" "\n"
" mov #(0f-1f),r1" "\n"
" mov.l r0,@(%O2,gbr)" "\n"
"0: mov.<bwl> @%0,r0" "\n"
" and %1,r0" "\n"
" not r0,r0" "\n"
" mov.<bwl> r0,@%0" "\n"
"1: mov #0,r0" "\n"
" mov.l r0,@(%O2,gbr)";
}
[(set_attr "length" "20")])
(define_insn_and_split "atomic_fetch_nand<mode>_soft_imask"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
(set (mem:QIHISI (match_dup 1))
@ -1074,6 +1320,13 @@
" not r0,r0" "\n"
" mov.<bwl> r0,@%1" "\n"
" ldc %3,sr";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_nand_fetch<mode>_soft_imask (gen_reg_rtx (<MODE>mode),
operands[1], operands[2]));
}
[(set_attr "length" "20")])
@ -1160,7 +1413,7 @@
}
[(set_attr "length" "8")])
(define_insn "atomic_<fetchop_name>_fetch<mode>_hard"
(define_insn_and_split "atomic_<fetchop_name>_fetch<mode>_hard"
[(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
(FETCHOP:QIHI
(mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r"))
@ -1190,11 +1443,17 @@
" mov.l @r15+,r0" "\n"
" movco.l r0,@%3" "\n"
" bf 0b";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_<fetchop_name><mode>_hard (operands[1], operands[2]));
}
[(set_attr "length" "28")])
;; Combine pattern for xor (val, -1) / nand (val, -1).
(define_insn "atomic_not_fetch<mode>_hard"
(define_insn_and_split "atomic_not_fetch<mode>_hard"
[(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
(not:QIHI (mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r"))))
(set (mem:QIHI (match_dup 1))
@ -1219,6 +1478,12 @@
" mov.l @r15+,r0" "\n"
" movco.l r0,@%2" "\n"
" bf 0b";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_not<mode>_hard (operands[1]));
}
[(set_attr "length" "28")])
@ -1268,7 +1533,7 @@
}
[(set_attr "length" "16")])
(define_insn "atomic_<fetchop_name>_fetch<mode>_soft_tcb"
(define_insn_and_split "atomic_<fetchop_name>_fetch<mode>_soft_tcb"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
(FETCHOP:QIHISI
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))
@ -1293,11 +1558,18 @@
"1: mov r0,%0" "\n"
" mov #0,r0" "\n"
" mov.l r0,@(%O3,gbr)";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_<fetchop_name><mode>_soft_tcb (
operands[1], operands[2], operands[3]));
}
[(set_attr "length" "20")])
;; Combine pattern for xor (val, -1) / nand (val, -1).
(define_insn "atomic_not_fetch<mode>_soft_tcb"
(define_insn_and_split "atomic_not_fetch<mode>_soft_tcb"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
(not:QIHISI (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))))
(set (mem:QIHISI (match_dup 1))
@ -1317,6 +1589,12 @@
"1: mov r0,%0" "\n"
" mov #0,r0" "\n"
" mov.l r0,@(%O2,gbr)";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_not<mode>_soft_tcb (operands[1], operands[2]));
}
[(set_attr "length" "20")])
@ -1426,7 +1704,7 @@
}
[(set_attr "length" "10")])
(define_insn "atomic_nand_fetch<mode>_hard"
(define_insn_and_split "atomic_nand_fetch<mode>_hard"
[(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
(not:QIHI
(and:QIHI (mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r"))
@ -1455,6 +1733,12 @@
" mov.l @r15+,r0" "\n"
" movco.l r0,@%3" "\n"
" bf 0b";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_nand<mode>_hard (operands[1], operands[2]));
}
[(set_attr "length" "28")])
@ -1483,7 +1767,7 @@
}
[(set_attr "length" "18")])
(define_insn "atomic_nand_fetch<mode>_soft_tcb"
(define_insn_and_split "atomic_nand_fetch<mode>_soft_tcb"
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
(not:QIHISI (and:QIHISI
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))
@ -1508,6 +1792,13 @@
" mov.<bwl> r0,@%1" "\n"
"1: mov #0,r0" "\n"
" mov.l r0,@(%O3,gbr)";
}
"&& can_create_pseudo_p () && optimize
&& sh_reg_dead_or_unused_after_insn (insn, REGNO (operands[0]))"
[(const_int 0)]
{
emit_insn (gen_atomic_nand<mode>_soft_tcb (operands[1], operands[2],
operands[3]));
}
[(set_attr "length" "22")])

View File

@ -1,3 +1,12 @@
2015-02-03 Oleg Endo <olegendo@gcc.gnu.org>
PR target/64660
* gcc.target/sh/pr64660-0.h: New.
* gcc.target/sh/pr64660-1.c: New.
* gcc.target/sh/pr64660-2.c: New.
* gcc.target/sh/pr64660-3.c: New.
* gcc.target/sh/pr64660-4.c: New.
2015-02-03 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/64877

View File

@ -0,0 +1,44 @@
/* Check that the appropriate atomic insns are used if the result values
are unused. */
#define concat_1(x, y) x ## y
#define concat(x, y) concat_1 (x, y)
#define makefuncname(name) concat (concat (test_, __LINE__), name)
#define emitfuncs(name,val)\
void makefuncname (_0) (char* mem)\
{\
name (mem, val, __ATOMIC_ACQ_REL);\
}\
void makefuncname (_1) (short* mem)\
{\
name (mem, val, __ATOMIC_ACQ_REL);\
}\
void makefuncname (_2) (int* mem)\
{\
name (mem, val, __ATOMIC_ACQ_REL);\
}\
emitfuncs (__atomic_add_fetch, 1)
emitfuncs (__atomic_fetch_add, 1)
emitfuncs (__atomic_sub_fetch, 1)
emitfuncs (__atomic_fetch_sub, 1)
emitfuncs (__atomic_and_fetch, 1)
emitfuncs (__atomic_fetch_and, 1)
emitfuncs (__atomic_or_fetch, 1)
emitfuncs (__atomic_fetch_or, 1)
emitfuncs (__atomic_xor_fetch, 1)
emitfuncs (__atomic_fetch_xor, 1)
emitfuncs (__atomic_nand_fetch, 1)
emitfuncs (__atomic_fetch_nand, 1)
emitfuncs (__atomic_xor_fetch, -1)
emitfuncs (__atomic_fetch_xor, -1)
emitfuncs (__atomic_nand_fetch, -1)
emitfuncs (__atomic_fetch_nand, -1)

View File

@ -0,0 +1,12 @@
/* Check that the appropriate atomic insns are used if the result values
are unused. */
/* { dg-do compile { target { atomic_model_soft_gusa_available } } } */
/* { dg-options "-dp -O2 -matomic-model=soft-gusa,strict" } */
/* { dg-final { scan-assembler-times "atomic_add_fetch" 12 } } */
/* { dg-final { scan-assembler-times "atomic_and_fetch" 6 } } */
/* { dg-final { scan-assembler-times "atomic_or_fetch" 6 } } */
/* { dg-final { scan-assembler-times "atomic_xor_fetch" 6 } } */
/* { dg-final { scan-assembler-times "atomic_nand_fetch" 6 } } */
/* { dg-final { scan-assembler-times "atomic_not_fetch" 12 } } */
#include "pr64660-0.h"

View File

@ -0,0 +1,13 @@
/* Check that the appropriate atomic insns are used if the result values
are unused. */
/* { dg-do compile { target { atomic_model_soft_tcb_available } } } */
/* { dg-options "-dp -O2 -matomic-model=soft-tcb,gbr-offset=0,strict" } */
/* { dg-final { scan-assembler-times "atomic_add" 12 } } */
/* { dg-final { scan-assembler-times "atomic_and" 6 } } */
/* { dg-final { scan-assembler-times "atomic_or" 6 } } */
/* { dg-final { scan-assembler-times "atomic_xor" 6 } } */
/* { dg-final { scan-assembler-times "atomic_nand" 6 } } */
/* { dg-final { scan-assembler-times "atomic_not" 12 } } */
/* { dg-final { scan-assembler-not "fetch" } } */
#include "pr64660-0.h"

View File

@ -0,0 +1,12 @@
/* Check that the appropriate atomic insns are used if the result values
are unused. */
/* { dg-do compile { target { atomic_model_soft_imask_available } } } */
/* { dg-options "-dp -O2 -matomic-model=soft-imask,strict -mno-usermode" } */
/* { dg-final { scan-assembler-times "atomic_add_fetch" 12 } } */
/* { dg-final { scan-assembler-times "atomic_and_fetch" 6 } } */
/* { dg-final { scan-assembler-times "atomic_or_fetch" 6 } } */
/* { dg-final { scan-assembler-times "atomic_xor_fetch" 6 } } */
/* { dg-final { scan-assembler-times "atomic_nand_fetch" 6 } } */
/* { dg-final { scan-assembler-times "atomic_not_fetch" 12 } } */
#include "pr64660-0.h"

View File

@ -0,0 +1,17 @@
/* Check that atomic not ops are generated. */
/* { dg-do compile { target { atomic_model_hard_llcs_available } } } */
/* { dg-options "-dp -O2 -matomic-model=hard-llcs,strict" } */
/* { dg-final { scan-assembler-times "atomic_add" 12 } } */
/* { dg-final { scan-assembler-times "atomic_add_fetch" 4 } } */
/* { dg-final { scan-assembler-times "atomic_and" 6 } } */
/* { dg-final { scan-assembler-times "atomic_and_fetch" 2 } } */
/* { dg-final { scan-assembler-times "atomic_or" 6 } } */
/* { dg-final { scan-assembler-times "atomic_or_fetch" 2 } } */
/* { dg-final { scan-assembler-times "atomic_xor" 6 } } */
/* { dg-final { scan-assembler-times "atomic_xor_fetch" 2 } } */
/* { dg-final { scan-assembler-times "atomic_nand" 6 } } */
/* { dg-final { scan-assembler-times "atomic_nand_fetch" 2 } } */
/* { dg-final { scan-assembler-times "atomic_not" 12 } } */
/* { dg-final { scan-assembler-times "atomic_not_fetch" 4 } } */
#include "pr64660-0.h"