rs6000.c (rs6000_emit_sync): Remove support for operand wrapped in NOT.
authorDavid Edelsohn <edelsohn@gnu.org>
Sat, 29 Nov 2008 21:24:03 +0000 (21:24 +0000)
committerDavid Edelsohn <dje@gcc.gnu.org>
Sat, 29 Nov 2008 21:24:03 +0000 (16:24 -0500)
        * config/rs6000/rs6000.c (rs6000_emit_sync): Remove support for
        operand wrapped in NOT.  Emit NAND as (ior (not X) (not Y)).
        (rs6000_split_atomic_op): Emit NAND as (ior (not X) (not Y)).
        * config/rs6000/sync.md (sync_nand<mode>): Represent NAND in RTL.
        Call rs6000_emit_sync with CODE=NOT and unmodified operands.
        Ignore sub-word case for now.
        (sync_nand<mode>_internal): Represent NAND in RTL.
        (sync_old_nand<mode): Same.
        (sync_old_name<mode>_internal): Same.
        (sync_new_nand<mode>): Same.
        (sync_new_nand<mode>_internal): Same.
        (sync_boolcshort_internal): Expect NAND.

From-SVN: r142285

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/sync.md

index 615aad2f7c1a2f243a0d262891794aa692c13208..392b0249f3ddc9233e0272fe3bf965c95d0fff47 100644 (file)
@@ -1,3 +1,18 @@
+2008-11-29  David Edelsohn  <edelsohn@gnu.org>
+
+       * config/rs6000/rs6000.c (rs6000_emit_sync): Remove support for
+       operand wrapped in NOT.  Emit NAND as (ior (not X) (not Y)).
+       (rs6000_split_atomic_op): Emit NAND as (ior (not X) (not Y)).
+       * config/rs6000/sync.md (sync_nand<mode>): Represent NAND in RTL.
+       Call rs6000_emit_sync with CODE=NOT and unmodified operands.
+       Ignore sub-word case for now.
+       (sync_nand<mode>_internal): Represent NAND in RTL.
+       (sync_old_nand<mode): Same.
+       (sync_old_name<mode>_internal): Same.
+       (sync_new_nand<mode>): Same.
+       (sync_new_nand<mode>_internal): Same.
+       (sync_boolcshort_internal): Expect NAND.
+
 2008-11-28  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/37955
index 46b1be0c8c4713e720dac849b68120b9503b3de1..e2d8ddc0003692e92a2e228637f190b451b93448 100644 (file)
@@ -13826,9 +13826,6 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
   if (sync_p)
     emit_insn (gen_lwsync ());
 
-  if (GET_CODE (m) == NOT)
-    used_m = XEXP (m, 0);
-  else
     used_m = m;
 
   /* If this is smaller than SImode, we'll have to use SImode with
@@ -13870,10 +13867,7 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
       /* It's safe to keep the old alias set of USED_M, because
         the operation is atomic and only affects the original
         USED_M.  */
-      if (GET_CODE (m) == NOT)
-       m = gen_rtx_NOT (SImode, used_m);
-      else
-       m = used_m;
+      m = used_m;
 
       if (GET_CODE (op) == NOT)
        {
@@ -13893,6 +13887,13 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
          emit_insn (gen_ashlsi3 (newop, newop, shift));
          break;
 
+       case NOT: /* NAND */
+         newop = expand_binop (SImode, ior_optab,
+                               oldop, GEN_INT (~imask), NULL_RTX,
+                               1, OPTAB_LIB_WIDEN);
+         emit_insn (gen_rotlsi3 (newop, newop, shift));
+         break;
+
        case AND:
          newop = expand_binop (SImode, ior_optab,
                                oldop, GEN_INT (~imask), NULL_RTX,
@@ -13930,19 +13931,6 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
          gcc_unreachable ();
        }
 
-      if (GET_CODE (m) == NOT)
-       {
-         rtx mask, xorm;
-
-         mask = gen_reg_rtx (SImode);
-         emit_move_insn (mask, GEN_INT (imask));
-         emit_insn (gen_ashlsi3 (mask, mask, shift));
-
-         xorm = gen_rtx_XOR (SImode, used_m, mask);
-         /* Depending on the value of 'op', the XOR or the operation might
-            be able to be simplified away.  */
-         newop = simplify_gen_binary (code, SImode, xorm, newop);
-       }
       op = newop;
       used_mode = SImode;
       before = gen_reg_rtx (used_mode);
@@ -13960,11 +13948,15 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
        after = gen_reg_rtx (used_mode);
     }
 
-  if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
+  if ((code == PLUS || code == MINUS)
       && used_mode != mode)
     the_op = op;  /* Computed above.  */
   else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
     the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
+  else if (code == NOT)
+    the_op = gen_rtx_fmt_ee (IOR, used_mode,
+                            gen_rtx_NOT (used_mode, m),
+                            gen_rtx_NOT (used_mode, op));
   else
     the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
 
@@ -14075,7 +14067,9 @@ rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
   emit_load_locked (mode, before, mem);
 
   if (code == NOT)
-    x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
+    x = gen_rtx_IOR (mode,
+                    gen_rtx_NOT (mode, before),
+                    gen_rtx_NOT (mode, val));
   else if (code == AND)
     x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
   else
index 5839715464547b4b5326057823c7cc3108669b96..0adc23cfc04bb36a3825717c485ecf1f4f3bb5dc 100644 (file)
 (define_expand "sync_nand<mode>"
   [(parallel [(set (match_operand:INT1 0 "memory_operand" "")
              (unspec:INT1
-               [(and:INT1 (not:INT1 (match_dup 0))
-                  (match_operand:INT1 1 "gpc_reg_operand" ""))]
+               [(ior:INT1 (not:INT1 (match_dup 0))
+                          (not:INT1 (match_operand:INT1 1 "gpc_reg_operand" "")))]
                UNSPEC_ATOMIC))
              (clobber (scratch:INT1))
              (clobber (scratch:CC))])]
 {
   if (<MODE>mode != SImode && <MODE>mode != DImode)
     {
+      FAIL;
       if (PPC405_ERRATUM77)
        FAIL;
-      rs6000_emit_sync (AND, <MODE>mode,
-                       gen_rtx_NOT (<MODE>mode, operands[0]),
-                       operands[1],
+      rs6000_emit_sync (NOT, <MODE>mode, operands[0], operands[1],
                        NULL_RTX, NULL_RTX, true);
       DONE;
     }
 (define_insn_and_split "*sync_nand<mode>_internal"
   [(set (match_operand:GPR 0 "memory_operand" "+Z")
        (unspec:GPR
-         [(and:GPR (not:GPR (match_dup 0))
-            (match_operand:GPR 1 "gpc_reg_operand" "r"))]
+         [(ior:GPR (not:GPR (match_dup 0))
+                   (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
          UNSPEC_ATOMIC))
    (clobber (match_scratch:GPR 2 "=&r"))
    (clobber (match_scratch:CC 3 "=&x"))]
                   (match_operand:INT1 1 "memory_operand" ""))
              (set (match_dup 1)
                   (unspec:INT1
-                    [(and:INT1 (not:INT1 (match_dup 1))
-                       (match_operand:INT1 2 "gpc_reg_operand" ""))]
+                    [(ior:INT1 (not:INT1 (match_dup 1))
+                               (not:INT1 (match_operand:INT1 2 "gpc_reg_operand" "")))]
                     UNSPEC_ATOMIC))
              (clobber (scratch:INT1))
              (clobber (scratch:CC))])]
 {
   if (<MODE>mode != SImode && <MODE>mode != DImode)
     {
+      FAIL;
       if (PPC405_ERRATUM77)
        FAIL;
-      rs6000_emit_sync (AND, <MODE>mode,
-                       gen_rtx_NOT (<MODE>mode, operands[1]),
-                       operands[2],
+      rs6000_emit_sync (NOT, <MODE>mode, operands[1], operands[2],
                        operands[0], NULL_RTX, true);
       DONE;
     }
        (match_operand:GPR 1 "memory_operand" "+Z"))
    (set (match_dup 1)
        (unspec:GPR
-         [(and:GPR (not:GPR (match_dup 1))
-            (match_operand:GPR 2 "gpc_reg_operand" "r"))]
+         [(ior:GPR (not:GPR (match_dup 1))
+                   (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")))]
          UNSPEC_ATOMIC))
    (clobber (match_scratch:GPR 3 "=&r"))
    (clobber (match_scratch:CC 4 "=&x"))]
 
 (define_expand "sync_new_nand<mode>"
   [(parallel [(set (match_operand:INT1 0 "gpc_reg_operand" "")
-                  (and:INT1
+                  (ior:INT1
                     (not:INT1 (match_operand:INT1 1 "memory_operand" ""))
-                    (match_operand:INT1 2 "gpc_reg_operand" "")))
+                    (not:INT1 (match_operand:INT1 2 "gpc_reg_operand" ""))))
              (set (match_dup 1)
                   (unspec:INT1
-                    [(and:INT1 (not:INT1 (match_dup 1)) (match_dup 2))]
+                    [(ior:INT1 (not:INT1 (match_dup 1))
+                               (not:INT1 (match_dup 2)))]
                     UNSPEC_ATOMIC))
              (clobber (scratch:INT1))
              (clobber (scratch:CC))])]
 {
   if (<MODE>mode != SImode && <MODE>mode != DImode)
     {
+      FAIL;
       if (PPC405_ERRATUM77)
        FAIL;
-      rs6000_emit_sync (AND, <MODE>mode,
-                       gen_rtx_NOT (<MODE>mode, operands[1]),
-                       operands[2],
+      rs6000_emit_sync (NOT, <MODE>mode, operands[1], operands[2],
                        NULL_RTX, operands[0], true);
       DONE;
     }
 
 (define_insn_and_split "*sync_new_nand<mode>_internal"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
-       (and:GPR
+       (ior:GPR
          (not:GPR (match_operand:GPR 1 "memory_operand" "+Z"))
-         (match_operand:GPR 2 "gpc_reg_operand" "r")))
+         (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))))
    (set (match_dup 1)
        (unspec:GPR
-         [(and:GPR (not:GPR (match_dup 1)) (match_dup 2))]
+         [(ior:GPR (not:GPR (match_dup 1)) (not:GPR (match_dup 2)))]
          UNSPEC_ATOMIC))
    (clobber (match_scratch:GPR 3 "=&r"))
    (clobber (match_scratch:CC 4 "=&x"))]
 ; Likewise, operand 5 is in practice either <= 2^16 or it is a register.
 (define_insn "*sync_boolcshort_internal"
   [(set (match_operand:SI 2 "gpc_reg_operand" "=&r")
-       (match_operator:SI 4 "boolean_operator"
-        [(xor:SI (match_operand:SI 0 "memory_operand" "+Z")
-                 (match_operand:SI 5 "logical_operand" "rK"))
-         (match_operand:SI 1 "gpc_reg_operand" "r")]))
+       (match_operator:SI 4 "boolean_or_operator"
+        [(xor:SI (not:SI (match_operand:SI 0 "memory_operand" "+Z"))
+                 (not:SI (match_operand:SI 5 "logical_operand" "rK")))
+        (match_operand:SI 1 "gpc_reg_operand" "r")]))
    (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0))
    (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP))
    (clobber (match_scratch:CC 6 "=&x"))]