[PATCH 3/4, MIPS] Move clear_upper32* patterns to the and patterns

Adam Nemet anemet@caviumnetworks.com
Sat Aug 1 00:23:00 GMT 2009


Richard Henderson writes:
> How about merging all the patterns?  E.g.

I tried working out the details, this is where it stands.  It passes
ext-[4567].c tests from the MIPS testsuite but I haven't done any further
testing.

I still need to think about if we want the operands to be commutative.  Also
why did you use !register_operand rather than memory_operand in and_ext_ok?
(I didn't use B for the constraints because that is a valid prefix.)

Adam


Index: gcc/config/mips/predicates.md
===================================================================
--- gcc.orig/config/mips/predicates.md	2009-07-31 16:56:46.000000000 -0700
+++ gcc/config/mips/predicates.md	2009-07-31 17:14:41.000000000 -0700
@@ -76,6 +76,16 @@ (define_predicate "const_0_or_1_operand"
        (ior (match_test "op == CONST0_RTX (GET_MODE (op))")
 	    (match_test "op == CONST1_RTX (GET_MODE (op))"))))
 
+;; Match the constant low-order bitmask operand in AND that should be
+;; implemented with <d>ext.
+(define_predicate "low_bitmask_operand"
+  (and (match_code "const_int")
+       (match_test "low_bitmask_len (mode, INTVAL (op)) > 16")))
+
+(define_predicate "and_ext_operand"
+  (ior (match_operand 0 "uns_arith_operand")
+       (match_operand 0 "low_bitmask_operand")))
+
 (define_predicate "d_operand"
   (and (match_code "reg")
        (match_test "TARGET_MIPS16
Index: gcc/config/mips/constraints.md
===================================================================
--- gcc.orig/config/mips/constraints.md	2009-07-31 16:56:46.000000000 -0700
+++ gcc/config/mips/constraints.md	2009-07-31 17:05:27.000000000 -0700
@@ -215,3 +215,27 @@ (define_constraint "YB"
    A signed 10-bit constant."
   (and (match_code "const_int")
        (match_test "IMM10_OPERAND (ival)")))
+
+(define_constraint "Yb"
+   "@internal
+    The constant @code{0xff}"
+    (and (match_code "const_int")
+	 (match_test "UINTVAL (op) == 0xff")))
+
+(define_constraint "Yh"
+   "@internal
+    The constant @code{0xffff}"
+    (and (match_code "const_int")
+	 (match_test "UINTVAL (op) == 0xffff")))
+
+(define_constraint "Yw"
+   "@internal
+    The constant @code{0xffffffff}"
+    (and (match_code "const_int")
+	 (match_test "UINTVAL (op) == 0xffff")))
+
+(define_constraint "Yx"
+   "@internal
+    A low-order bitmask constant"
+    (and (match_code "const_int")
+	 (match_operand 0 "low_bitmask_operand")))
Index: gcc/config/mips/mips-protos.h
===================================================================
--- gcc.orig/config/mips/mips-protos.h	2009-07-31 16:56:46.000000000 -0700
+++ gcc/config/mips/mips-protos.h	2009-07-31 17:05:27.000000000 -0700
@@ -316,6 +316,7 @@ extern bool mips16e_save_restore_pattern
 
 extern bool mask_low_and_shift_p (enum machine_mode, rtx, rtx, int);
 extern int mask_low_and_shift_len (enum machine_mode, rtx, rtx);
+extern bool and_ext_ok (enum machine_mode, rtx, rtx);
 
 union mips_gen_fn_ptrs
 {
Index: gcc/config/mips/mips.c
===================================================================
--- gcc.orig/config/mips/mips.c	2009-07-31 16:56:46.000000000 -0700
+++ gcc/config/mips/mips.c	2009-07-31 17:05:27.000000000 -0700
@@ -6781,6 +6781,32 @@ mask_low_and_shift_p (enum machine_mode 
   return IN_RANGE (mask_low_and_shift_len (mode, mask, shift), 1, maxlen);
 }
 
+/* Return true iff OP1 and OP2 are valid operands together for the
+   *and<MODE>3_ext pattern.  */
+
+bool
+and_ext_ok (enum machine_mode mode, rtx op1, rtx op2)
+{
+  if (TARGET_MIPS16 || !ISA_HAS_EXT_INS)
+    return false;
+
+  /* op2 values accepted in combination with a memory operand is a superset of
+     those accepted with a register operand.  At this point op2 is valid with
+     a register operand.  */
+  if (memory_operand (op1, mode))
+    {
+      unsigned HOST_WIDE_INT i;
+
+      if (!CONST_INT_P (op2))
+	return false;
+
+      i = UINTVAL (op1);
+      return i == 0xff || i == 0xffff || i == 0xffffffff;
+    }
+
+  return true;
+}
+
 /* The canonical form of a mask-low-and-shift-left operation is
    (and (ashift X SHIFT) MASK) where MASK has the lower SHIFT number of bits
    cleared.  Thus we need to shift MASK to the right before checking if it
Index: gcc/config/mips/mips.md
===================================================================
--- gcc.orig/config/mips/mips.md	2009-07-31 16:59:48.000000000 -0700
+++ gcc/config/mips/mips.md	2009-07-31 17:05:27.000000000 -0700
@@ -2572,13 +2572,47 @@ (define_insn "*and<mode>3"
   [(set (match_operand:GPR 0 "register_operand" "=d,d")
 	(and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
 		 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
-  "!TARGET_MIPS16"
+  "!TARGET_MIPS16 && !ISA_HAS_EXT_INS"
   "@
    and\t%0,%1,%2
    andi\t%0,%1,%x2"
   [(set_attr "type" "logical")
    (set_attr "mode" "<MODE>")])
 
+(define_insn "*and<mode>3_ext"
+  [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d")
+	(and:GPR (match_operand:GPR 1 "nonimmediate_operand" "W,W,W,d,d,d")
+		 (match_operand:GPR 2 "and_ext_operand" "Yb,Yh,Yw,K,Yx,d")))]
+  "and_ext_ok (<MODE>mode, operands[1], operands[2])"
+{
+  int len;
+
+  switch (which_alternative)
+    {
+    case 0:
+      operands[1] = gen_lowpart (QImode, operands[1]);
+      return "lbu\t%0,%1";
+    case 1:
+      operands[1] = gen_lowpart (HImode, operands[1]);
+      return "lhu\t%0,%1";
+    case 2:
+      operands[1] = gen_lowpart (SImode, operands[1]);
+      return "lwu\t%0,%1";
+    case 3:
+      return "andi\t%0,%1,%x2";
+    case 4:
+      len = low_bitmask_len (<MODE>mode, INTVAL (operands[2]));
+      operands[2] = GEN_INT (len);
+      return "<d>ext\t%0,%1,0,%2";
+    case 5:
+      return "and\t%0,%1,%2";
+    default:
+      gcc_unreachable ();
+    }
+}
+  [(set_attr "type" "load,load,load,logical,arith,logical")
+   (set_attr "mode" "<MODE>")])
+
 (define_insn "*and<mode>3_mips16"
   [(set (match_operand:GPR 0 "register_operand" "=d")
 	(and:GPR (match_operand:GPR 1 "register_operand" "%0")
@@ -2778,8 +2812,9 @@ (define_insn "*zero_extendsidi2_dext"
   [(set_attr "move_type" "arith,load")
    (set_attr "mode" "DI")])
 
-;; Combine is not allowed to convert this insn into a zero_extendsidi2
-;; because of TRULY_NOOP_TRUNCATION.
+;; Combine is not allowed to convert this insn into a zero_extendsidi2 because
+;; of TRULY_NOOP_TRUNCATION.  For ISA_HAS_EXT_INS see the *and<mode>_ext
+;; pattern.
 
 (define_insn_and_split "*clear_upper32"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
@@ -2802,21 +2837,6 @@ (define_insn_and_split "*clear_upper32"
   [(set_attr "move_type" "shift_shift,load")
    (set_attr "mode" "DI")])
 
-(define_insn "*clear_upper32_dext"
-  [(set (match_operand:DI 0 "register_operand" "=d,d")
-        (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,W")
-		(const_int 4294967295)))]
-  "TARGET_64BIT && ISA_HAS_EXT_INS"
-{
-  if (which_alternative == 0)
-    return "dext\t%0,%1,0,32";
-
-  operands[1] = gen_lowpart (SImode, operands[1]);
-  return "lwu\t%0,%1";
-}
-  [(set_attr "move_type" "arith,load")
-   (set_attr "mode" "DI")])
-
 (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
   [(set (match_operand:GPR 0 "register_operand")
         (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))]
Index: gcc/testsuite/gcc.target/mips/ext-5.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.target/mips/ext-5.c	2009-07-31 17:05:27.000000000 -0700
@@ -0,0 +1,11 @@
+/* For MIPS32r2 use EXT when ANDing with low-order bitmasks.  */
+/* { dg-do compile } */
+/* { dg-options "-O isa_rev>=2" } */
+/* { dg-final { scan-assembler "\text\t" } } */
+/* { dg-final { scan-assembler-not "\tandi?\t" } } */
+
+unsigned
+f (unsigned i)
+{
+  return i & 0x7ffffff;
+}
Index: gcc/testsuite/gcc.target/mips/ext-6.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.target/mips/ext-6.c	2009-07-31 17:05:27.000000000 -0700
@@ -0,0 +1,11 @@
+/* For MIPS64r2 use DEXT when ANDing with low-order bitmasks.  */
+/* { dg-do compile } */
+/* { dg-options "-O isa_rev>=2 -mgp64" } */
+/* { dg-final { scan-assembler "\tdext\t" } } */
+/* { dg-final { scan-assembler-not "\tandi?\t" } } */
+
+unsigned long long
+f (unsigned long long i)
+{
+  return i & 0x7ffffffffff;
+}
Index: gcc/testsuite/gcc.target/mips/ext-7.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.target/mips/ext-7.c	2009-07-31 17:05:27.000000000 -0700
@@ -0,0 +1,11 @@
+/* No need to use ext if we can use andi.  */
+/* { dg-do compile } */
+/* { dg-options "-O isa_rev>=2" } */
+/* { dg-final { scan-assembler "\tandi\t" } } */
+/* { dg-final { scan-assembler-not "\td?ext\t" } } */
+
+unsigned
+f (unsigned i)
+{
+  return i & 0x7fff;
+}




More information about the Gcc-patches mailing list