The condition/branch in decrement-and-branch peepholes is ne/brcc. This can be generalized to cover eq/brcs.
Tested without regressions. Because of PR52417, I had to run the tests with -fno-dse. There is one UNSUPPORTED because of that (missing dse dump). Ok for the trunk? Johann * config/avr/avr.md (eqne): New code iterator. (*dec-and-branchsi): Use it in text peephole's condition. (*dec-and-branchhi): Ditto. (*dec-and-branchqi): Ditto.
Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 184618) +++ config/avr/avr.md (working copy) @@ -232,6 +232,7 @@ (define_code_iterator any_extend [sign_ (define_code_iterator any_extend2 [sign_extend zero_extend]) (define_code_iterator xior [xor ior]) +(define_code_iterator eqne [eq ne]) ;; Define code attributes (define_code_attr extend_su @@ -4939,12 +4940,14 @@ (define_peephole ; "*dec-and-branchsi!=- (const_int -1))) (clobber (match_operand:QI 1 "d_register_operand" ""))]) (set (pc) - (if_then_else (ne (cc0) - (const_int 0)) + (if_then_else (eqne (cc0) + (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" { + const char *op; + int jump_mode; CC_STATUS_INIT; if (test_hard_reg_class (ADDW_REGS, operands[0])) output_asm_insn ("sbiw %0,1" CR_TAB @@ -4956,14 +4959,15 @@ (define_peephole ; "*dec-and-branchsi!=- "sbc %C0,__zero_reg__" CR_TAB "sbc %D0,__zero_reg__", operands); - switch (avr_jump_mode (operands[2], insn)) + jump_mode = avr_jump_mode (operands[2], insn); + op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; + operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); + + switch (jump_mode) { - case 1: - return "brcc %2"; - case 2: - return "brcs .+2\;rjmp %2"; - case 3: - return "brcs .+4\;jmp %2"; + case 1: return "%1 %2"; + case 2: return "%1 .+2\;rjmp %2"; + case 3: return "%1 .+4\;jmp %2"; } gcc_unreachable(); @@ -4980,11 +4984,14 @@ (define_peephole ; "*dec-and-branchhi!=- (const_int -1))) (clobber (match_operand:QI 1 "d_register_operand" ""))]) (set (pc) - (if_then_else (ne (cc0) (const_int 0)) + (if_then_else (eqne (cc0) + (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" { + const char *op; + int jump_mode; CC_STATUS_INIT; if (test_hard_reg_class (ADDW_REGS, operands[0])) output_asm_insn ("sbiw %0,1", operands); @@ -4992,14 +4999,15 @@ (define_peephole ; "*dec-and-branchhi!=- output_asm_insn ("subi %A0,1" CR_TAB "sbc %B0,__zero_reg__", operands); - switch (avr_jump_mode (operands[2], insn)) + jump_mode = avr_jump_mode (operands[2], insn); + op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; + operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); + + switch (jump_mode) { - case 1: - return "brcc %2"; - case 2: - return "brcs .+2\;rjmp %2"; - case 3: - return "brcs .+4\;jmp %2"; + case 1: return "%1 %2"; + case 2: return "%1 .+2\;rjmp %2"; + case 3: return "%1 .+4\;jmp %2"; } gcc_unreachable(); @@ -5017,12 +5025,14 @@ (define_peephole ; "*dec-and-branchhi!=- (const_int -1))) (clobber (match_operand:QI 1 "d_register_operand" ""))]) (set (pc) - (if_then_else (ne (cc0) - (const_int 0)) + (if_then_else (eqne (cc0) + (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" { + const char *op; + int jump_mode; CC_STATUS_INIT; if (test_hard_reg_class (ADDW_REGS, operands[0])) output_asm_insn ("sbiw %0,1", operands); @@ -5030,14 +5040,15 @@ (define_peephole ; "*dec-and-branchhi!=- output_asm_insn ("subi %A0,1" CR_TAB "sbc %B0,__zero_reg__", operands); - switch (avr_jump_mode (operands[2], insn)) + jump_mode = avr_jump_mode (operands[2], insn); + op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; + operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); + + switch (jump_mode) { - case 1: - return "brcc %2"; - case 2: - return "brcs .+2\;rjmp %2"; - case 3: - return "brcs .+4\;jmp %2"; + case 1: return "%1 %2"; + case 2: return "%1 .+2\;rjmp %2"; + case 3: return "%1 .+4\;jmp %2"; } gcc_unreachable(); @@ -5055,25 +5066,28 @@ (define_peephole ; "*dec-and-branchhi!=- (const_int -1))) (clobber (match_operand:QI 1 "d_register_operand" ""))]) (set (pc) - (if_then_else (ne (cc0) - (const_int 0)) + (if_then_else (eqne (cc0) + (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" { + const char *op; + int jump_mode; CC_STATUS_INIT; - output_asm_insn ("ldi %3,1" CR_TAB - "sub %A0,%3" CR_TAB - "sbc %B0,__zero_reg__", operands); + output_asm_insn ("ldi %3,1" CR_TAB + "sub %A0,%3" CR_TAB + "sbc %B0,__zero_reg__", operands); + + jump_mode = avr_jump_mode (operands[2], insn); + op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; + operands[1] = gen_rtx_CONST_STRING (VOIDmode, op); - switch (avr_jump_mode (operands[2], insn)) + switch (jump_mode) { - case 1: - return "brcc %2"; - case 2: - return "brcs .+2\;rjmp %2"; - case 3: - return "brcs .+4\;jmp %2"; + case 1: return "%1 %2"; + case 2: return "%1 .+2\;rjmp %2"; + case 3: return "%1 .+4\;jmp %2"; } gcc_unreachable(); @@ -5088,25 +5102,28 @@ (define_peephole ; "*dec-and-branchqi!=- (compare (match_dup 0) (const_int -1))) (set (pc) - (if_then_else (ne (cc0) (const_int 0)) + (if_then_else (eqne (cc0) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "" { + const char *op; + int jump_mode; CC_STATUS_INIT; cc_status.value1 = operands[0]; cc_status.flags |= CC_OVERFLOW_UNUSABLE; output_asm_insn ("subi %A0,1", operands); - switch (avr_jump_mode (operands[1], insn)) + jump_mode = avr_jump_mode (operands[1], insn); + op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs"; + operands[0] = gen_rtx_CONST_STRING (VOIDmode, op); + + switch (jump_mode) { - case 1: - return "brcc %1"; - case 2: - return "brcs .+2\;rjmp %1"; - case 3: - return "brcs .+4\;jmp %1"; + case 1: return "%0 %1"; + case 2: return "%0 .+2\;rjmp %1"; + case 3: return "%0 .+4\;jmp %1"; } gcc_unreachable();