builtins.c (expand_builtin_sync_operation): Revert last change.
authorRichard Henderson <rth@redhat.com>
Wed, 20 Apr 2005 04:54:11 +0000 (21:54 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 20 Apr 2005 04:54:11 +0000 (21:54 -0700)
        * builtins.c (expand_builtin_sync_operation): Revert last change.
        * optabs.c (expand_bool_compare_and_swap): Compare vs old value,
        not vs new value.
        (expand_compare_and_swap_loop): Likewise.
        (expand_sync_operation): Remove fallback from NAND to AND; invert
        memory operand when expanding from cmpxchg.
        (expand_sync_fetch_operation): Likewise.
        * doc/extend.texi (Atomic Builtins): Fix docs for nand and
        compare-and-swap.

        * config/alpha/alpha.c (alpha_split_atomic_op): Invert memory operand
        when implementing NAND.  Fix double-add for AFTER.
        * config/alpha/sync.md (sync_nand<I48MODE>): Invert memory operand.
        (sync_old_nand<I48MODE>, sync_new_nand<I48MODE>): Likewise.
        (sync_compare_and_swap<I48MODE>): Fix compare vs zero.  Return old
        memory value.
        (sync_lock_test_and_set<I48MODE>): Remove extra label and last
        memory barrier.

        * config/i386/sync.md (sync_compare_and_swap<IMODE>): Fix pattern
        to return old memory value.
        (sync_compare_and_swap_cc<IMODE>): Likewise.

        * config/ia64/ia64.c (ia64_dependencies_evaluation_hook): Early
        return pre-reload.  Don't consider output or anti dependencies.
        * config/ia64/sync.md (IMODE): New.
        (modesuffix): Add QI and HI.
        (memory_barrier): Simplify expansion.
        (sync_compare_and_swap<IMODE>): Use IMODE, not I48MODE.
        (cmpxchg_acq_<IMODE>): Likewise.
        (sync_lock_test_and_set<IMODE>): Likewise.
        (sync_lock_release<IMODE>): Likewise.

From-SVN: r98436

15 files changed:
gcc/ChangeLog
gcc/builtins.c
gcc/config/alpha/alpha.c
gcc/config/alpha/sync.md
gcc/config/i386/sync.md
gcc/config/ia64/ia64.c
gcc/config/ia64/sync.md
gcc/doc/extend.texi
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ia64-sync-1.c
gcc/testsuite/gcc.dg/ia64-sync-2.c
gcc/testsuite/gcc.dg/ia64-sync-3.c
gcc/testsuite/gcc.dg/ia64-sync-4.c
gcc/testsuite/lib/target-supports.exp

index f4737d7..bb9d66a 100644 (file)
@@ -1,3 +1,38 @@
+2005-04-19  Richard Henderson  <rth@redhat.com>
+
+       * builtins.c (expand_builtin_sync_operation): Revert last change.
+       * optabs.c (expand_bool_compare_and_swap): Compare vs old value,
+       not vs new value.
+       (expand_compare_and_swap_loop): Likewise.
+       (expand_sync_operation): Remove fallback from NAND to AND; invert
+       memory operand when expanding from cmpxchg.
+       (expand_sync_fetch_operation): Likewise.
+       * doc/extend.texi (Atomic Builtins): Fix docs for nand and
+       compare-and-swap.
+
+       * config/alpha/alpha.c (alpha_split_atomic_op): Invert memory operand
+       when implementing NAND.  Fix double-add for AFTER.
+       * config/alpha/sync.md (sync_nand<I48MODE>): Invert memory operand.
+       (sync_old_nand<I48MODE>, sync_new_nand<I48MODE>): Likewise.
+       (sync_compare_and_swap<I48MODE>): Fix compare vs zero.  Return old
+       memory value.
+       (sync_lock_test_and_set<I48MODE>): Remove extra label and last
+       memory barrier.
+
+       * config/i386/sync.md (sync_compare_and_swap<IMODE>): Fix pattern
+       to return old memory value.
+       (sync_compare_and_swap_cc<IMODE>): Likewise.
+
+       * config/ia64/ia64.c (ia64_dependencies_evaluation_hook): Early
+       return pre-reload.  Don't consider output or anti dependencies.
+       * config/ia64/sync.md (IMODE): New.
+       (modesuffix): Add QI and HI.
+       (memory_barrier): Simplify expansion.
+       (sync_compare_and_swap<IMODE>): Use IMODE, not I48MODE.
+       (cmpxchg_acq_<IMODE>): Likewise.
+       (sync_lock_test_and_set<IMODE>): Likewise.
+       (sync_lock_release<IMODE>): Likewise.
+
 2005-04-19  James A. Morrison  <phython@gcc.gnu.org>
 
        * fold-const.c (fold_binary): Fold ~(X ^ Y) to ~X ^ Y or X ^ ~Y if
index e907752..33102e0 100644 (file)
@@ -5255,20 +5255,13 @@ expand_builtin_sync_operation (tree arglist, enum rtx_code code, bool after,
 {
   enum machine_mode mode;
   rtx addr, val, mem;
-  tree valt;
 
   /* Expand the operands.  */
   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
   mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (TREE_VALUE (arglist))));
 
   arglist = TREE_CHAIN (arglist);
-  valt = TREE_VALUE (arglist);
-  if (code == NOT && TREE_CONSTANT (valt))
-    {
-      valt = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (valt), valt);
-      code = AND;
-    }
-  val = expand_expr (valt, NULL, mode, EXPAND_NORMAL);
+  val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
 
   /* Note that we explicitly do not want any alias information for this
      memory, so that we kill all other live memories.  Otherwise we don't
index 895189b..69d67f9 100644 (file)
@@ -4502,15 +4502,15 @@ alpha_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
 
   if (code == NOT)
     {
-      x = gen_rtx_NOT (mode, val);
-      x = gen_rtx_AND (mode, x, before);
+      x = gen_rtx_NOT (mode, before);
+      x = gen_rtx_AND (mode, x, val);
     }
   else
     x = gen_rtx_fmt_ee (code, mode, before, val);
 
-  emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
   if (after)
     emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
+  emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
 
   cond = gen_rtx_REG (DImode, REGNO (scratch));
   if (mode == SImode)
index 755a3f3..937a17a 100644 (file)
 (define_insn_and_split "sync_nand<mode>"
   [(set (match_operand:I48MODE 0 "memory_operand" "+m")
        (unspec_volatile:I48MODE
-         [(and:I48MODE
-            (not:I48MODE
-              (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI"))
-            (match_dup 0))]
+         [(and:I48MODE (not:I48MODE (match_dup 0))
+            (match_operand:I48MODE 1 "register_operand" "r"))]
          UNSPECV_ATOMIC))
    (clobber (match_scratch:I48MODE 2 "=&r"))]
   ""
        (match_operand:I48MODE 1 "memory_operand" "+m"))
    (set (match_dup 1)
        (unspec_volatile:I48MODE
-         [(and:I48MODE
-            (not:I48MODE
-              (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI"))
-            (match_dup 1))]
+         [(and:I48MODE (not:I48MODE (match_dup 1))
+            (match_operand:I48MODE 2 "register_operand" "r"))]
          UNSPECV_ATOMIC))
    (clobber (match_scratch:I48MODE 3 "=&r"))]
   ""
 (define_insn_and_split "sync_new_nand<mode>"
   [(set (match_operand:I48MODE 0 "register_operand" "=&r")
        (and:I48MODE 
-         (not:I48MODE
-           (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI"))
-         (match_operand:I48MODE 1 "memory_operand" "+m")))
+         (not:I48MODE (match_operand:I48MODE 1 "memory_operand" "+m"))
+         (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))
    (set (match_dup 1)
        (unspec_volatile:I48MODE
-         [(and:I48MODE (not:I48MODE (match_dup 2)) (match_dup 1))]
+         [(and:I48MODE (not:I48MODE (match_dup 1)) (match_dup 2))]
          UNSPECV_ATOMIC))
    (clobber (match_scratch:I48MODE 3 "=&r"))]
   ""
   emit_insn (gen_load_locked_<mode> (retval, mem));
 
   x = gen_lowpart (DImode, retval);
-  x = gen_rtx_EQ (DImode, x, oldval);
-  if (oldval != const0_rtx)
+  if (oldval == const0_rtx)
+    x = gen_rtx_NE (DImode, x, const0_rtx);
+  else
     {
+      x = gen_rtx_EQ (DImode, x, oldval);
       emit_insn (gen_rtx_SET (VOIDmode, cond, x));
       x = gen_rtx_EQ (DImode, cond, const0_rtx);
     }
   REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
     
   emit_move_insn (scratch, newval);
-  emit_move_insn (retval, newval);
-  
+
   emit_insn (gen_store_conditional_<mode> (cond, mem, scratch));
 
   x = gen_rtx_EQ (DImode, cond, const0_rtx);
   x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
   REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
 
-  emit_label (XEXP (label2, 0));
   emit_insn (gen_memory_barrier ());
+  emit_label (XEXP (label2, 0));
   DONE;
 }
   [(set_attr "type" "multi")])
   [(const_int 0)]
 {
   rtx retval, mem, val, scratch;
-  rtx cond, label1, label2, x;
+  rtx cond, label1, x;
   rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
 
   retval = operands[0];
   emit_insn (gen_memory_barrier ());
 
   label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
-  label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
   emit_label (XEXP (label1, 0));
 
   emit_insn (gen_load_locked_<mode> (retval, mem));
   x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
   REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
 
-  emit_label (XEXP (label2, 0));
-  emit_insn (gen_memory_barrier ());
   DONE;
 }
   [(set_attr "type" "multi")])
index 477b398..99d100f 100644 (file)
 
 (define_insn "sync_compare_and_swap<mode>"
   [(set (match_operand:IMODE 0 "register_operand" "=a")
+       (match_operand:IMODE 1 "memory_operand" "+m"))
+   (set (match_dup 1)
        (unspec_volatile:IMODE
-         [(match_operand:IMODE 1 "memory_operand" "+m")
+         [(match_dup 1)
           (match_operand:IMODE 2 "register_operand" "a")
           (match_operand:IMODE 3 "register_operand" "<modeconstraint>")]
          UNSPECV_CMPXCHG_1))
-   (set (match_dup 1)
-       (unspec_volatile:IMODE
-         [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_CMPXCHG"
   "lock\;cmpxchg{<modesuffix>}\t{%3, %1|%1, %3}")
 (define_expand "sync_compare_and_swap_cc<mode>"
   [(parallel
     [(set (match_operand:IMODE 0 "register_operand" "")
+         (match_operand:IMODE 1 "memory_operand" ""))
+     (set (match_dup 1)
          (unspec_volatile:IMODE
-           [(match_operand:IMODE 1 "memory_operand" "")
+           [(match_dup 1)
             (match_operand:IMODE 2 "register_operand" "")
             (match_operand:IMODE 3 "register_operand" "")]
            UNSPECV_CMPXCHG_1))
-     (set (match_dup 1)
-         (unspec_volatile:IMODE
-           [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2))
      (set (match_dup 4)
          (compare:CCZ
            (unspec_volatile:IMODE
-             [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_1)
-           (match_dup 3)))])]
+             [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2)
+           (match_dup 2)))])]
   "TARGET_CMPXCHG"
 {
   operands[4] = gen_rtx_REG (CCZmode, FLAGS_REG);
 
 (define_insn "*sync_compare_and_swap_cc<mode>"
   [(set (match_operand:IMODE 0 "register_operand" "=a")
+       (match_operand:IMODE 1 "memory_operand" "+m"))
+   (set (match_dup 1)
        (unspec_volatile:IMODE
-         [(match_operand:IMODE 1 "memory_operand" "+m")
+         [(match_dup 1)
           (match_operand:IMODE 2 "register_operand" "a")
           (match_operand:IMODE 3 "register_operand" "<modeconstraint>")]
          UNSPECV_CMPXCHG_1))
-   (set (match_dup 1)
-       (unspec_volatile:IMODE
-         [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2))
    (set (reg:CCZ FLAGS_REG)
        (compare:CCZ
          (unspec_volatile:IMODE
-           [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_1)
-         (match_dup 3)))]
+           [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2)
+         (match_dup 2)))]
   "TARGET_CMPXCHG"
   "lock\;cmpxchg{<modesuffix>}\t{%3, %1|%1, %3}")
 
index 82dff03..2435922 100644 (file)
@@ -5814,6 +5814,12 @@ ia64_dependencies_evaluation_hook (rtx head, rtx tail)
 {
   rtx insn, link, next, next_tail;
 
+  /* Before reload, which_alternative is not set, which means that
+     ia64_safe_itanium_class will produce wrong results for (at least)
+     move instructions.  */
+  if (!reload_completed)
+    return;
+
   next_tail = NEXT_INSN (tail);
   for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
     if (INSN_P (insn))
@@ -5824,6 +5830,8 @@ ia64_dependencies_evaluation_hook (rtx head, rtx tail)
       {
        for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
          {
+           if (REG_NOTE_KIND (link) != REG_DEP_TRUE)
+             continue;
            next = XEXP (link, 0);
            if ((ia64_safe_itanium_class (next) == ITANIUM_CLASS_ST
                 || ia64_safe_itanium_class (next) == ITANIUM_CLASS_STF)
index bca52b0..0ea8e96 100644 (file)
 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
+(define_mode_macro IMODE [QI HI SI DI])
 (define_mode_macro I48MODE [SI DI])
-(define_mode_attr modesuffix [(SI "4") (DI "8")])
+(define_mode_attr modesuffix [(QI "1") (HI "2") (SI "4") (DI "8")])
 
 
-(define_expand "memory_barrier"
-  [(set (mem:BLK (match_dup 0))
-       (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
-  ""
-{
-  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
-  MEM_VOLATILE_P (operands[0]) = 1;
-})
-
-(define_insn "*mf_internal"
-  [(set (match_operand:BLK 0 "" "")
-       (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))]
+(define_insn "memory_barrier"
+  [(set (mem:BLK (match_scratch:DI 0 "X"))
+       (unspec:BLK [(mem:BLK (match_scratch:DI 1 "X"))] UNSPEC_MF))]
   ""
   "mf"
   [(set_attr "itanium_class" "syst_m")])
   [(set_attr "itanium_class" "sem")])
 
 (define_expand "sync_compare_and_swap<mode>"
-  [(match_operand:I48MODE 0 "gr_register_operand" "")
-   (match_operand:I48MODE 1 "memory_operand" "")
-   (match_operand:I48MODE 2 "gr_register_operand" "")
-   (match_operand:I48MODE 3 "gr_register_operand" "")]
+  [(match_operand:IMODE 0 "gr_register_operand" "")
+   (match_operand:IMODE 1 "memory_operand" "")
+   (match_operand:IMODE 2 "gr_register_operand" "")
+   (match_operand:IMODE 3 "gr_register_operand" "")]
   ""
 {
   rtx ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
 })
 
 (define_insn "cmpxchg_acq_<mode>"
-  [(set (match_operand:I48MODE 0 "gr_register_operand" "=r")
-       (match_operand:I48MODE 1 "not_postinc_memory_operand" "+S"))
+  [(set (match_operand:IMODE 0 "gr_register_operand" "=r")
+       (match_operand:IMODE 1 "not_postinc_memory_operand" "+S"))
    (set (match_dup 1)
-        (unspec:I48MODE [(match_dup 1)
-                        (match_operand:DI 2 "ar_ccv_reg_operand" "")
-                        (match_operand:I48MODE 3 "gr_register_operand" "r")]
-                       UNSPEC_CMPXCHG_ACQ))]
+        (unspec:IMODE [(match_dup 1)
+                      (match_operand:DI 2 "ar_ccv_reg_operand" "")
+                      (match_operand:IMODE 3 "gr_register_operand" "r")]
+                     UNSPEC_CMPXCHG_ACQ))]
   ""
   "cmpxchg<modesuffix>.acq %0 = %1, %3, %2"
   [(set_attr "itanium_class" "sem")])
 
 (define_insn "sync_lock_test_and_set<mode>"
-  [(set (match_operand:I48MODE 0 "gr_register_operand" "=r")
-        (match_operand:I48MODE 1 "not_postinc_memory_operand" "+S"))
+  [(set (match_operand:IMODE 0 "gr_register_operand" "=r")
+        (match_operand:IMODE 1 "not_postinc_memory_operand" "+S"))
    (set (match_dup 1)
-        (match_operand:I48MODE 2 "gr_register_operand" "r"))]
+        (match_operand:IMODE 2 "gr_register_operand" "r"))]
   ""
   "xchg<modesuffix> %0 = %1, %2"
   [(set_attr "itanium_class" "sem")])
 
 (define_expand "sync_lock_release<mode>"
-  [(set (match_operand:I48MODE 0 "memory_operand" "")
-       (match_operand:I48MODE 1 "gr_reg_or_0_operand" ""))]
+  [(set (match_operand:IMODE 0 "memory_operand" "")
+       (match_operand:IMODE 1 "gr_reg_or_0_operand" ""))]
   ""
 {
   gcc_assert (MEM_VOLATILE_P (operands[0]));
index 5fc85a4..acd75e4 100644 (file)
@@ -4639,11 +4639,9 @@ returns the value that had previously been in memory.  That is,
 
 @smallexample
 @{ tmp = *ptr; *ptr @var{op}= value; return tmp; @}
+@{ tmp = *ptr; *ptr = ~tmp & value; return tmp; @}   // nand
 @end smallexample
 
-The builtin @code{__sync_fetch_and_nand} could be implemented by
-@code{__sync_fetch_and_and(ptr, ~value)}.
-
 @item @var{type} __sync_add_and_fetch (@var{type} *ptr, @var{type} value, ...)
 @itemx @var{type} __sync_sub_and_fetch (@var{type} *ptr, @var{type} value, ...)
 @itemx @var{type} __sync_or_and_fetch (@var{type} *ptr, @var{type} value, ...)
@@ -4661,6 +4659,7 @@ return the new value.  That is,
 
 @smallexample
 @{ *ptr @var{op}= value; return *ptr; @}
+@{ *ptr = ~*ptr & value; return *ptr; @}   // nand
 @end smallexample
 
 @item bool __sync_bool_compare_and_swap (@var{type} *ptr, @var{type} oldval @var{type} newval, ...)
@@ -4673,7 +4672,7 @@ value of @code{*@var{ptr}} is @var{oldval}, then write @var{newval} into
 
 The ``bool'' version returns true if the comparison is successful and 
 @var{newval} was written.  The ``val'' version returns the contents
-of @code{*@var{ptr}} after the operation.
+of @code{*@var{ptr}} before the operation.
 
 @item __sync_synchronize (...)
 @findex __sync_synchronize
index 90a42c2..e1b9e3d 100644 (file)
@@ -5588,12 +5588,17 @@ expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
       if (icode == CODE_FOR_nothing)
        return NULL_RTX;
 
+      /* Ensure that if old_val == mem, that we're not comparing
+        against an old value.  */
+      if (GET_CODE (old_val) == MEM)
+       old_val = force_reg (mode, old_val);
+
       subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
                                                 NULL_RTX, icode);
       if (subtarget == NULL_RTX)
        return NULL_RTX;
 
-      emit_cmp_insn (subtarget, new_val, EQ, const0_rtx, mode, true);
+      emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
     }
 
   /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
@@ -5700,7 +5705,7 @@ expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
       if (subtarget == NULL_RTX)
        return false;
 
-      emit_cmp_insn (subtarget, new_reg, EQ, const0_rtx, mode, true);
+      emit_cmp_insn (subtarget, old_reg, EQ, const0_rtx, mode, true);
     }
 
   /* ??? Mark this jump predicted not taken?  */
@@ -5735,6 +5740,9 @@ expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
     case AND:
       icode = sync_and_optab[mode];
       break;
+    case NOT:
+      icode = sync_nand_optab[mode];
+      break;
 
     case MINUS:
       icode = sync_sub_optab[mode];
@@ -5749,19 +5757,6 @@ expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
        }
       break;
 
-    case NOT:
-      icode = sync_nand_optab[mode];
-      if (icode == CODE_FOR_nothing)
-       {
-         icode = sync_and_optab[mode];
-         if (icode != CODE_FOR_nothing)
-           {
-             val = expand_simple_unop (mode, NOT, val, NULL_RTX, 1);
-             code = AND;
-           }
-       }
-      break;
-
     default:
       gcc_unreachable ();
     }
@@ -5790,12 +5785,13 @@ expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
 
       start_sequence ();
 
+      t1 = t0;
       if (code == NOT)
        {
-         val = expand_simple_unop (mode, NOT, val, NULL_RTX, true);
+         t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
          code = AND;
        }
-      t1 = expand_simple_binop (mode, code, t0, val, NULL_RTX,
+      t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
                                true, OPTAB_LIB_WIDEN);
 
       insn = get_insns ();
@@ -5842,6 +5838,10 @@ expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
       old_code = sync_old_and_optab[mode];
       new_code = sync_new_and_optab[mode];
       break;
+    case NOT:
+      old_code = sync_old_nand_optab[mode];
+      new_code = sync_new_nand_optab[mode];
+      break;
 
     case MINUS:
       old_code = sync_old_sub_optab[mode];
@@ -5858,21 +5858,6 @@ expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
        }
       break;
 
-    case NOT:
-      old_code = sync_old_nand_optab[mode];
-      new_code = sync_new_nand_optab[mode];
-      if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
-       {
-         old_code = sync_old_sub_optab[mode];
-         new_code = sync_new_sub_optab[mode];
-         if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
-           {
-             val = expand_simple_unop (mode, NOT, val, NULL_RTX, 1);
-             code = AND;
-           }
-       }
-      break;
-
     default:
       gcc_unreachable ();
     }
@@ -5933,6 +5918,9 @@ expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
                  else if (code == MINUS)
                    code = PLUS;
                }
+
+             if (code == NOT)
+               target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
              target = expand_simple_binop (mode, code, target, val, NULL_RTX,
                                            true, OPTAB_LIB_WIDEN);
            }
@@ -5952,14 +5940,15 @@ expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
 
       start_sequence ();
 
+      if (!after)
+       emit_move_insn (target, t0);
+      t1 = t0;
       if (code == NOT)
        {
-         val = expand_simple_unop (mode, NOT, val, NULL_RTX, true);
+         t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
          code = AND;
        }
-      if (!after)
-       emit_move_insn (target, t0);
-      t1 = expand_simple_binop (mode, code, t0, val, NULL_RTX,
+      t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
                                true, OPTAB_LIB_WIDEN);
       if (after)
        emit_move_insn (target, t1);
index c7d9f2e..f256d75 100644 (file)
@@ -1,3 +1,13 @@
+2005-04-19  Richard Henderson  <rth@redhat.com>
+
+       * lib/target-supports.exp (check_effective_target_vect_int_mult): 
+       Fix typo in exists check.
+       (check_effective_target_sync_int_long): New.
+       * gcc.dg/ia64-sync-1.c: Enable for all effective-target sync_int_long.
+       * gcc.dg/ia64-sync-2.c: Likewise.
+       * gcc.dg/ia64-sync-3.c: Likewise.
+       * gcc.dg/ia64-sync-4.c: Likewise.
+
 2005-04-19  James A. Morrison  <phython@gcc.gnu.org>
 
        * gcc.dg/fold-xor-1.c: New test.
index c33bf3b..f58f8cb 100644 (file)
@@ -1,11 +1,12 @@
-/* { dg-do run { target ia64-*-* } } */
+/* { dg-do run } */
+/* { dg-require-effective-target sync_int_long } */
 /* { dg-options } */
+/* { dg-options "-march=i486" { target i?86-*-* } } */
+/* { dg-options "-march=i486" { target { x86_64-*-* && ilp32 } } } */
 
 /* Test basic functionality of the intrinsics.  The operations should
    not be optimized away if no one checks the return values.  */
 
-#include <ia64intrin.h>
-
 extern void abort (void);
 extern void *memcpy (void *, const void *, __SIZE_TYPE__);
 
index e7dd65f..000a267 100644 (file)
@@ -1,10 +1,11 @@
-/* { dg-do run { target ia64-*-* } } */
+/* { dg-do run } */
+/* { dg-require-effective-target sync_int_long } */
 /* { dg-options } */
+/* { dg-options "-march=i486" { target i?86-*-* } } */
+/* { dg-options "-march=i486" { target { x86_64-*-* && ilp32 } } } */
 
 /* Test basic functionality of the intrinsics.  */
 
-#include <ia64intrin.h>
-
 extern void abort (void);
 extern void *memcpy (void *, const void *, __SIZE_TYPE__);
 
index c2772f7..46f6294 100644 (file)
@@ -1,10 +1,11 @@
-/* { dg-do run { target ia64-*-* } } */
+/* { dg-do run } */
+/* { dg-require-effective-target sync_int_long } */
 /* { dg-options } */
+/* { dg-options "-march=i486" { target i?86-*-* } } */
+/* { dg-options "-march=i486" { target { x86_64-*-* && ilp32 } } } */
 
 /* Test basic functionality of the intrinsics.  */
 
-#include <ia64intrin.h>
-
 extern void abort (void);
 extern void *memcpy (void *, const void *, __SIZE_TYPE__);
 
index 98dfdac..baeb852 100644 (file)
@@ -1,15 +1,17 @@
-/* { dg-do compile { target ia64-*-* } } */
+/* { dg-do compile } */
+/* { dg-require-effective-target sync_int_long } */
 /* { dg-options "-O2 -finline-functions" } */
+/* { dg-options "-march=i486" { target i?86-*-* } } */
+/* { dg-options "-march=i486" { target { x86_64-*-* && ilp32 } } } */
 
-/* Test inlining __sync_bool_compare_and_swap_di.  */
+/* Test inlining __sync_bool_compare_and_swap.  */
 
 #include <stdbool.h>
-#include <ia64intrin.h>
 
 static bool
 compare_and_swap(long *addr, long old, long new_val)
 {
-  return __sync_bool_compare_and_swap_di(addr, old, new_val);
+  return __sync_bool_compare_and_swap(addr, old, new_val);
 }
 
 void
index 18d0e9d..ab9953f 100644 (file)
@@ -861,7 +861,7 @@ proc check_effective_target_vect_condition { } {
 proc check_effective_target_vect_int_mult { } {
     global et_vect_int_mult_saved
 
-    if [info exists et_vect_int_mult] {
+    if [info exists et_vect_int_mult_saved] {
        verbose "check_effective_target_vect_int_mult: using cached result" 2
     } else {
        set et_vect_int_mult_saved 0
@@ -874,6 +874,27 @@ proc check_effective_target_vect_int_mult { } {
     return $et_vect_int_mult_saved
 }
 
+# Return 1 if the target supports atomic operations on "int" and "long".
+
+proc check_effective_target_sync_int_long { } {
+    global et_sync_int_long_saved
+
+    if [info exists et_sync_int_long_saved] {
+        verbose "check_effective_target_sync_int_long: using cached result" 2
+    } else {
+        set et_sync_int_long_saved 0
+        if { [istarget ia64-*-*]
+            || [istarget i?86-*-*]
+            || [istarget x86_64-*-*]
+            || [istarget alpha*-*-*] } {
+           set et_sync_int_long_saved 1
+        }
+    }
+
+    verbose "check_effective_target_sync_int_long: returning $et_sync_int_long_saved" 2
+    return $et_sync_int_long_saved
+}
+
 # Return 1 if the target matches the effective target 'arg', 0 otherwise.
 # This can be used with any check_* proc that takes no argument and
 # returns only 1 or 0.  It could be used with check_* procs that take