mirror of git://gcc.gnu.org/git/gcc.git
re PR target/64659 ([SH] Immedate values not used for atomic ops)
gcc/ PR target/64659 * config/sh/predicates.md (atomic_arith_operand, atomic_logical_operand): Remove. * config/sh/sync.md (fetchop_predicate, fetchop_constraint): Remove. (atomic_arith_operand_0): New predicate. (atomic_compare_and_swap<mode>): Use arith_reg_dest for output values. Use atomic_arith_operand_0 for input values. (atomic_compare_and_swapsi_hard, atomic_compare_and_swap<mode>_hard, atomic_compare_and_swap<mode>_soft_gusa, atomic_compare_and_swap<mode>_soft_tcb, atomic_compare_and_swap<mode>_soft_imask): Use arith_reg_dest and arith_reg_operand instead of register_operand. (atomic_exchange<mode>): Use arith_reg_dest for output value. Use atomic_arith_operand_0 for newval input. (atomic_exchangesi_hard, atomic_exchange<mode>_hard, atomic_exchange<mode>_soft_gusa, atomic_exchange<mode>_soft_tcb, atomic_exchange<mode>_soft_imask): Use arith_reg_dest and arith_reg_operand instead of register_operand. (atomic_arith_operand_1, atomic_logical_operand_1): New predicates. fetchop_predicate_1, fetchop_constraint_1_llcs, fetchop_constraint_1_gusa, fetchop_constraint_1_tcb, fetchop_constraint_1_imask): New code iterator attributes. (atomic_fetch_<fetchop_name><mode>): Use arith_reg_dest instead of register_operand. Use fetchop_predicate_1. (atomic_fetch_<fetchop_name>si_hard, atomic_fetch_<fetchop_name><mode>_hard): Use arith_reg_dest instead of register_operand. Use fetchop_predicate_1, fetchop_constraint_1_llcs. (atomic_fetch_<fetchop_name><mode>_soft_gusa): Use arith_reg_dest and arith_reg_operand instead of register_operand. Use fetchop_predicate_1, fetchop_constraint_1_gusa. (atomic_fetch_<fetchop_name><mode>_soft_tcb): Use arith_reg_dest and arith_reg_operand instead of register_operand. Use fetchop_predicate_1, fetchop_constraint_1_tcb. Adjust asm sequence to allow R0 usage. (atomic_fetch_<fetchop_name><mode>_soft_imask): Use arith_reg_dest and arith_reg_operand instead of register_operand. Use fetchop_predicate_1, fetchop_constraint_1_imask. Adjust asm sequence to allow R0 usage. (atomic_fetch_nand<mode>): Use arith_reg_dest instead of register_operand. Use atomic_logical_operand_1. (atomic_fetch_nandsi_hard, atomic_fetch_nand<mode>_hard, atomic_fetch_nand<mode>_soft_gusa): Use arith_reg_dest and arith_reg_operand instead of register_operand. (atomic_fetch_nand<mode>_soft_tcb, atomic_fetch_nand<mode>_soft_imask): Use arith_reg_dest and arith_reg_operand instead of register_operand. Use logical_operand and rK08. Adjust asm sequence to allow R0 usage. (atomic_<fetchop_name>_fetch<mode>): Use arith_reg_dest instead of register_operand. Use fetchop_predicate_1. (atomic_<fetchop_name>_fetchsi_hard, atomic_<fetchop_name>_fetch<mode>_hard): Use arith_reg_dest and arith_reg_operand instead of register_operand. Use fetchop_predicate_1, fetchop_constraint_1_llcs. (atomic_<fetchop_name>_fetch<mode>_soft_gusa): Use arith_reg_dest and arith_reg_operand instead of register_operand. Use fetchop_predicate_1, fetchop_constraint_1_gusa. (atomic_<fetchop_name>_fetch<mode>_soft_tcb): Use arith_reg_dest and arith_reg_operand instead of register_operand. Use fetchop_predicate_1, fetchop_constraint_1_tcb. Adjust asm sequence to allow R0 usage. (atomic_<fetchop_name>_fetch<mode>_soft_imask): Use arith_reg_dest and arith_reg_operand instead of register_operand. Use fetchop_predicate_1, fetchop_constraint_1_imask. Adjust asm sequence to allow R0 usage. (atomic_nand_fetch<mode>): Use arith_reg_dest instead of register_operand. Use atomic_logical_operand_1. (atomic_nand_fetchsi_hard, atomic_nand_fetch<mode>_hard, atomic_nand_fetch<mode>_soft_gusa): Use arith_reg_dest and arith_reg_operand instead of register_operand. (atomic_nand_fetch<mode>_soft_tcb): Use arith_reg_dest and arith_reg_operand instead of register_operand. Use logical_operand and K08. Adjust asm sequence to allow R0 usage. (atomic_nand_fetch<mode>_soft_imask): Use arith_reg_dest and arith_reg_operand instead of register_operand. Use logical_operand and K08. gcc/testsuite/ PR target/64659 * gcc.target/sh/sh.exp (check_effective_target_atomic_model_soft_gusa_available, check_effective_target_atomic_model_soft_tcb_available, check_effective_target_atomic_model_soft_imask_available, check_effective_target_atomic_model_hard_llcs_available): New. * gcc.target/sh/pr64659-0.h: New. * gcc.target/sh/pr64659-1.c: New. * gcc.target/sh/pr64659-2.c: New. * gcc.target/sh/pr64659-3.c: New. * gcc.target/sh/pr64659-4.c: New. From-SVN: r220217
This commit is contained in:
parent
13a48f3780
commit
c761dca15e
|
|
@ -1,3 +1,78 @@
|
|||
2015-01-28 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
PR target/64659
|
||||
* config/sh/predicates.md (atomic_arith_operand,
|
||||
atomic_logical_operand): Remove.
|
||||
* config/sh/sync.md (fetchop_predicate, fetchop_constraint): Remove.
|
||||
(atomic_arith_operand_0): New predicate.
|
||||
(atomic_compare_and_swap<mode>): Use arith_reg_dest for output values.
|
||||
Use atomic_arith_operand_0 for input values.
|
||||
(atomic_compare_and_swapsi_hard, atomic_compare_and_swap<mode>_hard,
|
||||
atomic_compare_and_swap<mode>_soft_gusa,
|
||||
atomic_compare_and_swap<mode>_soft_tcb,
|
||||
atomic_compare_and_swap<mode>_soft_imask): Use arith_reg_dest and
|
||||
arith_reg_operand instead of register_operand.
|
||||
(atomic_exchange<mode>): Use arith_reg_dest for output value. Use
|
||||
atomic_arith_operand_0 for newval input.
|
||||
(atomic_exchangesi_hard, atomic_exchange<mode>_hard,
|
||||
atomic_exchange<mode>_soft_gusa, atomic_exchange<mode>_soft_tcb,
|
||||
atomic_exchange<mode>_soft_imask): Use arith_reg_dest and
|
||||
arith_reg_operand instead of register_operand.
|
||||
(atomic_arith_operand_1, atomic_logical_operand_1): New predicates.
|
||||
fetchop_predicate_1, fetchop_constraint_1_llcs,
|
||||
fetchop_constraint_1_gusa, fetchop_constraint_1_tcb,
|
||||
fetchop_constraint_1_imask): New code iterator attributes.
|
||||
(atomic_fetch_<fetchop_name><mode>): Use arith_reg_dest instead of
|
||||
register_operand. Use fetchop_predicate_1.
|
||||
(atomic_fetch_<fetchop_name>si_hard,
|
||||
atomic_fetch_<fetchop_name><mode>_hard): Use arith_reg_dest instead of
|
||||
register_operand. Use fetchop_predicate_1, fetchop_constraint_1_llcs.
|
||||
(atomic_fetch_<fetchop_name><mode>_soft_gusa): Use arith_reg_dest
|
||||
and arith_reg_operand instead of register_operand. Use
|
||||
fetchop_predicate_1, fetchop_constraint_1_gusa.
|
||||
(atomic_fetch_<fetchop_name><mode>_soft_tcb): Use arith_reg_dest
|
||||
and arith_reg_operand instead of register_operand. Use
|
||||
fetchop_predicate_1, fetchop_constraint_1_tcb. Adjust asm sequence
|
||||
to allow R0 usage.
|
||||
(atomic_fetch_<fetchop_name><mode>_soft_imask): Use arith_reg_dest
|
||||
and arith_reg_operand instead of register_operand. Use
|
||||
fetchop_predicate_1, fetchop_constraint_1_imask. Adjust asm sequence
|
||||
to allow R0 usage.
|
||||
(atomic_fetch_nand<mode>): Use arith_reg_dest instead of
|
||||
register_operand. Use atomic_logical_operand_1.
|
||||
(atomic_fetch_nandsi_hard, atomic_fetch_nand<mode>_hard,
|
||||
atomic_fetch_nand<mode>_soft_gusa): Use arith_reg_dest and
|
||||
arith_reg_operand instead of register_operand.
|
||||
(atomic_fetch_nand<mode>_soft_tcb, atomic_fetch_nand<mode>_soft_imask):
|
||||
Use arith_reg_dest and arith_reg_operand instead of register_operand.
|
||||
Use logical_operand and rK08. Adjust asm sequence to allow R0 usage.
|
||||
(atomic_<fetchop_name>_fetch<mode>): Use arith_reg_dest instead of
|
||||
register_operand. Use fetchop_predicate_1.
|
||||
(atomic_<fetchop_name>_fetchsi_hard,
|
||||
atomic_<fetchop_name>_fetch<mode>_hard): Use arith_reg_dest and
|
||||
arith_reg_operand instead of register_operand. Use fetchop_predicate_1,
|
||||
fetchop_constraint_1_llcs.
|
||||
(atomic_<fetchop_name>_fetch<mode>_soft_gusa): Use arith_reg_dest and
|
||||
arith_reg_operand instead of register_operand. Use fetchop_predicate_1,
|
||||
fetchop_constraint_1_gusa.
|
||||
(atomic_<fetchop_name>_fetch<mode>_soft_tcb): Use arith_reg_dest and
|
||||
arith_reg_operand instead of register_operand. Use fetchop_predicate_1,
|
||||
fetchop_constraint_1_tcb. Adjust asm sequence to allow R0 usage.
|
||||
(atomic_<fetchop_name>_fetch<mode>_soft_imask): Use arith_reg_dest and
|
||||
arith_reg_operand instead of register_operand. Use fetchop_predicate_1,
|
||||
fetchop_constraint_1_imask. Adjust asm sequence to allow R0 usage.
|
||||
(atomic_nand_fetch<mode>): Use arith_reg_dest instead of
|
||||
register_operand. Use atomic_logical_operand_1.
|
||||
(atomic_nand_fetchsi_hard, atomic_nand_fetch<mode>_hard,
|
||||
atomic_nand_fetch<mode>_soft_gusa): Use arith_reg_dest and
|
||||
arith_reg_operand instead of register_operand.
|
||||
(atomic_nand_fetch<mode>_soft_tcb): Use arith_reg_dest and
|
||||
arith_reg_operand instead of register_operand. Use logical_operand
|
||||
and K08. Adjust asm sequence to allow R0 usage.
|
||||
(atomic_nand_fetch<mode>_soft_imask): Use arith_reg_dest and
|
||||
arith_reg_operand instead of register_operand. Use logical_operand
|
||||
and K08.
|
||||
|
||||
2015-01-28 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR other/63504
|
||||
|
|
|
|||
|
|
@ -1134,24 +1134,6 @@
|
|||
return 0;
|
||||
})
|
||||
|
||||
;; The atomic_* operand predicates are used for the atomic patterns.
|
||||
;; Depending on the particular pattern some operands can be immediate
|
||||
;; values. Using these predicates avoids the usage of 'force_reg' in the
|
||||
;; expanders.
|
||||
(define_predicate "atomic_arith_operand"
|
||||
(ior (match_code "subreg,reg")
|
||||
(and (match_test "satisfies_constraint_I08 (op)")
|
||||
(match_test "mode != QImode")
|
||||
(match_test "mode != HImode")
|
||||
(match_test "TARGET_SH4A"))))
|
||||
|
||||
(define_predicate "atomic_logical_operand"
|
||||
(ior (match_code "subreg,reg")
|
||||
(and (match_test "satisfies_constraint_K08 (op)")
|
||||
(match_test "mode != QImode")
|
||||
(match_test "mode != HImode")
|
||||
(match_test "TARGET_SH4A"))))
|
||||
|
||||
;; A predicate that matches any expression for which there is an
|
||||
;; insn pattern that sets the T bit.
|
||||
(define_predicate "treg_set_expr"
|
||||
|
|
|
|||
|
|
@ -195,26 +195,29 @@
|
|||
(define_code_attr fetchop_name
|
||||
[(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")])
|
||||
|
||||
(define_code_attr fetchop_predicate
|
||||
[(plus "atomic_arith_operand") (minus "register_operand")
|
||||
(ior "atomic_logical_operand") (xor "atomic_logical_operand")
|
||||
(and "atomic_logical_operand")])
|
||||
|
||||
(define_code_attr fetchop_constraint
|
||||
[(plus "rI08") (minus "r") (ior "rK08") (xor "rK08") (and "rK08")])
|
||||
|
||||
;;------------------------------------------------------------------------------
|
||||
;; comapre and swap
|
||||
|
||||
;; Only the hard_llcs SImode patterns can use an I08 for the comparison
|
||||
;; or for the new swapped in value.
|
||||
(define_predicate "atomic_arith_operand_0"
|
||||
(and (match_code "subreg,reg,const_int")
|
||||
(ior (match_operand 0 "arith_reg_operand")
|
||||
(and (match_test "satisfies_constraint_I08 (op)")
|
||||
(match_test "mode == SImode")
|
||||
(ior (match_test "TARGET_ATOMIC_HARD_LLCS")
|
||||
(match_test "TARGET_ATOMIC_ANY && TARGET_SH4A
|
||||
&& !TARGET_ATOMIC_STRICT"))))))
|
||||
|
||||
(define_expand "atomic_compare_and_swap<mode>"
|
||||
[(match_operand:SI 0 "register_operand" "") ;; bool success output
|
||||
(match_operand:QIHISI 1 "register_operand" "") ;; oldval output
|
||||
(match_operand:QIHISI 2 "memory_operand" "") ;; memory
|
||||
(match_operand:QIHISI 3 "atomic_arith_operand" "") ;; expected input
|
||||
(match_operand:QIHISI 4 "atomic_arith_operand" "") ;; newval input
|
||||
(match_operand:SI 5 "const_int_operand" "") ;; is_weak
|
||||
(match_operand:SI 6 "const_int_operand" "") ;; success model
|
||||
(match_operand:SI 7 "const_int_operand" "")] ;; failure model
|
||||
[(match_operand:SI 0 "arith_reg_dest") ;; bool success output
|
||||
(match_operand:QIHISI 1 "arith_reg_dest") ;; oldval output
|
||||
(match_operand:QIHISI 2 "memory_operand") ;; memory
|
||||
(match_operand:QIHISI 3 "atomic_arith_operand_0") ;; expected input
|
||||
(match_operand:QIHISI 4 "atomic_arith_operand_0") ;; newval input
|
||||
(match_operand:SI 5 "const_int_operand") ;; is_weak
|
||||
(match_operand:SI 6 "const_int_operand") ;; success model
|
||||
(match_operand:SI 7 "const_int_operand")] ;; failure model
|
||||
"TARGET_ATOMIC_ANY"
|
||||
{
|
||||
rtx addr = force_reg (Pmode, XEXP (operands[2], 0));
|
||||
|
|
@ -252,9 +255,9 @@
|
|||
})
|
||||
|
||||
(define_insn "atomic_compare_and_swapsi_hard"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&r")
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=&r")
|
||||
(unspec_volatile:SI
|
||||
[(mem:SI (match_operand:SI 1 "register_operand" "r"))
|
||||
[(mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:SI 2 "arith_operand" "rI08")
|
||||
(match_operand:SI 3 "arith_operand" "rI08")]
|
||||
UNSPECV_CMPXCHG_1))
|
||||
|
|
@ -278,11 +281,11 @@
|
|||
[(set_attr "length" "14")])
|
||||
|
||||
(define_insn "atomic_compare_and_swap<mode>_hard"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&r")
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=&r")
|
||||
(unspec_volatile:SI
|
||||
[(mem:QIHI (match_operand:SI 1 "register_operand" "r"))
|
||||
(match_operand:QIHI 2 "register_operand" "r")
|
||||
(match_operand:QIHI 3 "register_operand" "r")]
|
||||
[(mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:QIHI 2 "arith_reg_operand" "r")
|
||||
(match_operand:QIHI 3 "arith_reg_operand" "r")]
|
||||
UNSPECV_CMPXCHG_1))
|
||||
(set (mem:QIHI (match_dup 1))
|
||||
(unspec_volatile:QIHI [(const_int 0)] UNSPECV_CMPXCHG_2))
|
||||
|
|
@ -314,11 +317,11 @@
|
|||
[(set_attr "length" "30")])
|
||||
|
||||
(define_insn "atomic_compare_and_swap<mode>_soft_gusa"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&u")
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=&u")
|
||||
(unspec_volatile:SI
|
||||
[(mem:QIHISI (match_operand:SI 1 "register_operand" "u"))
|
||||
(match_operand:QIHISI 2 "register_operand" "u")
|
||||
(match_operand:QIHISI 3 "register_operand" "u")]
|
||||
[(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u"))
|
||||
(match_operand:QIHISI 2 "arith_reg_operand" "u")
|
||||
(match_operand:QIHISI 3 "arith_reg_operand" "u")]
|
||||
UNSPECV_CMPXCHG_1))
|
||||
(set (mem:QIHISI (match_dup 1))
|
||||
(unspec_volatile:QIHISI [(const_int 0)] UNSPECV_CMPXCHG_2))
|
||||
|
|
@ -343,11 +346,11 @@
|
|||
[(set_attr "length" "20")])
|
||||
|
||||
(define_insn "atomic_compare_and_swap<mode>_soft_tcb"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&r")
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=&r")
|
||||
(unspec_volatile:SI
|
||||
[(mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
|
||||
(match_operand:QIHISI 2 "register_operand" "r")
|
||||
(match_operand:QIHISI 3 "register_operand" "r")]
|
||||
[(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:QIHISI 2 "arith_reg_operand" "r")
|
||||
(match_operand:QIHISI 3 "arith_reg_operand" "r")]
|
||||
UNSPECV_CMPXCHG_1))
|
||||
(set (mem:QIHISI (match_dup 1))
|
||||
(unspec_volatile:QIHISI [(const_int 0)] UNSPECV_CMPXCHG_2))
|
||||
|
|
@ -374,11 +377,11 @@
|
|||
[(set_attr "length" "22")])
|
||||
|
||||
(define_insn "atomic_compare_and_swap<mode>_soft_imask"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&z")
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=&z")
|
||||
(unspec_volatile:SI
|
||||
[(mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
|
||||
(match_operand:QIHISI 2 "register_operand" "r")
|
||||
(match_operand:QIHISI 3 "register_operand" "r")]
|
||||
[(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:QIHISI 2 "arith_reg_operand" "r")
|
||||
(match_operand:QIHISI 3 "arith_reg_operand" "r")]
|
||||
UNSPECV_CMPXCHG_1))
|
||||
(set (mem:QIHISI (match_dup 1))
|
||||
(unspec_volatile:QIHISI [(const_int 0)] UNSPECV_CMPXCHG_2))
|
||||
|
|
@ -426,10 +429,10 @@
|
|||
;; read - write - return old value
|
||||
|
||||
(define_expand "atomic_exchange<mode>"
|
||||
[(match_operand:QIHISI 0 "register_operand" "") ;; oldval output
|
||||
(match_operand:QIHISI 1 "memory_operand" "") ;; memory
|
||||
(match_operand:QIHISI 2 "atomic_arith_operand" "") ;; newval input
|
||||
(match_operand:SI 3 "const_int_operand" "")] ;; memory model
|
||||
[(match_operand:QIHISI 0 "arith_reg_dest") ;; oldval output
|
||||
(match_operand:QIHISI 1 "memory_operand") ;; memory
|
||||
(match_operand:QIHISI 2 "atomic_arith_operand_0") ;; newval input
|
||||
(match_operand:SI 3 "const_int_operand")] ;; memory model
|
||||
"TARGET_ATOMIC_ANY"
|
||||
{
|
||||
rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
|
||||
|
|
@ -461,8 +464,8 @@
|
|||
})
|
||||
|
||||
(define_insn "atomic_exchangesi_hard"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&r")
|
||||
(mem:SI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:SI
|
||||
[(match_operand:SI 2 "arith_operand" "rI08")] UNSPEC_ATOMIC))
|
||||
|
|
@ -480,11 +483,11 @@
|
|||
[(set_attr "length" "10")])
|
||||
|
||||
(define_insn "atomic_exchange<mode>_hard"
|
||||
[(set (match_operand:QIHI 0 "register_operand" "=&r")
|
||||
(mem:QIHI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:QIHI
|
||||
[(match_operand:QIHI 2 "register_operand" "r")] UNSPEC_ATOMIC))
|
||||
[(match_operand:QIHI 2 "arith_reg_operand" "r")] UNSPEC_ATOMIC))
|
||||
(set (reg:SI T_REG) (const_int 1))
|
||||
(clobber (reg:SI R0_REG))
|
||||
(clobber (match_scratch:SI 3 "=&r"))
|
||||
|
|
@ -507,11 +510,11 @@
|
|||
[(set_attr "length" "24")])
|
||||
|
||||
(define_insn "atomic_exchange<mode>_soft_gusa"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&u")
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "u")))
|
||||
[(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))
|
||||
(unspec:QIHISI
|
||||
[(match_operand:QIHISI 2 "register_operand" "u")] UNSPEC_ATOMIC))
|
||||
[(match_operand:QIHISI 2 "arith_reg_operand" "u")] UNSPEC_ATOMIC))
|
||||
(clobber (reg:SI R0_REG))
|
||||
(clobber (reg:SI R1_REG))]
|
||||
"TARGET_ATOMIC_SOFT_GUSA"
|
||||
|
|
@ -527,11 +530,11 @@
|
|||
[(set_attr "length" "14")])
|
||||
|
||||
(define_insn "atomic_exchange<mode>_soft_tcb"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&r")
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:QIHISI
|
||||
[(match_operand:QIHISI 2 "register_operand" "r")] UNSPEC_ATOMIC))
|
||||
[(match_operand:QIHISI 2 "arith_reg_operand" "r")] UNSPEC_ATOMIC))
|
||||
(clobber (reg:SI R0_REG))
|
||||
(clobber (reg:SI R1_REG))
|
||||
(use (match_operand:SI 3 "gbr_displacement"))]
|
||||
|
|
@ -549,11 +552,11 @@
|
|||
[(set_attr "length" "16")])
|
||||
|
||||
(define_insn "atomic_exchange<mode>_soft_imask"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&z")
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&z")
|
||||
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))
|
||||
(set (mem:QIHISI (match_dup 1))
|
||||
(unspec:QIHISI
|
||||
[(match_operand:QIHISI 2 "register_operand" "r")] UNSPEC_ATOMIC))
|
||||
[(match_operand:QIHISI 2 "arith_reg_operand" "r")] UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:SI 3 "=&r"))]
|
||||
"TARGET_ATOMIC_SOFT_IMASK"
|
||||
{
|
||||
|
|
@ -570,15 +573,52 @@
|
|||
;;------------------------------------------------------------------------------
|
||||
;; read - add|sub|or|and|xor|nand - write - return old value
|
||||
|
||||
;; atomic_arith_operand_1 can be used by any atomic type for a plus op,
|
||||
;; since there's no r0 restriction.
|
||||
(define_predicate "atomic_arith_operand_1"
|
||||
(and (match_code "subreg,reg,const_int")
|
||||
(ior (match_operand 0 "arith_reg_operand")
|
||||
(match_test "satisfies_constraint_I08 (op)"))))
|
||||
|
||||
;; atomic_logic_operand_1 can be used by the hard_llcs, tcb and soft_imask
|
||||
;; patterns only due to its r0 restriction.
|
||||
(define_predicate "atomic_logical_operand_1"
|
||||
(and (match_code "subreg,reg,const_int")
|
||||
(ior (match_operand 0 "arith_reg_operand")
|
||||
(and (match_test "satisfies_constraint_K08 (op)")
|
||||
(ior (match_test "TARGET_ATOMIC_HARD_LLCS")
|
||||
(match_test "TARGET_ATOMIC_SOFT_IMASK")
|
||||
(match_test "TARGET_ATOMIC_SOFT_TCB")
|
||||
(match_test "TARGET_ATOMIC_ANY && TARGET_SH4A
|
||||
&& mode == SImode
|
||||
&& !TARGET_ATOMIC_STRICT"))))))
|
||||
|
||||
(define_code_attr fetchop_predicate_1
|
||||
[(plus "atomic_arith_operand_1") (minus "arith_reg_operand")
|
||||
(ior "atomic_logical_operand_1") (xor "atomic_logical_operand_1")
|
||||
(and "atomic_logical_operand_1")])
|
||||
|
||||
(define_code_attr fetchop_constraint_1_llcs
|
||||
[(plus "rI08") (minus "r") (ior "rK08") (xor "rK08") (and "rK08")])
|
||||
|
||||
(define_code_attr fetchop_constraint_1_gusa
|
||||
[(plus "uI08") (minus "u") (ior "u") (xor "u") (and "u")])
|
||||
|
||||
(define_code_attr fetchop_constraint_1_tcb
|
||||
[(plus "rI08") (minus "r") (ior "rK08") (xor "rK08") (and "rK08")])
|
||||
|
||||
(define_code_attr fetchop_constraint_1_imask
|
||||
[(plus "rI08") (minus "r") (ior "rK08") (xor "rK08") (and "rK08")])
|
||||
|
||||
(define_expand "atomic_fetch_<fetchop_name><mode>"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "")
|
||||
(match_operand:QIHISI 1 "memory_operand" ""))
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest")
|
||||
(match_operand:QIHISI 1 "memory_operand"))
|
||||
(set (match_dup 1)
|
||||
(unspec:QIHISI
|
||||
[(FETCHOP:QIHISI (match_dup 1)
|
||||
(match_operand:QIHISI 2 "<fetchop_predicate>" ""))]
|
||||
(match_operand:QIHISI 2 "<fetchop_predicate_1>"))]
|
||||
UNSPEC_ATOMIC))
|
||||
(match_operand:SI 3 "const_int_operand" "")]
|
||||
(match_operand:SI 3 "const_int_operand")]
|
||||
"TARGET_ATOMIC_ANY"
|
||||
{
|
||||
rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
|
||||
|
|
@ -612,12 +652,13 @@
|
|||
})
|
||||
|
||||
(define_insn "atomic_fetch_<fetchop_name>si_hard"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&r")
|
||||
(mem:SI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:SI
|
||||
[(FETCHOP:SI (mem:SI (match_dup 1))
|
||||
(match_operand:SI 2 "<fetchop_predicate>" "<fetchop_constraint>"))]
|
||||
(match_operand:SI 2 "<fetchop_predicate_1>"
|
||||
"<fetchop_constraint_1_llcs>"))]
|
||||
UNSPEC_ATOMIC))
|
||||
(set (reg:SI T_REG) (const_int 1))
|
||||
(clobber (reg:SI R0_REG))]
|
||||
|
|
@ -633,12 +674,13 @@
|
|||
[(set_attr "length" "10")])
|
||||
|
||||
(define_insn "atomic_fetch_<fetchop_name><mode>_hard"
|
||||
[(set (match_operand:QIHI 0 "register_operand" "=&r")
|
||||
(mem:QIHI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:QIHI
|
||||
[(FETCHOP:QIHI (mem:QIHI (match_dup 1))
|
||||
(match_operand:QIHI 2 "<fetchop_predicate>" "<fetchop_constraint>"))]
|
||||
(match_operand:QIHI 2 "<fetchop_predicate_1>"
|
||||
"<fetchop_constraint_1_llcs>"))]
|
||||
UNSPEC_ATOMIC))
|
||||
(set (reg:SI T_REG) (const_int 1))
|
||||
(clobber (reg:SI R0_REG))
|
||||
|
|
@ -664,12 +706,14 @@
|
|||
[(set_attr "length" "28")])
|
||||
|
||||
(define_insn "atomic_fetch_<fetchop_name><mode>_soft_gusa"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&u")
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "u")))
|
||||
[(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))
|
||||
(unspec:QIHISI
|
||||
[(FETCHOP:QIHISI (mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "register_operand" "u"))]
|
||||
[(FETCHOP:QIHISI
|
||||
(mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "<fetchop_predicate_1>"
|
||||
"<fetchop_constraint_1_gusa>"))]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:QIHISI 3 "=&u"))
|
||||
(clobber (reg:SI R0_REG))
|
||||
|
|
@ -689,65 +733,68 @@
|
|||
[(set_attr "length" "18")])
|
||||
|
||||
(define_insn "atomic_fetch_<fetchop_name><mode>_soft_tcb"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&r")
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:QIHISI
|
||||
[(FETCHOP:QIHISI (mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "register_operand" "r"))]
|
||||
[(FETCHOP:QIHISI
|
||||
(mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "<fetchop_predicate_1>"
|
||||
"<fetchop_constraint_1_tcb>"))]
|
||||
UNSPEC_ATOMIC))
|
||||
(use (match_operand:SI 3 "gbr_displacement"))
|
||||
(clobber (match_scratch:QIHISI 4 "=&r"))
|
||||
(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 #(0f-1f),r1" "\n"
|
||||
" mov.l r0,@(%O3,gbr)" "\n"
|
||||
"0: mov.<bwl> @%1,%0" "\n"
|
||||
" mov #0,r0" "\n"
|
||||
" mov %0,%4" "\n"
|
||||
" <fetchop_name> %2,%4" "\n"
|
||||
" mov.<bwl> %4,@%1" "\n"
|
||||
"1: mov.l r0,@(%O3,gbr)";
|
||||
"0: mov.<bwl> @%1,r0" "\n"
|
||||
" mov r0,%0" "\n"
|
||||
" <fetchop_name> %2,r0" "\n"
|
||||
" mov.<bwl> r0,@%1" "\n"
|
||||
"1: mov #0,r0" "\n"
|
||||
" mov.l r0,@(%O3,gbr)";
|
||||
}
|
||||
[(set_attr "length" "20")])
|
||||
|
||||
(define_insn "atomic_fetch_<fetchop_name><mode>_soft_imask"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&z")
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:QIHISI
|
||||
[(FETCHOP:QIHISI (mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "register_operand" "r"))]
|
||||
[(FETCHOP:QIHISI
|
||||
(mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "<fetchop_predicate_1>"
|
||||
"<fetchop_constraint_1_imask>"))]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:QIHISI 3 "=&r"))
|
||||
(clobber (match_scratch:SI 4 "=&r"))]
|
||||
(clobber (reg:SI R0_REG))
|
||||
(clobber (match_scratch:QIHISI 3 "=&r"))]
|
||||
"TARGET_ATOMIC_SOFT_IMASK"
|
||||
{
|
||||
return "\r stc sr,%0" "\n"
|
||||
" mov %0,%4" "\n"
|
||||
" or #0xF0,%0" "\n"
|
||||
" ldc %0,sr" "\n"
|
||||
" mov.<bwl> @%1,%0" "\n"
|
||||
" mov %0,%3" "\n"
|
||||
" <fetchop_name> %2,%3" "\n"
|
||||
" mov.<bwl> %3,@%1" "\n"
|
||||
" ldc %4,sr";
|
||||
return "\r stc sr,r0" "\n"
|
||||
" mov r0,%3" "\n"
|
||||
" or #0xF0,r0" "\n"
|
||||
" ldc r0,sr" "\n"
|
||||
" mov.<bwl> @%1,r0" "\n"
|
||||
" mov r0,%0" "\n"
|
||||
" <fetchop_name> %2,r0" "\n"
|
||||
" mov.<bwl> r0,@%1" "\n"
|
||||
" ldc %3,sr";
|
||||
}
|
||||
[(set_attr "length" "18")])
|
||||
|
||||
(define_expand "atomic_fetch_nand<mode>"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "")
|
||||
(match_operand:QIHISI 1 "memory_operand" ""))
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest")
|
||||
(match_operand:QIHISI 1 "memory_operand"))
|
||||
(set (match_dup 1)
|
||||
(unspec:QIHISI
|
||||
[(not:QIHISI (and:QIHISI (match_dup 1)
|
||||
(match_operand:QIHISI 2 "atomic_logical_operand" "")))]
|
||||
(match_operand:QIHISI 2 "atomic_logical_operand_1")))]
|
||||
UNSPEC_ATOMIC))
|
||||
(match_operand:SI 3 "const_int_operand" "")]
|
||||
(match_operand:SI 3 "const_int_operand")]
|
||||
"TARGET_ATOMIC_ANY"
|
||||
{
|
||||
rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
|
||||
|
|
@ -781,8 +828,8 @@
|
|||
})
|
||||
|
||||
(define_insn "atomic_fetch_nandsi_hard"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&r")
|
||||
(mem:SI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:SI
|
||||
[(not:SI (and:SI (mem:SI (match_dup 1))
|
||||
|
|
@ -803,8 +850,8 @@
|
|||
[(set_attr "length" "12")])
|
||||
|
||||
(define_insn "atomic_fetch_nand<mode>_hard"
|
||||
[(set (match_operand:QIHI 0 "register_operand" "=&r")
|
||||
(mem:QIHI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:QIHI
|
||||
[(not:QIHI (and:QIHI (mem:QIHI (match_dup 1))
|
||||
|
|
@ -835,12 +882,13 @@
|
|||
[(set_attr "length" "30")])
|
||||
|
||||
(define_insn "atomic_fetch_nand<mode>_soft_gusa"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&u")
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "u")))
|
||||
[(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))
|
||||
(unspec:QIHISI
|
||||
[(not:QIHISI (and:QIHISI (mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "register_operand" "u")))]
|
||||
[(not:QIHISI
|
||||
(and:QIHISI (mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "arith_reg_operand" "u")))]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:QIHISI 3 "=&u"))
|
||||
(clobber (reg:SI R0_REG))
|
||||
|
|
@ -861,55 +909,56 @@
|
|||
[(set_attr "length" "20")])
|
||||
|
||||
(define_insn "atomic_fetch_nand<mode>_soft_tcb"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&r")
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:QIHISI
|
||||
[(not:QIHISI (and:QIHISI (mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "register_operand" "r")))]
|
||||
[(not:QIHISI
|
||||
(and:QIHISI (mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "logical_operand" "rK08")))]
|
||||
UNSPEC_ATOMIC))
|
||||
(use (match_operand:SI 3 "gbr_displacement"))
|
||||
(clobber (match_scratch:QIHISI 4 "=&r"))
|
||||
(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"
|
||||
" .align 2" "\n"
|
||||
" mov.l r0,@(%O3,gbr)" "\n"
|
||||
"0: mov.<bwl> @%1,%0" "\n"
|
||||
" mov #0,r0" "\n"
|
||||
" mov %2,%4" "\n"
|
||||
" and %0,%4" "\n"
|
||||
" not %4,%4" "\n"
|
||||
" mov.<bwl> %4,@%1" "\n"
|
||||
"1: mov.l r0,@(%O3,gbr)";
|
||||
"0: mov.<bwl> @%1,r0" "\n"
|
||||
" mov r0,%0" "\n"
|
||||
" and %2,r0" "\n"
|
||||
" not r0,r0" "\n"
|
||||
" mov.<bwl> r0,@%1" "\n"
|
||||
"1: mov #0,r0" "\n"
|
||||
" mov.l r0,@(%O3,gbr)";
|
||||
}
|
||||
[(set_attr "length" "22")])
|
||||
|
||||
(define_insn "atomic_fetch_nand<mode>_soft_imask"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&z")
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
|
||||
[(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))
|
||||
(unspec:QIHISI
|
||||
[(not:QIHISI (and:QIHISI (mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "register_operand" "r")))]
|
||||
[(not:QIHISI
|
||||
(and:QIHISI (mem:QIHISI (match_dup 1))
|
||||
(match_operand:QIHISI 2 "logical_operand" "rK08")))]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:QIHISI 3 "=&r"))
|
||||
(clobber (match_scratch:SI 4 "=&r"))]
|
||||
(clobber (reg:SI R0_REG))
|
||||
(clobber (match_scratch:SI 3 "=&r"))]
|
||||
"TARGET_ATOMIC_SOFT_IMASK"
|
||||
{
|
||||
return "\r stc sr,%0" "\n"
|
||||
" mov %0,%4" "\n"
|
||||
" or #0xF0,%0" "\n"
|
||||
" ldc %0,sr" "\n"
|
||||
" mov.<bwl> @%1,%0" "\n"
|
||||
" mov %2,%3" "\n"
|
||||
" and %0,%3" "\n"
|
||||
" not %3,%3" "\n"
|
||||
" mov.<bwl> %3,@%1" "\n"
|
||||
" ldc %4,sr";
|
||||
return "\r stc sr,r0" "\n"
|
||||
" mov r0,%3" "\n"
|
||||
" or #0xF0,r0" "\n"
|
||||
" ldc r0,sr" "\n"
|
||||
" mov.<bwl> @%1,r0" "\n"
|
||||
" mov r0,%0" "\n"
|
||||
" and %2,r0" "\n"
|
||||
" not r0,r0" "\n"
|
||||
" mov.<bwl> r0,@%1" "\n"
|
||||
" ldc %3,sr";
|
||||
}
|
||||
[(set_attr "length" "20")])
|
||||
|
||||
|
|
@ -917,10 +966,10 @@
|
|||
;; read - add|sub|or|and|xor|nand - write - return new value
|
||||
|
||||
(define_expand "atomic_<fetchop_name>_fetch<mode>"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "")
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest")
|
||||
(FETCHOP:QIHISI
|
||||
(match_operand:QIHISI 1 "memory_operand" "")
|
||||
(match_operand:QIHISI 2 "<fetchop_predicate>" "")))
|
||||
(match_operand:QIHISI 1 "memory_operand")
|
||||
(match_operand:QIHISI 2 "<fetchop_predicate_1>")))
|
||||
(set (match_dup 1)
|
||||
(unspec:QIHISI
|
||||
[(FETCHOP:QIHISI (match_dup 1) (match_dup 2))]
|
||||
|
|
@ -959,10 +1008,11 @@
|
|||
})
|
||||
|
||||
(define_insn "atomic_<fetchop_name>_fetchsi_hard"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&z")
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=&z")
|
||||
(FETCHOP:SI
|
||||
(mem:SI (match_operand:SI 1 "register_operand" "r"))
|
||||
(match_operand:SI 2 "<fetchop_predicate>" "<fetchop_constraint>")))
|
||||
(mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:SI 2 "<fetchop_predicate_1>"
|
||||
"<fetchop_constraint_1_llcs>")))
|
||||
(set (mem:SI (match_dup 1))
|
||||
(unspec:SI
|
||||
[(FETCHOP:SI (mem:SI (match_dup 1)) (match_dup 2))]
|
||||
|
|
@ -979,10 +1029,11 @@
|
|||
[(set_attr "length" "8")])
|
||||
|
||||
(define_insn "atomic_<fetchop_name>_fetch<mode>_hard"
|
||||
[(set (match_operand:QIHI 0 "register_operand" "=&r")
|
||||
[(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
|
||||
(FETCHOP:QIHI
|
||||
(mem:QIHI (match_operand:SI 1 "register_operand" "r"))
|
||||
(match_operand:QIHI 2 "<fetchop_predicate>" "<fetchop_constraint>")))
|
||||
(mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:QIHI 2 "<fetchop_predicate_1>"
|
||||
"<fetchop_constraint_1_llcs>")))
|
||||
(set (mem:QIHI (match_dup 1))
|
||||
(unspec:QIHI
|
||||
[(FETCHOP:QIHI (mem:QIHI (match_dup 1)) (match_dup 2))]
|
||||
|
|
@ -1011,10 +1062,11 @@
|
|||
[(set_attr "length" "28")])
|
||||
|
||||
(define_insn "atomic_<fetchop_name>_fetch<mode>_soft_gusa"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&u")
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u")
|
||||
(FETCHOP:QIHISI
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "u"))
|
||||
(match_operand:QIHISI 2 "register_operand" "u")))
|
||||
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u"))
|
||||
(match_operand:QIHISI 2 "<fetchop_predicate_1>"
|
||||
"<fetchop_constraint_1_gusa>")))
|
||||
(set (mem:QIHISI (match_dup 1))
|
||||
(unspec:QIHISI
|
||||
[(FETCHOP:QIHISI (mem:QIHISI (match_dup 1)) (match_dup 2))]
|
||||
|
|
@ -1035,10 +1087,11 @@
|
|||
[(set_attr "length" "16")])
|
||||
|
||||
(define_insn "atomic_<fetchop_name>_fetch<mode>_soft_tcb"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&r")
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
|
||||
(FETCHOP:QIHISI
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
|
||||
(match_operand:QIHISI 2 "register_operand" "r")))
|
||||
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:QIHISI 2 "<fetchop_predicate_1>"
|
||||
"<fetchop_constraint_1_tcb>")))
|
||||
(set (mem:QIHISI (match_dup 1))
|
||||
(unspec:QIHISI
|
||||
[(FETCHOP:QIHISI (mem:QIHISI (match_dup 1)) (match_dup 2))]
|
||||
|
|
@ -1049,22 +1102,24 @@
|
|||
"TARGET_ATOMIC_SOFT_TCB"
|
||||
{
|
||||
return "\r mova 1f,r0" "\n"
|
||||
" .align 2" "\n"
|
||||
" mov #(0f-1f),r1" "\n"
|
||||
" .align 2" "\n"
|
||||
" mov.l r0,@(%O3,gbr)" "\n"
|
||||
"0: mov.<bwl> @%1,%0" "\n"
|
||||
"0: mov.<bwl> @%1,r0" "\n"
|
||||
" <fetchop_name> %2,r0" "\n"
|
||||
" mov.<bwl> r0,@%1" "\n"
|
||||
"1: mov r0,%0" "\n"
|
||||
" mov #0,r0" "\n"
|
||||
" <fetchop_name> %2,%0" "\n"
|
||||
" mov.<bwl> %0,@%1" "\n"
|
||||
"1: mov.l r0,@(%O3,gbr)";
|
||||
" mov.l r0,@(%O3,gbr)";
|
||||
}
|
||||
[(set_attr "length" "18")])
|
||||
[(set_attr "length" "20")])
|
||||
|
||||
(define_insn "atomic_<fetchop_name>_fetch<mode>_soft_imask"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&z")
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&z")
|
||||
(FETCHOP:QIHISI
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
|
||||
(match_operand:QIHISI 2 "register_operand" "r")))
|
||||
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:QIHISI 2 "<fetchop_predicate_1>"
|
||||
"<fetchop_constraint_1_imask>")))
|
||||
(set (mem:QIHISI (match_dup 1))
|
||||
(unspec:QIHISI
|
||||
[(FETCHOP:QIHISI (mem:QIHISI (match_dup 1)) (match_dup 2))]
|
||||
|
|
@ -1084,15 +1139,15 @@
|
|||
[(set_attr "length" "16")])
|
||||
|
||||
(define_expand "atomic_nand_fetch<mode>"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "")
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest")
|
||||
(not:QIHISI (and:QIHISI
|
||||
(match_operand:QIHISI 1 "memory_operand" "")
|
||||
(match_operand:QIHISI 2 "atomic_logical_operand" ""))))
|
||||
(match_operand:QIHISI 1 "memory_operand")
|
||||
(match_operand:QIHISI 2 "atomic_logical_operand_1"))))
|
||||
(set (match_dup 1)
|
||||
(unspec:QIHISI
|
||||
[(not:QIHISI (and:QIHISI (match_dup 1) (match_dup 2)))]
|
||||
UNSPEC_ATOMIC))
|
||||
(match_operand:SI 3 "const_int_operand" "")]
|
||||
(match_operand:SI 3 "const_int_operand")]
|
||||
"TARGET_ATOMIC_ANY"
|
||||
{
|
||||
rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
|
||||
|
|
@ -1126,8 +1181,8 @@
|
|||
})
|
||||
|
||||
(define_insn "atomic_nand_fetchsi_hard"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&z")
|
||||
(not:SI (and:SI (mem:SI (match_operand:SI 1 "register_operand" "r"))
|
||||
[(set (match_operand:SI 0 "arith_reg_dest" "=&z")
|
||||
(not:SI (and:SI (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:SI 2 "logical_operand" "rK08"))))
|
||||
(set (mem:SI (match_dup 1))
|
||||
(unspec:SI
|
||||
|
|
@ -1146,9 +1201,9 @@
|
|||
[(set_attr "length" "10")])
|
||||
|
||||
(define_insn "atomic_nand_fetch<mode>_hard"
|
||||
[(set (match_operand:QIHI 0 "register_operand" "=&r")
|
||||
[(set (match_operand:QIHI 0 "arith_reg_dest" "=&r")
|
||||
(not:QIHI
|
||||
(and:QIHI (mem:QIHI (match_operand:SI 1 "register_operand" "r"))
|
||||
(and:QIHI (mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:QIHI 2 "logical_operand" "rK08"))))
|
||||
(set (mem:QIHI (match_dup 1))
|
||||
(unspec:QIHI
|
||||
|
|
@ -1178,10 +1233,10 @@
|
|||
[(set_attr "length" "28")])
|
||||
|
||||
(define_insn "atomic_nand_fetch<mode>_soft_gusa"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&u")
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u")
|
||||
(not:QIHISI (and:QIHISI
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "u"))
|
||||
(match_operand:QIHISI 2 "register_operand" "u"))))
|
||||
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u"))
|
||||
(match_operand:QIHISI 2 "arith_reg_operand" "u"))))
|
||||
(set (mem:QIHISI (match_dup 1))
|
||||
(unspec:QIHISI
|
||||
[(not:QIHISI (and:QIHISI (mem:QIHISI (match_dup 1)) (match_dup 2)))]
|
||||
|
|
@ -1203,10 +1258,10 @@
|
|||
[(set_attr "length" "18")])
|
||||
|
||||
(define_insn "atomic_nand_fetch<mode>_soft_tcb"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&r")
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r")
|
||||
(not:QIHISI (and:QIHISI
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
|
||||
(match_operand:QIHISI 2 "register_operand" "r"))))
|
||||
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:QIHISI 2 "logical_operand" "rK08"))))
|
||||
(set (mem:QIHISI (match_dup 1))
|
||||
(unspec:QIHISI
|
||||
[(not:QIHISI (and:QIHISI (mem:QIHISI (match_dup 1)) (match_dup 2)))]
|
||||
|
|
@ -1220,20 +1275,21 @@
|
|||
" mov #(0f-1f),r1" "\n"
|
||||
" .align 2" "\n"
|
||||
" mov.l r0,@(%O3,gbr)" "\n"
|
||||
"0: mov.<bwl> @%1,%0" "\n"
|
||||
" mov #0,r0" "\n"
|
||||
" and %2,%0" "\n"
|
||||
" not %0,%0" "\n"
|
||||
" mov.<bwl> %0,@%1" "\n"
|
||||
"1: mov.l r0,@(%O3,gbr)";
|
||||
"0: mov.<bwl> @%1,r0" "\n"
|
||||
" and %2,r0" "\n"
|
||||
" not r0,r0" "\n"
|
||||
" mov r0,%0" "\n"
|
||||
" mov.<bwl> r0,@%1" "\n"
|
||||
"1: mov #0,r0" "\n"
|
||||
" mov.l r0,@(%O3,gbr)";
|
||||
}
|
||||
[(set_attr "length" "20")])
|
||||
[(set_attr "length" "22")])
|
||||
|
||||
(define_insn "atomic_nand_fetch<mode>_soft_imask"
|
||||
[(set (match_operand:QIHISI 0 "register_operand" "=&z")
|
||||
[(set (match_operand:QIHISI 0 "arith_reg_dest" "=&z")
|
||||
(not:QIHISI (and:QIHISI
|
||||
(mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
|
||||
(match_operand:QIHISI 2 "register_operand" "r"))))
|
||||
(mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand:QIHISI 2 "logical_operand" "rK08"))))
|
||||
(set (mem:QIHISI (match_dup 1))
|
||||
(unspec:QIHISI
|
||||
[(not:QIHISI (and:QIHISI (mem:QIHISI (match_dup 1)) (match_dup 2)))]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,17 @@
|
|||
2015-01-28 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
PR target/64659
|
||||
* gcc.target/sh/sh.exp
|
||||
(check_effective_target_atomic_model_soft_gusa_available,
|
||||
check_effective_target_atomic_model_soft_tcb_available,
|
||||
check_effective_target_atomic_model_soft_imask_available,
|
||||
check_effective_target_atomic_model_hard_llcs_available): New.
|
||||
* gcc.target/sh/pr64659-0.h: New.
|
||||
* gcc.target/sh/pr64659-1.c: New.
|
||||
* gcc.target/sh/pr64659-2.c: New.
|
||||
* gcc.target/sh/pr64659-3.c: New.
|
||||
* gcc.target/sh/pr64659-4.c: New.
|
||||
|
||||
2015-01-28 Alex Velenko <Alex.Velenko@arm.com>
|
||||
|
||||
* gcc.target/arm/atomic-op-consume.c (scan-assember-times): Adjust
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
/* Check that atomic ops utilize insns with immediate values. */
|
||||
|
||||
#define emitfuncs(name)\
|
||||
void test_ ## name ## _0 (char* mem)\
|
||||
{\
|
||||
name (mem, 1, __ATOMIC_ACQ_REL);\
|
||||
}\
|
||||
void test_ ## name ## _1 (short* mem)\
|
||||
{\
|
||||
name (mem, 1, __ATOMIC_ACQ_REL);\
|
||||
}\
|
||||
void test_ ## name ##_2 (int* mem)\
|
||||
{\
|
||||
name (mem, 1, __ATOMIC_ACQ_REL);\
|
||||
}\
|
||||
|
||||
emitfuncs (__atomic_add_fetch)
|
||||
emitfuncs (__atomic_fetch_add)
|
||||
|
||||
emitfuncs (__atomic_sub_fetch)
|
||||
emitfuncs (__atomic_fetch_sub)
|
||||
|
||||
emitfuncs (__atomic_and_fetch)
|
||||
emitfuncs (__atomic_fetch_and)
|
||||
|
||||
emitfuncs (__atomic_or_fetch)
|
||||
emitfuncs (__atomic_fetch_or)
|
||||
|
||||
emitfuncs (__atomic_xor_fetch)
|
||||
emitfuncs (__atomic_fetch_xor)
|
||||
|
||||
emitfuncs (__atomic_nand_fetch)
|
||||
emitfuncs (__atomic_fetch_nand)
|
||||
|
||||
void
|
||||
test___atomic_compare_exchange_0 (char* mem)
|
||||
{
|
||||
char expected = 1;
|
||||
char desired = 5;
|
||||
__atomic_compare_exchange (mem, &expected, &desired, 0, __ATOMIC_ACQ_REL,
|
||||
__ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
void
|
||||
test___atomic_compare_exchange_1 (short* mem)
|
||||
{
|
||||
short expected = 1;
|
||||
short desired = 5;
|
||||
__atomic_compare_exchange (mem, &expected, &desired, 0, __ATOMIC_ACQ_REL,
|
||||
__ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
void
|
||||
test___atomic_compare_exchange_2 (int* mem)
|
||||
{
|
||||
int expected = 1;
|
||||
int desired = 5;
|
||||
__atomic_compare_exchange (mem, &expected, &desired, 0, __ATOMIC_ACQ_REL,
|
||||
__ATOMIC_RELAXED);
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/* Check that atomic ops utilize insns with immediate values. */
|
||||
/* { dg-do compile { target { atomic_model_soft_gusa_available } } } */
|
||||
/* { dg-options "-O2 -matomic-model=soft-gusa,strict" } */
|
||||
/* { dg-final { scan-assembler-times "add\t#1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "add\t#-1" 6 } } */
|
||||
|
||||
#include "pr64659-0.h"
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
/* Check that atomic ops utilize insns with immediate values. */
|
||||
/* { dg-do compile { target { atomic_model_soft_tcb_available } } } */
|
||||
/* { dg-options "-O2 -matomic-model=soft-tcb,gbr-offset=0,strict" } */
|
||||
/* { dg-final { scan-assembler-times "add\t#1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "add\t#-1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "and\t#1" 12 } } */
|
||||
/* { dg-final { scan-assembler-times "\tor\t#1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "xor\t#1" 6 } } */
|
||||
|
||||
#include "pr64659-0.h"
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
/* Check that atomic ops utilize insns with immediate values. */
|
||||
/* { dg-do compile { target { atomic_model_soft_imask_available } } } */
|
||||
/* { dg-options "-O2 -matomic-model=soft-imask,strict -mno-usermode" } */
|
||||
/* { dg-final { scan-assembler-times "add\t#1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "add\t#-1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "and\t#1" 12 } } */
|
||||
/* { dg-final { scan-assembler-times "\tor\t#1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "xor\t#1" 6 } } */
|
||||
|
||||
#include "pr64659-0.h"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/* Check that atomic ops utilize insns with immediate values. */
|
||||
/* { dg-do compile { target { atomic_model_hard_llcs_available } } } */
|
||||
/* { dg-options "-O2 -matomic-model=hard-llcs,strict" } */
|
||||
/* { dg-final { scan-assembler-times "add\t#1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "add\t#-1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "and\t#1" 12 } } */
|
||||
/* { dg-final { scan-assembler-times "\tor\t#1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "xor\t#1" 6 } } */
|
||||
/* { dg-final { scan-assembler-times "cmp/eq\t#1" 1 } } */
|
||||
|
||||
#include "pr64659-0.h"
|
||||
|
|
@ -33,6 +33,34 @@ proc check_effective_target_sh2a { } {
|
|||
} ""]
|
||||
}
|
||||
|
||||
# Return 1 if target supports atomic-model=soft-gusa
|
||||
proc check_effective_target_atomic_model_soft_gusa_available { } {
|
||||
return [check_no_compiler_messages atomic_model_soft_gusa_available object {
|
||||
int x = 0;
|
||||
} "-matomic-model=soft-gusa"]
|
||||
}
|
||||
|
||||
# Return 1 if target supports atomic-model=soft-tcb
|
||||
proc check_effective_target_atomic_model_soft_tcb_available { } {
|
||||
return [check_no_compiler_messages atomic_model_soft_tcb_available object {
|
||||
int x = 0;
|
||||
} "-matomic-model=soft-tcb,gbr-offset=0"]
|
||||
}
|
||||
|
||||
# Return 1 if target supports atomic-model=soft-imask
|
||||
proc check_effective_target_atomic_model_soft_imask_available { } {
|
||||
return [check_no_compiler_messages atomic_model_soft_imask_available object {
|
||||
int x = 0;
|
||||
} "-matomic-model=soft-imask -mno-usermode"]
|
||||
}
|
||||
|
||||
# Return 1 if target supports atomic-model=hard-llcs
|
||||
proc check_effective_target_atomic_model_hard_llcs_available { } {
|
||||
return [check_no_compiler_messages atomic_model_hard_llcs_available object {
|
||||
int x = 0;
|
||||
} "-matomic-model=hard-llcs"]
|
||||
}
|
||||
|
||||
# If a testcase doesn't have special options, use these.
|
||||
global DEFAULT_CFLAGS
|
||||
if ![info exists DEFAULT_CFLAGS] then {
|
||||
|
|
|
|||
Loading…
Reference in New Issue