target-supports.exp (check_effective_target_sync_int_long): Add mips*-*-*.
authorDavid Daney <ddaney@avtrex.com>
Thu, 8 May 2008 17:04:12 +0000 (17:04 +0000)
committerDavid Daney <daney@gcc.gnu.org>
Thu, 8 May 2008 17:04:12 +0000 (17:04 +0000)
2008-05-08  David Daney  <ddaney@avtrex.com>

* lib/target-supports.exp (check_effective_target_sync_int_long): Add
mips*-*-*.
(check_effective_target_sync_char_short): Same.

2008-05-08  David Daney  <ddaney@avtrex.com>
    Richard Sandiford  <rsandifo@nildram.co.uk>

* config/mips/mips.md (mips_expand_compare_and_swap_12): Handle
special case of constant zero operands.
* config/mips/mips.c (mips_expand_compare_and_swap_12): Zero extend
old and new values.  Special case constant zero values.
* config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Skip 'sync' if compare
fails.
(MIPS_COMPARE_AND_SWAP_12): Handle constant zero operands.
(MIPS_COMPARE_AND_SWAP_12_0): New macro.

Co-Authored-By: Richard Sandiford <rsandifo@nildram.co.uk>
From-SVN: r135088

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md
gcc/testsuite/ChangeLog
gcc/testsuite/lib/target-supports.exp

index 7ac7cd27fe3ece451ba5affccae7bec14f09a3a2..ae8d7a9d19716a0277bb55326602b3deab1ee587 100644 (file)
@@ -1,3 +1,15 @@
+2008-05-08  David Daney  <ddaney@avtrex.com>
+           Richard Sandiford  <rsandifo@nildram.co.uk>
+       
+       * config/mips/mips.md (mips_expand_compare_and_swap_12): Handle
+       special case of constant zero operands.
+       * config/mips/mips.c (mips_expand_compare_and_swap_12): Zero extend
+       old and new values.  Special case constant zero values.
+       * config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Skip 'sync' if compare
+       fails.
+       (MIPS_COMPARE_AND_SWAP_12): Handle constant zero operands.
+       (MIPS_COMPARE_AND_SWAP_12_0): New macro.
+
 2008-05-08  Paolo Bonzini  <bonzini@gnu.org>
 
        PR target/36090
index de2e42a33c70effe513c95ffa3f6a19e10bd563a..218953385b3e8f6af01f9bae2a55cf72a4b4f540 100644 (file)
@@ -5880,7 +5880,10 @@ void
 mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
 {
   rtx orig_addr, memsi_addr, memsi, shift, shiftsi, unshifted_mask;
-  rtx mask, inverted_mask, oldvalsi, old_shifted, newvalsi, new_shifted, res;
+  rtx unshifted_mask_reg, mask, inverted_mask, res;
+  enum machine_mode mode;
+
+  mode = GET_MODE (mem);
 
   /* Compute the address of the containing SImode value.  */
   orig_addr = force_reg (Pmode, XEXP (mem, 0));
@@ -5896,8 +5899,7 @@ mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
      counting from the least significant byte.  */
   shift = mips_force_binary (Pmode, AND, orig_addr, GEN_INT (3));
   if (TARGET_BIG_ENDIAN)
-    mips_emit_binary (XOR, shift, shift,
-                     GEN_INT (GET_MODE (mem) == QImode ? 3 : 2));
+    mips_emit_binary (XOR, shift, shift, GEN_INT (mode == QImode ? 3 : 2));
 
   /* Multiply by eight to convert the shift value from bytes to bits.  */
   mips_emit_binary (ASHIFT, shift, shift, GEN_INT (3));
@@ -5907,9 +5909,9 @@ mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
   shiftsi = force_reg (SImode, gen_lowpart (SImode, shift));
 
   /* Set MASK to an inclusive mask of the QImode or HImode value.  */
-  unshifted_mask = GEN_INT (GET_MODE_MASK (GET_MODE (mem)));
-  unshifted_mask = force_reg (SImode, unshifted_mask);
-  mask = mips_force_binary (SImode, ASHIFT, unshifted_mask, shiftsi);
+  unshifted_mask = GEN_INT (GET_MODE_MASK (mode));
+  unshifted_mask_reg = force_reg (SImode, unshifted_mask);
+  mask = mips_force_binary (SImode, ASHIFT, unshifted_mask_reg, shiftsi);
 
   /* Compute the equivalent exclusive mask.  */
   inverted_mask = gen_reg_rtx (SImode);
@@ -5917,17 +5919,25 @@ mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
                          gen_rtx_NOT (SImode, mask)));
 
   /* Shift the old value into place.  */
-  oldvalsi = force_reg (SImode, gen_lowpart (SImode, oldval));
-  old_shifted = mips_force_binary (SImode, ASHIFT, oldvalsi, shiftsi);
+  if (oldval != const0_rtx)
+    {
+      oldval = convert_modes (SImode, mode, oldval, true);
+      oldval = force_reg (SImode, oldval);
+      oldval = mips_force_binary (SImode, ASHIFT, oldval, shiftsi);
+    }
 
   /* Do the same for the new value.  */
-  newvalsi = force_reg (SImode, gen_lowpart (SImode, newval));
-  new_shifted = mips_force_binary (SImode, ASHIFT, newvalsi, shiftsi);
+  if (newval != const0_rtx)
+    {
+      newval = convert_modes (SImode, mode, newval, true);
+      newval = force_reg (SImode, newval);
+      newval = mips_force_binary (SImode, ASHIFT, newval, shiftsi);
+    }
 
   /* Do the SImode atomic access.  */
   res = gen_reg_rtx (SImode);
   emit_insn (gen_compare_and_swap_12 (res, memsi, mask, inverted_mask,
-                                     old_shifted, new_shifted));
+                                     oldval, newval));
 
   /* Shift and convert the result.  */
   mips_emit_binary (AND, res, res, mask);
index 1391c99dde45e9f5c4cfc47f00e2bf2025287558..9f59f1a2550c1cb6c90a71ec018d1bc658860ce9 100644 (file)
@@ -2902,7 +2902,8 @@ while (0)
   "\tsc" SUFFIX "\t%@,%1\n"                    \
   "\tbeq\t%@,%.,1b\n"                          \
   "\tnop\n"                                    \
-  "2:\tsync%-%]%>%)"
+  "\tsync%-%]%>%)\n"                           \
+  "2:\n"
 
 /* Return an asm string that atomically:
 
@@ -2919,7 +2920,7 @@ while (0)
   "%(%<%[%|sync\n"                             \
   "1:\tll\t%0,%1\n"                            \
   "\tand\t%@,%0,%2\n"                          \
-  "\tbne\t%@,%4,2f\n"                          \
+  "\tbne\t%@,%z4,2f\n"                         \
   "\tand\t%@,%0,%3\n"                          \
   "\tor\t%@,%@,%5\n"                           \
   "\tsc\t%@,%1\n"                              \
@@ -2928,6 +2929,20 @@ while (0)
   "\tsync%-%]%>%)\n"                           \
   "2:\n"
 
+/* Like MIPS_COMPARE_AND_SWAP_12, except %5 is a constant zero,
+   so the OR can be omitted.  */
+#define MIPS_COMPARE_AND_SWAP_12_0             \
+  "%(%<%[%|sync\n"                             \
+  "1:\tll\t%0,%1\n"                            \
+  "\tand\t%@,%0,%2\n"                          \
+  "\tbne\t%@,%z4,2f\n"                         \
+  "\tand\t%@,%0,%3\n"                          \
+  "\tsc\t%@,%1\n"                              \
+  "\tbeq\t%@,%.,1b\n"                          \
+  "\tnop\n"                                    \
+  "\tsync%-%]%>%)\n"                           \
+  "2:\n"
+
 /* Return an asm string that atomically:
 
      - Sets memory reference %0 to %0 INSN %1.
index 05adf2226d4b1322ba8355f77621ed43affebcaf..a423529b3308c5491e0a97caa3d747ff81ec4349 100644 (file)
 
 ;; Helper insn for mips_expand_compare_and_swap_12.
 (define_insn "compare_and_swap_12"
-  [(set (match_operand:SI 0 "register_operand" "=&d")
-       (match_operand:SI 1 "memory_operand" "+R"))
+  [(set (match_operand:SI 0 "register_operand" "=&d,&d")
+       (match_operand:SI 1 "memory_operand" "+R,R"))
    (set (match_dup 1)
-       (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d")
-                            (match_operand:SI 3 "register_operand" "d")
-                            (match_operand:SI 4 "register_operand" "d")
-                            (match_operand:SI 5 "register_operand" "d")]
+       (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d,d")
+                            (match_operand:SI 3 "register_operand" "d,d")
+                            (match_operand:SI 4 "reg_or_0_operand" "dJ,dJ")
+                            (match_operand:SI 5 "reg_or_0_operand" "d,J")]
                            UNSPEC_COMPARE_AND_SWAP_12))]
   "GENERATE_LL_SC"
 {
-  return MIPS_COMPARE_AND_SWAP_12;
+  if (which_alternative == 0)
+    return MIPS_COMPARE_AND_SWAP_12;
+  else
+    return MIPS_COMPARE_AND_SWAP_12_0;
 }
-  [(set_attr "length" "40")])
+  [(set_attr "length" "40,36")])
 
 (define_insn "sync_add<mode>"
   [(set (match_operand:GPR 0 "memory_operand" "+R,R")
index 3106bfbffb9a509781638952c270c41f3974c589..ff5d2cc92ffbbfaf0c64acc925f4e921a7a4d1b1 100644 (file)
@@ -1,3 +1,9 @@
+2008-05-08  David Daney  <ddaney@avtrex.com>
+
+       * lib/target-supports.exp (check_effective_target_sync_int_long): Add
+       mips*-*-*.
+       (check_effective_target_sync_char_short): Same.
+
 2008-05-08  Kai Tietz  <kai.tietz@onevision.com>
 
        * gcc.c-torture/compile/pr36172.c: Replace unsigned long by
index de78c716ee21e37b9fda3a8fe77b2434e1484de9..150a217ea6cb5e3824da98356034e81e60dfab9a 100644 (file)
@@ -2052,7 +2052,8 @@ proc check_effective_target_sync_int_long { } {
             || [istarget s390*-*-*] 
             || [istarget powerpc*-*-*]
             || [istarget sparc64-*-*]
-            || [istarget sparcv9-*-*] } {
+            || [istarget sparcv9-*-*]
+            || [istarget mips*-*-*] } {
            set et_sync_int_long_saved 1
         }
     }
@@ -2079,7 +2080,8 @@ proc check_effective_target_sync_char_short { } {
             || [istarget s390*-*-*] 
             || [istarget powerpc*-*-*]
             || [istarget sparc64-*-*]
-            || [istarget sparcv9-*-*] } {
+            || [istarget sparcv9-*-*]
+            || [istarget mips*-*-*] } {
            set et_sync_char_short_saved 1
         }
     }