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
This commit is contained in:
parent
01c196ea91
commit
6399761a4a
6 changed files with 90 additions and 6 deletions
|
@ -1,3 +1,16 @@
|
|||
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>
|
||||
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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")))
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Add table
Reference in a new issue