"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