This adds a new output modifier "e" that prints an 's' for things like
xoris, and changes "u" to work for both xoris and xori.  With that, both
SI and DI can simply use an "n" constraint, where previously they needed
"K,L" resp. "K,J" (and it used "JF" in fact, but the F doesn't do anything
there).


2014-08-15  Segher Boessenkool  <seg...@kernel.crashing.org>

gcc/
        * config/rs6000/rs6000.c (print_operand) <'e'>: New.
        <'u'>: Also support printing the low-order 16 bits.
        * config/rs6000/rs6000.md (iorsi3, xorsi3, *boolsi3_internal1,
        *boolsi3_internal2 and split, *boolsi3_internal3 and split): Delete.
        (iordi3, xordi3, *booldi3_internal1, *booldi3_internal2 and split,
        *booldi3_internal3 and split): Delete.
        (ior<mode>3, xor<mode>3, *bool<mode>3, *bool<mode>3_dot,
        *bool<mode>3_dot2): New.
        (two anonymous define_splits for non_logical_cint_operand): Merge.

---
 gcc/config/rs6000/rs6000.c  |  30 +++-
 gcc/config/rs6000/rs6000.md | 328 ++++++++++++--------------------------------
 2 files changed, 114 insertions(+), 244 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d90afcc..f7673de 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -17996,6 +17996,19 @@ print_operand (FILE *file, rtx x, int code)
       fprintf (file, "%d", i + 1);
       return;
 
+    case 'e':
+      /* If the low 16 bits are 0, but some other bit is set, write 's'.  */
+      if (! INT_P (x))
+       {
+         output_operand_lossage ("invalid %%e value");
+         return;
+       }
+
+      uval = INTVAL (x);
+      if ((uval & 0xffff) == 0 && uval != 0)
+       putc ('s', file);
+      return;
+
     case 'E':
       /* X is a CR register.  Print the number of the EQ bit of the CR */
       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
@@ -18298,12 +18311,19 @@ print_operand (FILE *file, rtx x, int code)
       return;
 
     case 'u':
-      /* High-order 16 bits of constant for use in unsigned operand.  */
+      /* High-order or low-order 16 bits of constant, whichever is non-zero,
+        for use in unsigned operand.  */
       if (! INT_P (x))
-       output_operand_lossage ("invalid %%u value");
-      else
-       fprintf (file, HOST_WIDE_INT_PRINT_HEX,
-                (INTVAL (x) >> 16) & 0xffff);
+       {
+         output_operand_lossage ("invalid %%u value");
+         return;
+       }
+
+      uval = INTVAL (x);
+      if ((uval & 0xffff) == 0)
+       uval >>= 16;
+
+      fprintf (file, HOST_WIDE_INT_PRINT_HEX, uval & 0xffff);
       return;
 
     case 'v':
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 7a99957..2e4df11 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3159,142 +3159,144 @@ (define_insn_and_split "*andsi3_internal6"
 }"
   [(set_attr "length" "8")])
 
-(define_expand "iorsi3"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-       (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
-               (match_operand:SI 2 "reg_or_logical_cint_operand" "")))]
+
+(define_expand "ior<mode>3"
+  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
+       (ior:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
+                (match_operand:SDI 2 "reg_or_cint_operand" "")))]
   ""
-  "
 {
-  if (GET_CODE (operands[2]) == CONST_INT
-      && ! logical_operand (operands[2], SImode))
+  if (<MODE>mode == DImode && !TARGET_POWERPC64)
+    {
+      rs6000_split_logical (operands, IOR, false, false, false, NULL_RTX);
+      DONE;
+    }
+
+  if (non_logical_cint_operand (operands[2], <MODE>mode))
     {
-      HOST_WIDE_INT value = INTVAL (operands[2]);
       rtx tmp = ((!can_create_pseudo_p ()
                  || rtx_equal_p (operands[0], operands[1]))
-                ? operands[0] : gen_reg_rtx (SImode));
+                ? operands[0] : gen_reg_rtx (<MODE>mode));
+      HOST_WIDE_INT value = INTVAL (operands[2]);
 
-      emit_insn (gen_iorsi3 (tmp, operands[1],
+      emit_insn (gen_ior<mode>3 (tmp, operands[1],
                             GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
-      emit_insn (gen_iorsi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
+
+      emit_insn (gen_ior<mode>3 (operands[0], tmp, GEN_INT (value & 0xffff)));
       DONE;
     }
-}")
 
-(define_expand "xorsi3"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-       (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
-               (match_operand:SI 2 "reg_or_logical_cint_operand" "")))]
+  if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
+    operands[2] = force_reg (<MODE>mode, operands[2]);
+})
+
+(define_expand "xor<mode>3"
+  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
+       (xor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
+                (match_operand:SDI 2 "reg_or_cint_operand" "")))]
   ""
-  "
 {
-  if (GET_CODE (operands[2]) == CONST_INT
-      && ! logical_operand (operands[2], SImode))
+  if (<MODE>mode == DImode && !TARGET_POWERPC64)
+    {
+      rs6000_split_logical (operands, XOR, false, false, false, NULL_RTX);
+      DONE;
+    }
+
+  if (non_logical_cint_operand (operands[2], <MODE>mode))
     {
-      HOST_WIDE_INT value = INTVAL (operands[2]);
       rtx tmp = ((!can_create_pseudo_p ()
                  || rtx_equal_p (operands[0], operands[1]))
-                ? operands[0] : gen_reg_rtx (SImode));
+                ? operands[0] : gen_reg_rtx (<MODE>mode));
+      HOST_WIDE_INT value = INTVAL (operands[2]);
 
-      emit_insn (gen_xorsi3 (tmp, operands[1],
+      emit_insn (gen_xor<mode>3 (tmp, operands[1],
                             GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
-      emit_insn (gen_xorsi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
+
+      emit_insn (gen_xor<mode>3 (operands[0], tmp, GEN_INT (value & 0xffff)));
       DONE;
     }
-}")
 
-(define_insn "*boolsi3_internal1"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
-       (match_operator:SI 3 "boolean_or_operator"
-        [(match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
-         (match_operand:SI 2 "logical_operand" "r,K,L")]))]
+  if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
+    operands[2] = force_reg (<MODE>mode, operands[2]);
+})
+
+(define_insn "*bool<mode>3"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
+       (match_operator:GPR 3 "boolean_or_operator"
+        [(match_operand:GPR 1 "gpc_reg_operand" "%r,r")
+         (match_operand:GPR 2 "logical_operand" "r,n")]))]
   ""
   "@
    %q3 %0,%1,%2
-   %q3i %0,%1,%b2
-   %q3is %0,%1,%u2")
+   %q3i%e2 %0,%1,%u2"
+  [(set_attr "type" "logical")])
 
-(define_insn "*boolsi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-       (compare:CC (match_operator:SI 4 "boolean_or_operator"
-        [(match_operand:SI 1 "gpc_reg_operand" "%r,r")
-         (match_operand:SI 2 "gpc_reg_operand" "r,r")])
+(define_insn_and_split "*bool<mode>3_dot"
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+       (compare:CC (match_operator:GPR 3 "boolean_or_operator"
+        [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
+         (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
         (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "TARGET_32BIT"
+   (clobber (match_scratch:GPR 0 "=r,r"))]
+  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
   "@
-   %q4. %3,%1,%2
+   %q3. %0,%1,%2
    #"
-  [(set_attr "type" "logical,compare")
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
+  [(set (match_dup 0)
+       (match_dup 3))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  ""
+  [(set_attr "type" "logical")
    (set_attr "dot" "yes")
    (set_attr "length" "4,8")])
 
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-       (compare:CC (match_operator:SI 4 "boolean_operator"
-        [(match_operand:SI 1 "gpc_reg_operand" "")
-         (match_operand:SI 2 "gpc_reg_operand" "")])
-        (const_int 0)))
-   (clobber (match_scratch:SI 3 ""))]
-  "TARGET_32BIT && reload_completed"
-  [(set (match_dup 3) (match_dup 4))
-   (set (match_dup 0)
-       (compare:CC (match_dup 3)
-                   (const_int 0)))]
-  "")
-
-(define_insn "*boolsi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-       (compare:CC (match_operator:SI 4 "boolean_operator"
-        [(match_operand:SI 1 "gpc_reg_operand" "%r,r")
-         (match_operand:SI 2 "gpc_reg_operand" "r,r")])
+(define_insn_and_split "*bool<mode>3_dot2"
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+       (compare:CC (match_operator:GPR 3 "boolean_or_operator"
+        [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
+         (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-       (match_dup 4))]
-  "TARGET_32BIT"
+   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
+       (match_dup 3))]
+  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
   "@
-   %q4. %0,%1,%2
+   %q3. %0,%1,%2
    #"
-  [(set_attr "type" "logical,compare")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-       (compare:CC (match_operator:SI 4 "boolean_operator"
-        [(match_operand:SI 1 "gpc_reg_operand" "")
-         (match_operand:SI 2 "gpc_reg_operand" "")])
-        (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-       (match_dup 4))]
-  "TARGET_32BIT && reload_completed"
-  [(set (match_dup 0) (match_dup 4))
-   (set (match_dup 3)
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
+  [(set (match_dup 0)
+       (match_dup 3))
+   (set (match_dup 4)
        (compare:CC (match_dup 0)
                    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "logical")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
 
 ;; Split a logical operation that we can't do in one insn into two insns,
 ;; each of which does one 16-bit part.  This is used by combine.
 
 (define_split
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-       (match_operator:SI 3 "boolean_or_operator"
-        [(match_operand:SI 1 "gpc_reg_operand" "")
-         (match_operand:SI 2 "non_logical_cint_operand" "")]))]
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
+       (match_operator:GPR 3 "boolean_or_operator"
+        [(match_operand:GPR 1 "gpc_reg_operand" "")
+         (match_operand:GPR 2 "non_logical_cint_operand" "")]))]
   ""
   [(set (match_dup 0) (match_dup 4))
    (set (match_dup 0) (match_dup 5))]
-"
 {
   rtx i;
   i = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
-  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
+  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
                                operands[1], i);
   i = GEN_INT (INTVAL (operands[2]) & 0xffff);
-  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
+  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
                                operands[0], i);
-}")
+})
+
 
 (define_insn "*boolcsi3_internal1"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -7838,158 +7840,6 @@ (define_split
   build_mask64_2_operands (operands[2], &operands[5]);
 }")
 
-(define_expand "iordi3"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-       (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
-               (match_operand:DI 2 "reg_or_cint_operand" "")))]
-  ""
-{
-  if (!TARGET_POWERPC64)
-    {
-      rs6000_split_logical (operands, IOR, false, false, false, NULL_RTX);
-      DONE;
-    }
-  else if (!reg_or_logical_cint_operand (operands[2], DImode))
-    operands[2] = force_reg (DImode, operands[2]);
-  else if (non_logical_cint_operand (operands[2], DImode))
-    {
-      HOST_WIDE_INT value;
-      rtx tmp = ((!can_create_pseudo_p ()
-                 || rtx_equal_p (operands[0], operands[1]))
-                ? operands[0] : gen_reg_rtx (DImode));
-
-      value = INTVAL (operands[2]);
-      emit_insn (gen_iordi3 (tmp, operands[1],
-                            GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
-
-      emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
-      DONE;
-    }
-})
-
-(define_expand "xordi3"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-       (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
-               (match_operand:DI 2 "reg_or_cint_operand" "")))]
-  ""
-{
-  if (!TARGET_POWERPC64)
-    {
-      rs6000_split_logical (operands, XOR, false, false, false, NULL_RTX);
-      DONE;
-    }
-  else if (!reg_or_logical_cint_operand (operands[2], DImode))
-    operands[2] = force_reg (DImode, operands[2]);
-  if (non_logical_cint_operand (operands[2], DImode))
-    {
-      HOST_WIDE_INT value;
-      rtx tmp = ((!can_create_pseudo_p ()
-                 || rtx_equal_p (operands[0], operands[1]))
-                ? operands[0] : gen_reg_rtx (DImode));
-
-      value = INTVAL (operands[2]);
-      emit_insn (gen_xordi3 (tmp, operands[1],
-                            GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
-
-      emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
-      DONE;
-    }
-})
-
-(define_insn "*booldi3_internal1"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
-       (match_operator:DI 3 "boolean_or_operator"
-        [(match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
-         (match_operand:DI 2 "logical_operand" "r,K,JF")]))]
-  "TARGET_POWERPC64"
-  "@
-   %q3 %0,%1,%2
-   %q3i %0,%1,%b2
-   %q3is %0,%1,%u2")
-
-(define_insn "*booldi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-       (compare:CC (match_operator:DI 4 "boolean_or_operator"
-        [(match_operand:DI 1 "gpc_reg_operand" "%r,r")
-         (match_operand:DI 2 "gpc_reg_operand" "r,r")])
-        (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
-  "TARGET_64BIT"
-  "@
-   %q4. %3,%1,%2
-   #"
-  [(set_attr "type" "logical,compare")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-       (compare:CC (match_operator:DI 4 "boolean_operator"
-        [(match_operand:DI 1 "gpc_reg_operand" "")
-         (match_operand:DI 2 "gpc_reg_operand" "")])
-        (const_int 0)))
-   (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 3) (match_dup 4))
-   (set (match_dup 0)
-       (compare:CC (match_dup 3)
-                   (const_int 0)))]
-  "")
-
-(define_insn "*booldi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-       (compare:CC (match_operator:DI 4 "boolean_or_operator"
-        [(match_operand:DI 1 "gpc_reg_operand" "%r,r")
-         (match_operand:DI 2 "gpc_reg_operand" "r,r")])
-        (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-       (match_dup 4))]
-  "TARGET_64BIT"
-  "@
-   %q4. %0,%1,%2
-   #"
-  [(set_attr "type" "logical,compare")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-       (compare:CC (match_operator:DI 4 "boolean_operator"
-        [(match_operand:DI 1 "gpc_reg_operand" "")
-         (match_operand:DI 2 "gpc_reg_operand" "")])
-        (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-       (match_dup 4))]
-  "TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 0) (match_dup 4))
-   (set (match_dup 3)
-       (compare:CC (match_dup 0)
-                   (const_int 0)))]
-  "")
-
-;; Split a logical operation that we can't do in one insn into two insns,
-;; each of which does one 16-bit part.  This is used by combine.
-
-(define_split
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-       (match_operator:DI 3 "boolean_or_operator"
-        [(match_operand:DI 1 "gpc_reg_operand" "")
-         (match_operand:DI 2 "non_logical_cint_operand" "")]))]
-  "TARGET_POWERPC64"
-  [(set (match_dup 0) (match_dup 4))
-   (set (match_dup 0) (match_dup 5))]
-"
-{
-  rtx i3,i4;
-
-  i3 = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
-  i4 = GEN_INT (INTVAL (operands[2]) & 0xffff);
-  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
-                               operands[1], i3);
-  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
-                               operands[0], i4);
-}")
-
 (define_insn "*boolcdi3_internal1"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
        (match_operator:DI 3 "boolean_operator"
-- 
1.8.1.4

Reply via email to