summaryrefslogtreecommitdiff
path: root/gcc/config/mips/sync.md
diff options
context:
space:
mode:
authormkuvyrkov <mkuvyrkov@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-20 00:59:08 +0000
committermkuvyrkov <mkuvyrkov@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-20 00:59:08 +0000
commit974f0a74e2116143b88d8cea8e1dd5a9c18ef96c (patch)
treef1219ec201306c17b838cace3e3d9e84db7b1af8 /gcc/config/mips/sync.md
parent39a8c5eaded1e5771a941c56a49ca0a5e9c5eca0 (diff)
downloadgcc-974f0a74e2116143b88d8cea8e1dd5a9c18ef96c.tar.gz
2012-06-19 Tom de Vries <vries@codesourcery.com>
Maxim Kuvyrkov <maxim@codesourcery.com> * config/mips/constraints.md (ZR): New constraint. * config/mips/predicates.md (mem_noofs_operand): New predicate. * config/mips/mips.c (mips_print_operand): Handle new print modifier. * config/mips/mips.h (TARGET_XLP): Define. (TARGET_SYNC_AFTER_SC): Update. (ISA_HAS_SWAP, ISA_HAS_LDADD): Define. * config/mips/sync.md (atomic_exchange, atomic_fetch_add): Use XLP-specific swap and ldadd patterns. (atomic_exchange_swap, atomic_fetch_add_ldadd): New patterns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@188804 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/mips/sync.md')
-rw-r--r--gcc/config/mips/sync.md60
1 files changed, 56 insertions, 4 deletions
diff --git a/gcc/config/mips/sync.md b/gcc/config/mips/sync.md
index 604aefa3d0e..0a7905a3300 100644
--- a/gcc/config/mips/sync.md
+++ b/gcc/config/mips/sync.md
@@ -607,8 +607,22 @@
(match_operand:GPR 1 "memory_operand")
(match_operand:GPR 2 "arith_operand")
(match_operand:SI 3 "const_int_operand")]
- "GENERATE_LL_SC"
+ "GENERATE_LL_SC || ISA_HAS_SWAP"
{
+ if (ISA_HAS_SWAP)
+ {
+ if (!mem_noofs_operand (operands[1], <MODE>mode))
+ {
+ rtx addr;
+
+ addr = force_reg (Pmode, XEXP (operands[1], 0));
+ operands[1] = replace_equiv_address (operands[1], addr);
+ }
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+ emit_insn (gen_atomic_exchange<mode>_swap (operands[0], operands[1],
+ operands[2]));
+ }
+ else
emit_insn (gen_atomic_exchange<mode>_llsc (operands[0], operands[1],
operands[2], operands[3]));
DONE;
@@ -623,7 +637,7 @@
UNSPEC_ATOMIC_EXCHANGE))
(unspec_volatile:GPR [(match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC_EXCHANGE)]
- "GENERATE_LL_SC"
+ "GENERATE_LL_SC && !ISA_HAS_SWAP"
{ return mips_output_sync_loop (insn, operands); }
[(set_attr "sync_insn1" "li,move")
(set_attr "sync_oldval" "0")
@@ -631,13 +645,38 @@
(set_attr "sync_insn1_op2" "2")
(set_attr "sync_memmodel" "3")])
+;; XLP issues implicit sync for SWAP/LDADD, so no need for an explicit one.
+(define_insn "atomic_exchange<mode>_swap"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (unspec_volatile:GPR [(match_operand:GPR 1 "mem_noofs_operand" "+ZR")]
+ UNSPEC_ATOMIC_EXCHANGE))
+ (set (match_dup 1)
+ (unspec_volatile:GPR [(match_operand:GPR 2 "register_operand" "0")]
+ UNSPEC_ATOMIC_EXCHANGE))]
+ "ISA_HAS_SWAP"
+ "swap<size>\t%0,%b1")
+
(define_expand "atomic_fetch_add<mode>"
[(match_operand:GPR 0 "register_operand")
(match_operand:GPR 1 "memory_operand")
(match_operand:GPR 2 "arith_operand")
(match_operand:SI 3 "const_int_operand")]
- "GENERATE_LL_SC"
+ "GENERATE_LL_SC || ISA_HAS_LDADD"
{
+ if (ISA_HAS_LDADD)
+ {
+ if (!mem_noofs_operand (operands[1], <MODE>mode))
+ {
+ rtx addr;
+
+ addr = force_reg (Pmode, XEXP (operands[1], 0));
+ operands[1] = replace_equiv_address (operands[1], addr);
+ }
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+ emit_insn (gen_atomic_fetch_add<mode>_ldadd (operands[0], operands[1],
+ operands[2]));
+ }
+ else
emit_insn (gen_atomic_fetch_add<mode>_llsc (operands[0], operands[1],
operands[2], operands[3]));
DONE;
@@ -654,10 +693,23 @@
UNSPEC_ATOMIC_FETCH_OP))
(unspec_volatile:GPR [(match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC_FETCH_OP)]
- "GENERATE_LL_SC"
+ "GENERATE_LL_SC && !ISA_HAS_LDADD"
{ return mips_output_sync_loop (insn, operands); }
[(set_attr "sync_insn1" "addiu,addu")
(set_attr "sync_oldval" "0")
(set_attr "sync_mem" "1")
(set_attr "sync_insn1_op2" "2")
(set_attr "sync_memmodel" "3")])
+
+;; XLP issues implicit sync for SWAP/LDADD, so no need for an explicit one.
+(define_insn "atomic_fetch_add<mode>_ldadd"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (unspec_volatile:GPR [(match_operand:GPR 1 "mem_noofs_operand" "+ZR")]
+ UNSPEC_ATOMIC_FETCH_OP))
+ (set (match_dup 1)
+ (unspec_volatile:GPR
+ [(plus:GPR (match_dup 1)
+ (match_operand:GPR 2 "register_operand" "0"))]
+ UNSPEC_ATOMIC_FETCH_OP))]
+ "ISA_HAS_LDADD"
+ "ldadd<size>\t%0,%b1")