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:
parent
0ed4f01761
commit
3548abca02
@ -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
|
||||
|
@ -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")])
|
||||
|
||||
|
@ -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
|
||||
|
44
gcc/testsuite/gcc.target/sh/pr64660-0.h
Normal file
44
gcc/testsuite/gcc.target/sh/pr64660-0.h
Normal 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)
|
12
gcc/testsuite/gcc.target/sh/pr64660-1.c
Normal file
12
gcc/testsuite/gcc.target/sh/pr64660-1.c
Normal 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"
|
13
gcc/testsuite/gcc.target/sh/pr64660-2.c
Normal file
13
gcc/testsuite/gcc.target/sh/pr64660-2.c
Normal 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"
|
12
gcc/testsuite/gcc.target/sh/pr64660-3.c
Normal file
12
gcc/testsuite/gcc.target/sh/pr64660-3.c
Normal 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"
|
17
gcc/testsuite/gcc.target/sh/pr64660-4.c
Normal file
17
gcc/testsuite/gcc.target/sh/pr64660-4.c
Normal 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"
|
Loading…
Reference in New Issue
Block a user