This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 4/4, MIPS] Add *and<mode>3_ext pattern


This is the patch the actually adds the new pattern to generate ext when the
same operation with "and"  would require us to synthesize the constant first.

Between all these different "and" combine patterns
(*and<mode>3, *clear_upper32_dext, *and<mode>3_ext) I let the order in the .md
file decide the precedence and added to tests to validate this.  This is
obviously more efficient than enforcing mutual exclusivity on these patterns
but it's also more error-prone (hence the tests).

If we want to enforce exclusivity I can change the predicate to (untested):

;; Match the constant low-order bitmask operand in AND that can be implemented
;; with <d>ext.  Give preference to *and<mode>3 and *clear_upper32_dext by not
;; matching their operand.
(define_predicate "and_ext_low_bitmask_operand"
  (and (match_code "const_int")
       (match_test "low_bitmask_len (VOIDmode, INTVAL (op)) > 0")
       (match_test "INTVAL (op) != 0xffffffff")
       (not (match_operand 0 "const_uns_arith_operand"))))

Bootstrapped and regtested on mips64octeon-linux and regtested on
mipsisa64r2-elf.

OK to install?

Adam


	* config/mips/predicates.md (low_bitmask_operand): New predicate.
	* config/mips/mips.md (*and<mode>3_ext): New pattern.

testsuite/
	* gcc.target/mips/ext-4.c: Make sure the dext is generated by the
          clear_upper32 pattern.
	* gcc.target/mips/ext-5.c: New test.
	* gcc.target/mips/ext-6.c: New test.
	* gcc.target/mips/ext-7.c: New test.

Index: gcc/config/mips/predicates.md
===================================================================
--- gcc.orig/config/mips/predicates.md	2009-07-29 12:23:24.000000000 -0700
+++ gcc/config/mips/predicates.md	2009-07-29 12:24:37.000000000 -0700
@@ -76,6 +76,12 @@ (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 can be implemented
+;; with <d>ext.
+(define_predicate "low_bitmask_operand"
+  (and (match_code "const_int")
+       (match_test "low_bitmask_len (VOIDmode, INTVAL (op)) > 0")))
+
 (define_predicate "d_operand"
   (and (match_code "reg")
        (match_test "TARGET_MIPS16
Index: gcc/config/mips/mips.md
===================================================================
--- gcc.orig/config/mips/mips.md	2009-07-29 12:24:29.000000000 -0700
+++ gcc/config/mips/mips.md	2009-07-29 12:24:37.000000000 -0700
@@ -2627,6 +2627,19 @@ (define_insn "*clear_upper32_dext"
   [(set_attr "move_type" "arith,load")
    (set_attr "mode" "DI")])
 
+(define_insn "*and<mode>3_ext"
+  [(set (match_operand:GPR 0 "register_operand" "=d")
+	(and:GPR (match_operand:GPR 1 "register_operand" "%d")
+		 (match_operand:GPR 2 "low_bitmask_operand" "")))]
+  "ISA_HAS_EXT_INS"
+{
+  operands[2] = GEN_INT (low_bitmask_len (<MODE>mode, INTVAL (operands[2])));
+  return "<d>ext\t%0,%1,0,%2";
+}
+  [(set_attr "type" "arith")
+   (set_attr "mode" "<MODE>")])
+
+
 (define_expand "ior<mode>3"
   [(set (match_operand:GPR 0 "register_operand")
 	(ior:GPR (match_operand:GPR 1 "register_operand")
Index: gcc/testsuite/gcc.target/mips/ext-4.c
===================================================================
--- gcc.orig/testsuite/gcc.target/mips/ext-4.c	2009-07-29 12:23:24.000000000 -0700
+++ gcc/testsuite/gcc.target/mips/ext-4.c	2009-07-29 12:24:37.000000000 -0700
@@ -1,8 +1,10 @@
-/* For MIPS64r2 use DEXT rather than DSLL/DSRL for clear_upper32.  */
+/* For MIPS64r2 use DEXT rather than DSLL/DSRL for clear_upper32.  Make sure
+   the and_ext pattern does not shadow the clear_upper32 pattern. */
 /* { dg-do compile } */
-/* { dg-options "-O isa_rev>=2 -mgp64" } */
+/* { dg-options "-O isa_rev>=2 -mgp64 -dp" } */
 /* { dg-final { scan-assembler "\tdext\t" } } */
 /* { dg-final { scan-assembler-not "sll" } } */
+/* { dg-final { scan-assembler "clear_upper32" } } */
 
 unsigned long long
 f (unsigned long long i)
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-29 12:24:37.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-29 12:24:37.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-29 12:24:37.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;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]