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)))