diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2024-09-15 20:37:48 +0200 |
---|---|---|
committer | Georg-Johann Lay <avr@gjlay.de> | 2024-09-16 09:20:55 +0200 |
commit | 9f8e18213cbcfbadce56f7f531bd61fe4c7eab11 (patch) | |
tree | 5e4781b115e6aa29ea0f2a6bd5d000258146c5a1 | |
parent | 719edcba4d177918b189f27c272f80cd6da7cbc9 (diff) | |
download | gcc-9f8e18213cbcfbadce56f7f531bd61fe4c7eab11.zip gcc-9f8e18213cbcfbadce56f7f531bd61fe4c7eab11.tar.gz gcc-9f8e18213cbcfbadce56f7f531bd61fe4c7eab11.tar.bz2 |
AVR: Partially revert r15-3623.
ADIW doesn't mix with CPC / SBIC because it's not only about
propagating the Z flag but also about carry.
gcc/
* config/avr/avr.cc (avr_out_compare): Don't mix ADIW with SBCI / CPC.
-rw-r--r-- | gcc/config/avr/avr.cc | 32 |
1 files changed, 10 insertions, 22 deletions
diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 4cb51ea..5597f3e 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -6026,25 +6026,15 @@ avr_out_compare (rtx_insn *insn, rtx *xop, int *plen) if (n_bytes == 4 && eqne_p && AVR_HAVE_ADIW - && REGNO (xreg) >= REG_22) + && REGNO (xreg) >= REG_22 + && (xval == const0_rtx + || (IN_RANGE (avr_int16 (xval, 2), 0, 63) + && reg_unused_after (insn, xreg)))) { - 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); - - int16_t hi16 = avr_int16 (xval, 2); - if (reg_unused_after (insn, xreg) - && (IN_RANGE (hi16, 0, 63) - || (eqne_p - && IN_RANGE (hi16, -63, -1)))) - { - rtx op[] = { xop[0], avr_word (xval, 2) }; - avr_asm_len (hi16 < 0 ? "adiw %C0,%n1" : "sbiw %C0,%1", - op, plen, 1); - return avr_asm_len ("sbci %B0,hi8(%1)" CR_TAB - "sbci %A0,lo8(%1)", xop, plen, 2); - } + xop[2] = avr_word (xval, 2); + return avr_asm_len ("sbiw %C0,%2" CR_TAB + "sbci %B0,hi8(%1)" CR_TAB + "sbci %A0,lo8(%1)", xop, plen, 3); } bool changed[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -6078,12 +6068,10 @@ avr_out_compare (rtx_insn *insn, rtx *xop, int *plen) if (IN_RANGE (val16, -63, -1) && eqne_p + && n_bytes == 2 && reg_unused_after (insn, xreg)) { - avr_asm_len ("adiw %0,%n1", xop, plen, 1); - changed[0] = changed[1] = true; - i++; - continue; + return avr_asm_len ("adiw %0,%n1", xop, plen, 1); } } |