This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch,AVR]: Tweak neghi2, add some peephole
- From: Georg-Johann Lay <avr at gjlay dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Eric Weddington <eric dot weddington at atmel dot com>, Denis Chertykov <chertykov at gmail dot com>
- Date: Thu, 16 Feb 2012 14:03:53 +0100
- Subject: [Patch,AVR]: Tweak neghi2, add some peephole
neghi2's "r,0" alternative reads
com %B0
neg %A0
sbc %B0,__zero_reg__
inc %B0
The INC commutates with the NEG+SBC and can be moved 2 instructions up:
com %B0
inc %B0
neg %A0
sbc %B0,__zero_reg__
COM+INC can be fused to NEG:
neg %B0
neg %A0
sbc %B0,__zero_reg__
with the additional benefit that cc0 is always set_czn now.
The *dec-and-branchhi!=-1 text peephole just coverd vanilla addhi3 without
clobber register. As addhi3 now has a clobber added in many cases,
that peephole don't match them any more. The patch adds peephole alternatives
for clobber variants of addhi3.
Passed without regressions.
Ok to apply?
Johann
* config/avr/avr.md (neghi2): Remove "!d,0" alternative. Tweak "r,0".
(*dec-and-branchhi!=-1.d.clobber): New text peephole.
(*dec-and-branchhi!=-1.l.clobber): New text peephole.
Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md (revision 184269)
+++ config/avr/avr.md (working copy)
@@ -3807,15 +3807,14 @@ (define_insn "*negqihi2"
(set_attr "cc" "set_n")])
(define_insn "neghi2"
- [(set (match_operand:HI 0 "register_operand" "=!d,r,&r")
- (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
+ [(set (match_operand:HI 0 "register_operand" "=r,&r")
+ (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
""
"@
- com %B0\;neg %A0\;sbci %B0,lo8(-1)
- com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
+ neg %B0\;neg %A0\;sbc %B0,__zero_reg__
clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
- [(set_attr "length" "3,4,4")
- (set_attr "cc" "set_czn,set_n,set_czn")])
+ [(set_attr "length" "3,4")
+ (set_attr "cc" "set_czn")])
(define_insn "negpsi2"
[(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
@@ -4919,7 +4918,7 @@ (define_insn "*sbix_branch_tmp_bit7"
;; ************************* Peepholes ********************************
-(define_peephole
+(define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
[(parallel [(set (match_operand:SI 0 "d_register_operand" "")
(plus:SI (match_dup 0)
(const_int -1)))
@@ -4960,7 +4959,7 @@ (define_peephole
return "";
})
-(define_peephole
+(define_peephole ; "*dec-and-branchhi!=-1"
[(set (match_operand:HI 0 "d_register_operand" "")
(plus:HI (match_dup 0)
(const_int -1)))
@@ -4996,7 +4995,81 @@ (define_peephole
return "";
})
-(define_peephole
+;; Same as above but with clobber flavour of addhi3
+(define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
+ [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
+ (plus:HI (match_dup 0)
+ (const_int -1)))
+ (clobber (scratch:QI))])
+ (parallel [(set (cc0)
+ (compare (match_dup 0)
+ (const_int -1)))
+ (clobber (match_operand:QI 1 "d_register_operand" ""))])
+ (set (pc)
+ (if_then_else (ne (cc0)
+ (const_int 0))
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ ""
+ {
+ CC_STATUS_INIT;
+ if (test_hard_reg_class (ADDW_REGS, operands[0]))
+ output_asm_insn ("sbiw %0,1", operands);
+ else
+ output_asm_insn ("subi %A0,1" CR_TAB
+ "sbc %B0,__zero_reg__", operands);
+
+ switch (avr_jump_mode (operands[2], insn))
+ {
+ case 1:
+ return "brcc %2";
+ case 2:
+ return "brcs .+2\;rjmp %2";
+ case 3:
+ return "brcs .+4\;jmp %2";
+ }
+
+ gcc_unreachable();
+ return "";
+ })
+
+;; Same as above but with clobber flavour of addhi3
+(define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
+ [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
+ (plus:HI (match_dup 0)
+ (const_int -1)))
+ (clobber (match_operand:QI 3 "d_register_operand" ""))])
+ (parallel [(set (cc0)
+ (compare (match_dup 0)
+ (const_int -1)))
+ (clobber (match_operand:QI 1 "d_register_operand" ""))])
+ (set (pc)
+ (if_then_else (ne (cc0)
+ (const_int 0))
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ ""
+ {
+ CC_STATUS_INIT;
+ output_asm_insn ("ldi %3,1" CR_TAB
+ "sub %A0,%3" CR_TAB
+ "sbc %B0,__zero_reg__", operands);
+
+ switch (avr_jump_mode (operands[2], insn))
+ {
+ case 1:
+ return "brcc %2";
+ case 2:
+ return "brcs .+2\;rjmp %2";
+ case 3:
+ return "brcs .+4\;jmp %2";
+ }
+
+ gcc_unreachable();
+ return "";
+ })
+
+(define_peephole ; "*dec-and-branchqi!=-1"
[(set (match_operand:QI 0 "d_register_operand" "")
(plus:QI (match_dup 0)
(const_int -1)))