This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 1/4, MIPS] Add r2 variant for *clear_upper32
- From: Adam Nemet <anemet at caviumnetworks dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 30 Jul 2009 12:25:09 -0700
- Subject: [PATCH 1/4, MIPS] Add r2 variant for *clear_upper32
- References: <19057.62127.907350.916479@ropi.home>
While trying to implement what I said here
http://gcc.gnu.org/ml/gcc-patches/2009-07/msg01112.html
I came to realize that it make sense to have a *clear_upper32 pattern for
dext. The reason is that this pattern provides a memory alternative unlike
the and patterns.
We also have proof that the memory alternative matches sometimes
(http://gcc.gnu.org/ml/gcc-patches/2007-09/msg01415.html). There is a
separate question of whether we should have memory alternative when anding
with 0xff or 0xffff. Unlike in the case of 0xfff_fffff, the middle-end is
free to turn these into (zero_extend:N (subreg:N reg:W)), so it should be less
important. (I tried and could not get them triggered).
In the new pattern I am using "o" for the memory operand's constraint. I am
also changing the same thing for the *zero_extensidi2_dext pattern; these
patterns are not applicable to mips16 and while the constraint amounts to m
for non-mips16, there is no need for the extra checks performed by "W" (unless
of course we want to keep the !ISA_HAS_EXT_INS and the ISA_HAS_EXT_INS
patterns similar).
With this patch we now have two instances of:
{
...
operands[1] = gen_lowpart (SImode, operands[1]);
return "lwu\t%0,%1";
}
in output templates. We could probably add a new print operand code for
gen_lowpart (SImode, ...) and rewrite this as a regular output template.
Bootstrapped and regtested on mips64octeon-linux and regtested on
mipsisa64r2-elf.
OK to install?
Adam
* config/mips/mips.md (*zero_extendsidi2_dext): Change the constraint
of the second alternative of the operand one from "W" to "o".
(*clear_upper32_dext): New pattern.
testsuite/
* gcc.target/mips/ext-4.c: New test.
Index: gcc/config/mips/mips.md
===================================================================
--- gcc.orig/config/mips/mips.md 2009-07-28 18:25:59.000000000 -0700
+++ gcc/config/mips/mips.md 2009-07-29 11:19:04.000000000 -0700
@@ -2770,7 +2770,7 @@ (define_insn_and_split "*zero_extendsidi
(define_insn "*zero_extendsidi2_dext"
[(set (match_operand:DI 0 "register_operand" "=d,d")
- (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))]
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,o")))]
"TARGET_64BIT && ISA_HAS_EXT_INS"
"@
dext\t%0,%1,0,32
@@ -2785,7 +2785,7 @@ (define_insn_and_split "*clear_upper32"
[(set (match_operand:DI 0 "register_operand" "=d,d")
(and:DI (match_operand:DI 1 "nonimmediate_operand" "d,W")
(const_int 4294967295)))]
- "TARGET_64BIT"
+ "TARGET_64BIT && !ISA_HAS_EXT_INS"
{
if (which_alternative == 0)
return "#";
@@ -2802,6 +2802,21 @@ (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,o")
+ (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-4.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.target/mips/ext-4.c 2009-07-29 11:05:48.000000000 -0700
@@ -0,0 +1,11 @@
+/* For MIPS64r2 use DEXT rather than DSLL/DSRL for clear_upper32. */
+/* { dg-do compile } */
+/* { dg-options "-O isa_rev>=2 -mgp64" } */
+/* { dg-final { scan-assembler "\tdext\t" } } */
+/* { dg-final { scan-assembler-not "sll" } } */
+
+unsigned long long
+f (unsigned long long i)
+{
+ return i & 0xffffffffull;
+}