diff mbox series

[avr] Tweak 32-bit comparisons.

Message ID ebea68f4-3e27-4878-b302-5e69582f8186@gjlay.de
State New
Headers show
Series [avr] Tweak 32-bit comparisons. | expand

Commit Message

Georg-Johann Lay Sept. 10, 2024, 3:59 p.m. UTC
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.

Comments

Jeff Law Sept. 18, 2024, 3:22 p.m. UTC | #1
On 9/10/24 9:59 AM, Georg-Johann Lay wrote:
> 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.
OK
jeff
diff mbox series

Patch

    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.  */