constraints.md (ZR): New constraint.
authorTom de Vries <vries@codesourcery.com>
Wed, 20 Jun 2012 00:59:08 +0000 (00:59 +0000)
committerMaxim Kuvyrkov <mkuvyrkov@gcc.gnu.org>
Wed, 20 Jun 2012 00:59:08 +0000 (00:59 +0000)
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

gcc/ChangeLog
gcc/config/mips/constraints.md
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/predicates.md
gcc/config/mips/sync.md

index 069b61c9535b5ab44e4a642e5df697586617aa45..0b679ae5d8ba67dc3b44ddd36d1a209cf1248aff 100644 (file)
@@ -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>
 
index 2bfb2aaf2c57f72a711acf6960566795defe5b2c..b543217c43ab6babc9c3c08ef35fd9c35bc42812 100644 (file)
 (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"))
index f37c19499d7ff2f442b9b9502970b7ed255a87d2..64b486d1d0b683f0644d835b84a51818cb8940cd 100644 (file)
@@ -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
index 97f38b2c49b8cc129988e594c741c0b9aec75b71..d8b0c6384e2f2e4b19af1d46ff68d1e64485ad48 100644 (file)
@@ -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)
 
index 57b1af2de3e26e17edff379c27296b4cfbc99ce3..97971e9a205fba4e34bfdfe8ef8044068705c249 100644 (file)
 (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")))
index 604aefa3d0e5180e09292d121e4c0c6a09fcef80..0a7905a3300e62477053d00c93eee2fe118242b7 100644 (file)
    (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;
         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")
    (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;
         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")