aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2024-09-15 20:37:48 +0200
committerGeorg-Johann Lay <avr@gjlay.de>2024-09-16 09:20:55 +0200
commit9f8e18213cbcfbadce56f7f531bd61fe4c7eab11 (patch)
tree5e4781b115e6aa29ea0f2a6bd5d000258146c5a1
parent719edcba4d177918b189f27c272f80cd6da7cbc9 (diff)
downloadgcc-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.cc32
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);
}
}