Message ID | 4E807D9B.8020303@gjlay.de |
---|---|
State | New |
Headers | show |
2011/9/26 Georg-Johann Lay <avr@gjlay.de>: > This is a minor tweak to do eq/ne comparisons one instruction shorter in the > case where the compare target is unused after the comparison: > > For 1: > DEC R0 > OR R0,R1 > OR R0,R2 > OR R0,R3 > > For -1: > AND R0,R3 > AND R0,R2 > AND R0,R1 > COM R0 > > The text peephole casesi+2 used 0xffff where -1 is the right canonical > representation, e.g. the following source > > char c; > > unsigned int cmp_p (unsigned int x) > { > if (--x == 65535) > c = 0; > return x; > } > > compiles with -S -Os -dP -fno-peephole to > > ; (insn 7 6 8 (parallel [ > ; (set (cc0) > ; (compare (reg/v:HI 24 r24 [orig:42 x ] [42]) > ; (const_int -1 [0xffffffff]))) > ; (clobber (reg:QI 18 r18)) > ; ]) cmp.c:6 184 {*cmphi} > ; (expr_list:REG_UNUSED (reg:QI 18 r18) > ; (nil))) > > > Fixed that, too. Test suite passes fine. > > Ok? > > Johann > > * config/avr/avr.md (peephole casesi+2): Use -1 > instead of 65535. > * config/avr/avr.c (avr_out_compare): Print shorter sequence for > EQ/NE comparisons against +/-1 in the case of unused-after, > non-ld-regs target. > Please commit. Denis.
Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 179191) +++ config/avr/avr.md (working copy) @@ -4119,7 +4119,7 @@ (define_peephole (parallel [(set (cc0) (compare (match_dup 0) - (const_int 65535))) + (const_int -1))) (clobber (match_operand:QI 1 "d_register_operand" ""))]) (set (pc) (if_then_else (ne (cc0) (const_int 0)) Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 179191) +++ config/avr/avr.c (working copy) @@ -3048,6 +3048,37 @@ avr_out_compare (rtx insn, rtx *xop, int if (plen) *plen = 0; + /* Comparisons == +/-1 and != +/-1 can be done similar to camparing + against 0 by ORing the bytes. This is one instruction shorter. */ + + if (!test_hard_reg_class (LD_REGS, xreg) + && compare_eq_p (insn) + && reg_unused_after (insn, xreg)) + { + if (xval == const1_rtx) + { + avr_asm_len ("dec %A0" CR_TAB + "or %A0,%B0", xop, plen, 2); + + if (n_bytes == 4) + avr_asm_len ("or %A0,%C0" CR_TAB + "or %A0,%D0", xop, plen, 2); + + return ""; + } + else if (xval == constm1_rtx) + { + if (n_bytes == 4) + avr_asm_len ("and %A0,%D0" CR_TAB + "and %A0,%C0", xop, plen, 2); + + avr_asm_len ("and %A0,%B0" CR_TAB + "com %A0", xop, plen, 2); + + return ""; + } + } + for (i = 0; i < n_bytes; i++) { /* We compare byte-wise. */