The order in which multi-byte EQ and NE comparisons are performing the byte comparisons does not matter, and there are situations where using SBIW on the high word can save an instruction.
This is for trunk. Johann -- AVR: Tweak 32-bit EQ and NE comparisons. The order in which multi-byte EQ and NE comparisons are performing the byte comparisons does not matter, and there are situations where using SBIW on the high word can save an instruction. gcc/ * config/avr/avr.cc (avr_out_compare): Tweak 32-bit EQ and NE comparisons that can use SBIW for the hi16 part.
AVR: Tweak 32-bit EQ and NE comparisons. The order in which multi-byte EQ and NE comparisons are performing the byte comparisons does not matter, and there are situations where using SBIW on the high word can save an instruction. gcc/ * config/avr/avr.cc (avr_out_compare): Tweak 32-bit EQ and NE comparisons that can use SBIW for the hi16 part. diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 1f809d8e1e3..99657911171 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -5647,6 +5647,31 @@ avr_out_compare (rtx_insn *insn, rtx *xop, int *plen) } } + /* Comparisons == and != may change the order in which the sub-bytes are + being compared. Start with the high 16 bits so we can use SBIW. */ + + if (n_bytes == 4 + && compare_eq_p (insn) + && AVR_HAVE_ADIW + && REGNO (xreg) >= REG_22) + { + if (xval == const0_rtx) + return avr_asm_len ("sbiw %C0,0" CR_TAB + "cpc %B0,__zero_reg__" CR_TAB + "cpc %A0,__zero_reg__", xop, plen, 3); + + rtx xhi16 = simplify_gen_subreg (HImode, xval, mode, 2); + if (IN_RANGE (UINTVAL (xhi16) & GET_MODE_MASK (HImode), 0, 63) + && reg_unused_after (insn, xreg)) + { + xop[1] = xhi16; + avr_asm_len ("sbiw %C0,%1", xop, plen, 1); + xop[1] = xval; + return avr_asm_len ("sbci %B0,hi8(%1)" CR_TAB + "sbci %A0,lo8(%1)", xop, plen, 2); + } + } + for (int i = 0; i < n_bytes; i++) { /* We compare byte-wise. */