From: Georg-Johann Lay Date: Tue, 10 Sep 2024 15:51:58 +0000 (+0200) Subject: AVR: Tweak 32-bit EQ and NE comparisons. X-Git-Tag: basepoints/gcc-16~5931 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ec16778312a902592822cbda626241da68ea643;p=thirdparty%2Fgcc.git 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 f743261c6ad..25220c3bc0c 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -5990,6 +5990,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. */