Commit 6399761a by Tom de Vries Committed by Maxim Kuvyrkov

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
parent 01c196ea
2012-06-19 Tom de Vries <vries@codesourcery.com> 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> Maxim Kuvyrkov <maxim@codesourcery.com>
* config/mips/mips.c (mips_emit_pre_atomic_barrier_p,) * config/mips/mips.c (mips_emit_pre_atomic_barrier_p,)
......
...@@ -231,3 +231,8 @@ ...@@ -231,3 +231,8 @@
(define_constraint "Yx" (define_constraint "Yx"
"@internal" "@internal"
(match_operand 0 "low_bitmask_operand")) (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"))
...@@ -7806,7 +7806,8 @@ mips_print_operand_punct_valid_p (unsigned char code) ...@@ -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. '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. 'L' Print the low-order register in a double-word register operand.
'M' Print high-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 static void
mips_print_operand (FILE *file, rtx op, int letter) mips_print_operand (FILE *file, rtx op, int letter)
...@@ -7935,6 +7936,11 @@ mips_print_operand (FILE *file, rtx op, int letter) ...@@ -7935,6 +7936,11 @@ mips_print_operand (FILE *file, rtx op, int letter)
case MEM: case MEM:
if (letter == 'D') if (letter == 'D')
output_address (plus_constant (Pmode, XEXP (op, 0), 4)); 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') else if (letter && letter != 'z')
output_operand_lossage ("invalid use of '%%%c'", letter); output_operand_lossage ("invalid use of '%%%c'", letter);
else else
......
...@@ -223,6 +223,7 @@ struct mips_cpu_info { ...@@ -223,6 +223,7 @@ struct mips_cpu_info {
#define TARGET_SB1 (mips_arch == PROCESSOR_SB1 \ #define TARGET_SB1 (mips_arch == PROCESSOR_SB1 \
|| mips_arch == PROCESSOR_SB1A) || mips_arch == PROCESSOR_SB1A)
#define TARGET_SR71K (mips_arch == PROCESSOR_SR71000) #define TARGET_SR71K (mips_arch == PROCESSOR_SR71000)
#define TARGET_XLP (mips_arch == PROCESSOR_XLP)
/* Scheduling target defines. */ /* Scheduling target defines. */
#define TUNE_20KC (mips_tune == PROCESSOR_20KC) #define TUNE_20KC (mips_tune == PROCESSOR_20KC)
...@@ -311,7 +312,7 @@ struct mips_cpu_info { ...@@ -311,7 +312,7 @@ struct mips_cpu_info {
stores. It does not tell anything about ordering of loads and stores. It does not tell anything about ordering of loads and
stores prior to and following the SC, only about the SC itself and stores prior to and following the SC, only about the SC itself and
those loads and stores follow it. */ 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. /* Define preprocessor macros for the -march and -mtune options.
PREFIX is either _MIPS_ARCH or _MIPS_TUNE, INFO is the selected PREFIX is either _MIPS_ARCH or _MIPS_TUNE, INFO is the selected
...@@ -1054,6 +1055,9 @@ struct mips_cpu_info { ...@@ -1054,6 +1055,9 @@ struct mips_cpu_info {
? TARGET_LLSC && !TARGET_MIPS16 \ ? TARGET_LLSC && !TARGET_MIPS16 \
: ISA_HAS_LL_SC) : ISA_HAS_LL_SC)
#define ISA_HAS_SWAP (TARGET_XLP)
#define ISA_HAS_LDADD (TARGET_XLP)
/* ISA includes the baddu instruction. */ /* ISA includes the baddu instruction. */
#define ISA_HAS_BADDU (TARGET_OCTEON && !TARGET_MIPS16) #define ISA_HAS_BADDU (TARGET_OCTEON && !TARGET_MIPS16)
......
...@@ -370,3 +370,7 @@ ...@@ -370,3 +370,7 @@
(define_predicate "small_data_pattern" (define_predicate "small_data_pattern"
(and (match_code "set,parallel,unspec,unspec_volatile,prefetch") (and (match_code "set,parallel,unspec,unspec_volatile,prefetch")
(match_test "mips_small_data_pattern_p (op)"))) (match_test "mips_small_data_pattern_p (op)")))
(define_predicate "mem_noofs_operand"
(and (match_code "mem")
(match_code "reg" "0")))
...@@ -607,8 +607,22 @@ ...@@ -607,8 +607,22 @@
(match_operand:GPR 1 "memory_operand") (match_operand:GPR 1 "memory_operand")
(match_operand:GPR 2 "arith_operand") (match_operand:GPR 2 "arith_operand")
(match_operand:SI 3 "const_int_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], emit_insn (gen_atomic_exchange<mode>_llsc (operands[0], operands[1],
operands[2], operands[3])); operands[2], operands[3]));
DONE; DONE;
...@@ -623,7 +637,7 @@ ...@@ -623,7 +637,7 @@
UNSPEC_ATOMIC_EXCHANGE)) UNSPEC_ATOMIC_EXCHANGE))
(unspec_volatile:GPR [(match_operand:SI 3 "const_int_operand")] (unspec_volatile:GPR [(match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC_EXCHANGE)] UNSPEC_ATOMIC_EXCHANGE)]
"GENERATE_LL_SC" "GENERATE_LL_SC && !ISA_HAS_SWAP"
{ return mips_output_sync_loop (insn, operands); } { return mips_output_sync_loop (insn, operands); }
[(set_attr "sync_insn1" "li,move") [(set_attr "sync_insn1" "li,move")
(set_attr "sync_oldval" "0") (set_attr "sync_oldval" "0")
...@@ -631,13 +645,38 @@ ...@@ -631,13 +645,38 @@
(set_attr "sync_insn1_op2" "2") (set_attr "sync_insn1_op2" "2")
(set_attr "sync_memmodel" "3")]) (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>" (define_expand "atomic_fetch_add<mode>"
[(match_operand:GPR 0 "register_operand") [(match_operand:GPR 0 "register_operand")
(match_operand:GPR 1 "memory_operand") (match_operand:GPR 1 "memory_operand")
(match_operand:GPR 2 "arith_operand") (match_operand:GPR 2 "arith_operand")
(match_operand:SI 3 "const_int_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], emit_insn (gen_atomic_fetch_add<mode>_llsc (operands[0], operands[1],
operands[2], operands[3])); operands[2], operands[3]));
DONE; DONE;
...@@ -654,10 +693,23 @@ ...@@ -654,10 +693,23 @@
UNSPEC_ATOMIC_FETCH_OP)) UNSPEC_ATOMIC_FETCH_OP))
(unspec_volatile:GPR [(match_operand:SI 3 "const_int_operand")] (unspec_volatile:GPR [(match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC_FETCH_OP)] UNSPEC_ATOMIC_FETCH_OP)]
"GENERATE_LL_SC" "GENERATE_LL_SC && !ISA_HAS_LDADD"
{ return mips_output_sync_loop (insn, operands); } { return mips_output_sync_loop (insn, operands); }
[(set_attr "sync_insn1" "addiu,addu") [(set_attr "sync_insn1" "addiu,addu")
(set_attr "sync_oldval" "0") (set_attr "sync_oldval" "0")
(set_attr "sync_mem" "1") (set_attr "sync_mem" "1")
(set_attr "sync_insn1_op2" "2") (set_attr "sync_insn1_op2" "2")
(set_attr "sync_memmodel" "3")]) (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")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment