When LRA pulls an address operand out of a MEM it caninoicalizes a
containing MULT into ASHIFT.  Adjust the address decomposer to recognize
this form.

        PR target/116413
        * config/m68k/m68k.cc (m68k_decompose_index): Accept ASHIFT like
        MULT.
        (m68k_rtx_costs) [PLUS]: Likewise.
        (m68k_legitimize_address): Likewise.
---
 gcc/config/m68k/m68k.cc | 58 ++++++++++++++++++++++++++++-------------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/gcc/config/m68k/m68k.cc b/gcc/config/m68k/m68k.cc
index 21c94981d22..7986e92c511 100644
--- a/gcc/config/m68k/m68k.cc
+++ b/gcc/config/m68k/m68k.cc
@@ -1503,12 +1503,14 @@ m68k_legitimize_address (rtx x, rtx oldx, machine_mode 
mode)
 
 #define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = 1; }
 
-      if (GET_CODE (XEXP (x, 0)) == MULT)
+      if (GET_CODE (XEXP (x, 0)) == MULT
+         || GET_CODE (XEXP (x, 0)) == ASHIFT)
        {
          COPY_ONCE (x);
          XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
        }
-      if (GET_CODE (XEXP (x, 1)) == MULT)
+      if (GET_CODE (XEXP (x, 1)) == MULT
+         || GET_CODE (XEXP (x, 1)) == ASHIFT)
        {
          COPY_ONCE (x);
          XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
@@ -2069,16 +2071,29 @@ m68k_decompose_index (rtx x, bool strict_p, struct 
m68k_address *address)
 
   /* Check for a scale factor.  */
   scale = 1;
-  if ((TARGET_68020 || TARGET_COLDFIRE)
-      && GET_CODE (x) == MULT
-      && GET_CODE (XEXP (x, 1)) == CONST_INT
-      && (INTVAL (XEXP (x, 1)) == 2
-         || INTVAL (XEXP (x, 1)) == 4
-         || (INTVAL (XEXP (x, 1)) == 8
-             && (TARGET_COLDFIRE_FPU || !TARGET_COLDFIRE))))
+  if (TARGET_68020 || TARGET_COLDFIRE)
     {
-      scale = INTVAL (XEXP (x, 1));
-      x = XEXP (x, 0);
+      if (GET_CODE (x) == MULT
+         && GET_CODE (XEXP (x, 1)) == CONST_INT
+         && (INTVAL (XEXP (x, 1)) == 2
+             || INTVAL (XEXP (x, 1)) == 4
+             || (INTVAL (XEXP (x, 1)) == 8
+                 && (TARGET_COLDFIRE_FPU || !TARGET_COLDFIRE))))
+       {
+         scale = INTVAL (XEXP (x, 1));
+         x = XEXP (x, 0);
+       }
+      /* LRA uses ASHIFT instead of MULT outside of MEM.  */
+      else if (GET_CODE (x) == ASHIFT
+              && GET_CODE (XEXP (x, 1)) == CONST_INT
+              && (INTVAL (XEXP (x, 1)) == 1
+                  || INTVAL (XEXP (x, 1)) == 2
+                  || (INTVAL (XEXP (x, 1)) == 3
+                      && (TARGET_COLDFIRE_FPU || !TARGET_COLDFIRE))))
+       {
+         scale = 1 << INTVAL (XEXP (x, 1));
+         x = XEXP (x, 0);
+       }
     }
 
   /* Check for a word extension.  */
@@ -2246,8 +2261,10 @@ m68k_decompose_address (machine_mode mode, rtx x,
      ??? do_tablejump creates these addresses before placing the target
      label, so we have to assume that unplaced labels are jump table
      references.  It seems unlikely that we would ever generate indexed
-     accesses to unplaced labels in other cases.  */
+     accesses to unplaced labels in other cases.  Do not accept it in
+     PIC mode, since the label address will need to be loaded from memory.  */
   if (GET_CODE (x) == PLUS
+      && !flag_pic
       && m68k_jump_table_ref_p (XEXP (x, 1))
       && m68k_decompose_index (XEXP (x, 0), strict_p, address))
     {
@@ -3068,12 +3085,17 @@ m68k_rtx_costs (rtx x, machine_mode mode, int 
outer_code,
       /* An lea costs about three times as much as a simple add.  */
       if (mode == SImode
          && GET_CODE (XEXP (x, 1)) == REG
-         && GET_CODE (XEXP (x, 0)) == MULT
-         && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
-         && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-         && (INTVAL (XEXP (XEXP (x, 0), 1)) == 2
-             || INTVAL (XEXP (XEXP (x, 0), 1)) == 4
-             || INTVAL (XEXP (XEXP (x, 0), 1)) == 8))
+         && ((GET_CODE (XEXP (x, 0)) == MULT
+              && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+              && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+              && (INTVAL (XEXP (XEXP (x, 0), 1)) == 2
+                  || INTVAL (XEXP (XEXP (x, 0), 1)) == 4
+                  || INTVAL (XEXP (XEXP (x, 0), 1)) == 8))
+             || (GET_CODE (XEXP (x, 0)) == ASHIFT
+                 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+                 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+                 && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 0), 1))
+                     <= 3))))
        {
            /* lea an@(dx:l:i),am */
            *total = COSTS_N_INSNS (TARGET_COLDFIRE ? 2 : 3);
-- 
2.46.0


-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

Reply via email to