diff options
author | Tom de Vries <vries@codesourcery.com> | 2012-06-20 00:59:08 +0000 |
---|---|---|
committer | Maxim Kuvyrkov <mkuvyrkov@gcc.gnu.org> | 2012-06-20 00:59:08 +0000 |
commit | 6399761a4a77d5e5996c8e82eba042f4a26a4c3d (patch) | |
tree | f1219ec201306c17b838cace3e3d9e84db7b1af8 | |
parent | 01c196ea91cce2665bc7e8df7edfd7dca0352d86 (diff) | |
download | gcc-6399761a4a77d5e5996c8e82eba042f4a26a4c3d.zip gcc-6399761a4a77d5e5996c8e82eba042f4a26a4c3d.tar.gz gcc-6399761a4a77d5e5996c8e82eba042f4a26a4c3d.tar.bz2 |
constraints.md (ZR): New constraint.
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.
Co-Authored-By: Maxim Kuvyrkov <maxim@codesourcery.com>
From-SVN: r188804
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/mips/constraints.md | 5 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 8 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 6 | ||||
-rw-r--r-- | gcc/config/mips/predicates.md | 4 | ||||
-rw-r--r-- | gcc/config/mips/sync.md | 60 |
6 files changed, 90 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 069b61c..0b679ae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,17 @@ 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. + +2012-06-19 Tom de Vries <vries@codesourcery.com> Maxim Kuvyrkov <maxim@codesourcery.com> * config/mips/mips.c (mips_emit_pre_atomic_barrier_p,) diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md index 2bfb2aa..b543217 100644 --- a/gcc/config/mips/constraints.md +++ b/gcc/config/mips/constraints.md @@ -231,3 +231,8 @@ (define_constraint "Yx" "@internal" (match_operand 0 "low_bitmask_operand")) + +(define_memory_constraint "ZR" + "@internal + An address valid for loading/storing register exclusive" + (match_operand 0 "mem_noofs_operand")) diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index f37c194..64b486d 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -7806,7 +7806,8 @@ mips_print_operand_punct_valid_p (unsigned char code) 'D' Print the second part of a double-word register or memory operand. 'L' Print the low-order register in a double-word register operand. 'M' Print high-order register in a double-word register operand. - 'z' Print $0 if OP is zero, otherwise print OP normally. */ + 'z' Print $0 if OP is zero, otherwise print OP normally. + 'b' Print the address of a memory operand, without offset. */ static void mips_print_operand (FILE *file, rtx op, int letter) @@ -7935,6 +7936,11 @@ mips_print_operand (FILE *file, rtx op, int letter) case MEM: if (letter == 'D') output_address (plus_constant (Pmode, XEXP (op, 0), 4)); + else if (letter == 'b') + { + gcc_assert (REG_P (XEXP (op, 0))); + mips_print_operand (file, XEXP (op, 0), 0); + } else if (letter && letter != 'z') output_operand_lossage ("invalid use of '%%%c'", letter); else diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 97f38b2..d8b0c63 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -223,6 +223,7 @@ struct mips_cpu_info { #define TARGET_SB1 (mips_arch == PROCESSOR_SB1 \ || mips_arch == PROCESSOR_SB1A) #define TARGET_SR71K (mips_arch == PROCESSOR_SR71000) +#define TARGET_XLP (mips_arch == PROCESSOR_XLP) /* Scheduling target defines. */ #define TUNE_20KC (mips_tune == PROCESSOR_20KC) @@ -311,7 +312,7 @@ struct mips_cpu_info { stores. It does not tell anything about ordering of loads and stores prior to and following the SC, only about the SC itself and those loads and stores follow it. */ -#define TARGET_SYNC_AFTER_SC (!TARGET_OCTEON) +#define TARGET_SYNC_AFTER_SC (!TARGET_OCTEON && !TARGET_XLP) /* Define preprocessor macros for the -march and -mtune options. PREFIX is either _MIPS_ARCH or _MIPS_TUNE, INFO is the selected @@ -1054,6 +1055,9 @@ struct mips_cpu_info { ? TARGET_LLSC && !TARGET_MIPS16 \ : ISA_HAS_LL_SC) +#define ISA_HAS_SWAP (TARGET_XLP) +#define ISA_HAS_LDADD (TARGET_XLP) + /* ISA includes the baddu instruction. */ #define ISA_HAS_BADDU (TARGET_OCTEON && !TARGET_MIPS16) diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md index 57b1af2..97971e9 100644 --- a/gcc/config/mips/predicates.md +++ b/gcc/config/mips/predicates.md @@ -370,3 +370,7 @@ (define_predicate "small_data_pattern" (and (match_code "set,parallel,unspec,unspec_volatile,prefetch") (match_test "mips_small_data_pattern_p (op)"))) + +(define_predicate "mem_noofs_operand" + (and (match_code "mem") + (match_code "reg" "0"))) diff --git a/gcc/config/mips/sync.md b/gcc/config/mips/sync.md index 604aefa..0a7905a 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") |