PR target/53156
authorhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 29 Apr 2012 06:59:09 +0000 (06:59 +0000)
committerhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 29 Apr 2012 06:59:09 +0000 (06:59 +0000)
* config/cris/cris.md (andqu): New peephole2.
(andu): Tweak head comment.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186940 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/cris/cris.md

index 713c23f..5c0e973 100644 (file)
@@ -1,3 +1,9 @@
+2012-04-29  Hans-Peter Nilsson  <hp@axis.com>
+
+       PR target/53156
+       * config/cris/cris.md (andqu): New peephole2.
+       (andu): Tweak head comment.
+
 2012-04-28  Joern Rennecke  <joern.rennecke@embecosm.com>
            Steven Bosscher  <steven@gcc.gnu.org>
            Maxim Kuvyrkov  <maxim@codesourcery.com>
index febe6f5..92657d1 100644 (file)
   "operands[7]
      = rtx_equal_p (operands[3], operands[0]) ? operands[4] : operands[3];")
 
-;;  I cannot tell GCC (2.1, 2.7.2) how to correctly reload an instruction
-;; that looks like
-;;   and.b some_byte,const,reg_32
-;; where reg_32 is the destination of the "three-address" code optimally.
+;; There seems to be no other way to make GCC (including 4.8/trunk at
+;; r186932) optimally reload an instruction that looks like
+;;   and.d reg_or_mem,const_32__65535,other_reg
+;; where other_reg is the destination.
 ;; It should be:
-;;   movu.b some_byte,reg_32
-;;   and.b const,reg_32
+;;   movu.[bw] reg_or_mem,reg_32
+;;   and.[bw] trunc_int_for_mode([bw], const_32__65535),reg_32 ;; or andq
 ;; but it turns into:
-;;   move.b some_byte,reg_32
-;;   and.d const,reg_32
-;; Fix it here.
+;;   move.d reg_or_mem,reg_32
+;;   and.d const_32__65535,reg_32
+;; Fix it with these two peephole2's.
 ;; Testcases: gcc.dg/cris-peep2-andu1.c gcc.dg/cris-peep2-andu2.c
 
 (define_peephole2 ; andu (casesi+45)
                                                ? QImode : amode)));
 })
 
+;; Since r186861, gcc.dg/cris-peep2-andu2.c trigs this pattern, with which
+;; we fix up e.g.:
+;;  movu.b 254,$r9.
+;;  and.d $r10,$r9
+;; into:
+;;  movu.b $r10,$r9
+;;  andq -2,$r9.
+;; Only do this for values fitting the quick immediate operand.
+(define_peephole2 ; andqu (casesi+46)
+  [(set (match_operand:SI 0 "register_operand")
+       (match_operand:SI 1 "const_int_operand"))
+   (set (match_dup 0)
+       (and:SI (match_dup 0) (match_operand:SI 2 "nonimmediate_operand")))]
+   ;; Since the size of the memory access will be made different here,
+   ;; don't do this for a volatile access or a post-incremented address.
+  "satisfies_constraint_O (operands[1])
+   && !side_effects_p (operands[2])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])"
+  [(set (match_dup 0) (match_dup 3))
+   (set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))]
+{
+  enum machine_mode zmode = INTVAL (operands[2]) <= 255 ? QImode : HImode;
+  rtx op1
+    = (REG_S_P (operands[2])
+       ? gen_rtx_REG (zmode, REGNO (operands[2]))
+       : adjust_address (operands[2], zmode, 0));
+  operands[3] = gen_rtx_ZERO_EXTEND (SImode, op1);
+  operands[4] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]), QImode));
+})
+
 ;; Try and avoid GOTPLT reads escaping a call: transform them into
 ;; PLT.  Curiously (but thankfully), peepholes for instructions
 ;; *without side-effects* that just feed a call (or call_value) are