]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
m68k: Accept ASHIFT like MULT in address operand
authorAndreas Schwab <schwab@linux-m68k.org>
Tue, 27 Aug 2024 19:01:00 +0000 (21:01 +0200)
committerAndreas Schwab <schwab@linux-m68k.org>
Tue, 27 Aug 2024 20:21:44 +0000 (22:21 +0200)
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

index 21c94981d220d2287f6c549cd2e78637baaab3d1..7986e92c5116a30e4fbef8b0c46c81d3d4e73ef2 100644 (file)
@@ -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);