diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2015-02-03 20:24:13 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2015-02-03 20:24:13 +0000 |
commit | 3548abca0218168da1bb9f8cace29282a7495fbf (patch) | |
tree | c47a87d39f9c500a700aef5ef93d27e45d2c70ec | |
parent | 0ed4f01761116587a0aac7faae8512d6e73eeed0 (diff) | |
download | gcc-3548abca0218168da1bb9f8cace29282a7495fbf.zip gcc-3548abca0218168da1bb9f8cace29282a7495fbf.tar.gz gcc-3548abca0218168da1bb9f8cace29282a7495fbf.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 54 | ||||
-rw-r--r-- | gcc/config/sh/sync.md | 333 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr64660-0.h | 44 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr64660-1.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr64660-2.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr64660-3.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr64660-4.c | 17 |
8 files changed, 473 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d1f628..98c968e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/sh/sync.md b/gcc/config/sh/sync.md index 089a628..d1413c5 100644 --- a/gcc/config/sh/sync.md +++ b/gcc/config/sh/sync.md @@ -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)) @@ -671,10 +671,17 @@ " 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)) @@ -690,9 +697,15 @@ " 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)) @@ -722,10 +735,45 @@ " 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)) @@ -750,9 +798,40 @@ " 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_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 "atomic_fetch_<fetchop_name><mode>_soft_gusa" +(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)) @@ -777,10 +856,17 @@ " 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)) @@ -799,9 +885,16 @@ " 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)) @@ -827,10 +920,42 @@ "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)) @@ -851,9 +976,35 @@ "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)) @@ -877,10 +1028,17 @@ " 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)) @@ -899,6 +1057,13 @@ " 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")]) (define_expand "atomic_fetch_nand<mode>" @@ -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)) @@ -962,9 +1127,16 @@ " 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)) @@ -994,9 +1166,44 @@ " 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)) @@ -1021,9 +1228,16 @@ " 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)) @@ -1049,9 +1263,41 @@ "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)) @@ -1075,6 +1321,13 @@ " 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")) @@ -1191,10 +1444,16 @@ " 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)) @@ -1220,6 +1479,12 @@ " 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")]) (define_insn "atomic_<fetchop_name>_fetch<mode>_soft_gusa" @@ -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")) @@ -1294,10 +1559,17 @@ " 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)) @@ -1318,6 +1590,12 @@ " 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_<fetchop_name>_fetch<mode>_soft_imask" @@ -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")) @@ -1456,6 +1734,12 @@ " 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")]) (define_insn "atomic_nand_fetch<mode>_soft_gusa" @@ -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")) @@ -1509,6 +1793,13 @@ "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_nand_fetch<mode>_soft_imask" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 00c0450..98d72cb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.target/sh/pr64660-0.h b/gcc/testsuite/gcc.target/sh/pr64660-0.h new file mode 100644 index 0000000..28c1ac6 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr64660-0.h @@ -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) diff --git a/gcc/testsuite/gcc.target/sh/pr64660-1.c b/gcc/testsuite/gcc.target/sh/pr64660-1.c new file mode 100644 index 0000000..2d5442c --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr64660-1.c @@ -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" diff --git a/gcc/testsuite/gcc.target/sh/pr64660-2.c b/gcc/testsuite/gcc.target/sh/pr64660-2.c new file mode 100644 index 0000000..c0cef13 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr64660-2.c @@ -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" diff --git a/gcc/testsuite/gcc.target/sh/pr64660-3.c b/gcc/testsuite/gcc.target/sh/pr64660-3.c new file mode 100644 index 0000000..fe3a83d --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr64660-3.c @@ -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" diff --git a/gcc/testsuite/gcc.target/sh/pr64660-4.c b/gcc/testsuite/gcc.target/sh/pr64660-4.c new file mode 100644 index 0000000..4d5d7f4 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr64660-4.c @@ -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" |