[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