On Mon, Jun 01, 2015 at 08:39:05AM -0500, Segher Boessenkool wrote:
> On Mon, Jun 01, 2015 at 11:33:18AM +0930, Alan Modra wrote:
> > Unifying andsi_mask with anddi_mask, and the fact that constraints for
> > const_int see VOIDmode rather than the operand mode is why we get
> > rldicr rather than rlwinm.  Easily fixed by separating the si/di
> > patterns, and with a little more work I may even be able to keep them
> > together.
> 
> Maybe just swapping T to be before S will do what you want, already?

Nope.

Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md     (revision 223878)
+++ gcc/config/rs6000/predicates.md     (working copy)
@@ -764,7 +764,11 @@
 
   if (TARGET_POWERPC64)
     {
-      /* Fail if the mask is not 32-bit.  */
+      /* Fail if the mask is not 32-bit.  Note: If constraints are
+        implemented using mask_operand then they will never fail this
+        test.  const_ints are VOIDmode, which is what is seen here
+        when called from a constraint.  When called as a predicate,
+        the match_operand mode is seen.  */
       if (mode == DImode && (c & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0)
        return 0;
 
The above, part of a patch I was writing to fix these problems, is why
putting T before S doesn't work.  eg. "T" matches 0xffffffff80000000,
which is good for SImode where you're really masking with 0x80000000,
but using rlwinm for the same constant in DImode would of course mask
off the top 32 bits.

> > In and<mode>3 expander I think you want the following since
> > and64_2_operand covers the extra double-rotate cases, not all DImode.
> > 
> > -  if ((<MODE>mode == DImode && !and64_2_operand (operands[2], <MODE>mode))
> > -      || (<MODE>mode != DImode && !and_operand (operands[2], <MODE>mode)))
> > +  if (!and_operand (operands[2], <MODE>mode)
> > +      && (<MODE>mode != DImode || !and64_2_operand (operands[2], 
> > <MODE>mode)))
> 
> and64_2_operand includes all of and_operand.  I agree it is a mess.

but and64_2_operand doesn't include all of and_operand!

> > In and<mode>3_imm_mask_dot and and<mode>3_imm_mask_dot2.  Typo?
> > -   && any_mask_operand (operands[2], <MODE>mode)"
> > +   && !any_mask_operand (operands[2], <MODE>mode)"
> 
> Thinko; that whole line should just be removed.  We prefer e.g. "rlwinm"
> over "andi.", but "andi." over "rlwinm.".  I'll do a patch.

OK, I have a patch too..

> > get rid of WORD_REGISTER_OPERATIONS,
> 
> rs6000 should not define it.  What e.g. does it mean for mullw?  Or,
> worse, mulhw?  Pretty much anything with "w" in its name is problematic.

In many places WORD_REGISTER_OPERATIONS is used, it is saying "don't
trust the high bits".  At the moment we definitely do need it defined!

> and gets rid of 2rld completely.

That's a good idea.  If we want it still, and I think we do, just
implement the two rldicl/r in the expander.

-- 
Alan Modra
Australia Development Lab, IBM

Reply via email to