pa.c (mem_shadd_or_shadd_rtx_p): New function factored out of hppa_legitimize_address...
authorJeff Law <law@redhat.com>
Fri, 22 May 2015 16:13:07 +0000 (10:13 -0600)
committerJeff Law <law@gcc.gnu.org>
Fri, 22 May 2015 16:13:07 +0000 (10:13 -0600)
* pa.c (mem_shadd_or_shadd_rtx_p): New function factored out
of hppa_legitimize_address to handle both forms of a multiply
by 2, 4 or 8.
(hppa_legitimize_address): Use mem_shadd_or_shadd_rtx_p.
Always generate the ASHIFT variant as the result is not directly
used in a MEM.  Update comments and refactor slightly to improve
readability.

From-SVN: r223579

gcc/ChangeLog
gcc/config/pa/pa.c

index 593877fe3a13402a66cd76eda0fc2efbb66ec2e0..e2d49e67f1349ba80d3b7ee4cdc30e0f67ed827c 100644 (file)
@@ -1,3 +1,13 @@
+2015-05-22  Jeff Law  <law@redhat.com>
+
+       * pa.c (mem_shadd_or_shadd_rtx_p): New function factored out
+       of hppa_legitimize_address to handle both forms of a multiply
+       by 2, 4 or 8.
+       (hppa_legitimize_address): Use mem_shadd_or_shadd_rtx_p. 
+       Always generate the ASHIFT variant as the result is not directly
+       used in a MEM.  Update comments and refactor slightly to improve
+       readability.
+
 2015-05-22  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR target/65491
index f99cf335f4998d038ed11f50c915d9bcff4ba031..090eeb4a80816159276b161939b4db0bd275939e 100644 (file)
@@ -997,6 +997,23 @@ legitimize_tls_address (rtx addr)
   return ret;
 }
 
+/* Helper for hppa_legitimize_address.  Given X, return true if it
+   is a left shift by 1, 2 or 3 positions or a multiply by 2, 4 or 8.
+
+   This respectively represent canonical shift-add rtxs or scaled
+   memory addresses.  */
+static bool
+mem_shadd_or_shadd_rtx_p (rtx x)
+{
+  return ((GET_CODE (x) == ASHIFT
+          || GET_CODE (x) == MULT)
+         && GET_CODE (XEXP (x, 1)) == CONST_INT
+         && ((GET_CODE (x) == ASHIFT
+              && pa_shadd_constant_p (INTVAL (XEXP (x, 1))))
+             || (GET_CODE (x) == MULT
+                 && pa_mem_shadd_constant_p (INTVAL (XEXP (x, 1))))));
+}
+
 /* Try machine-dependent ways of modifying an illegitimate address
    to be legitimate.  If we find one, return the new, valid address.
    This macro is used in only one place: `memory_address' in explow.c.
@@ -1042,6 +1059,13 @@ legitimize_tls_address (rtx addr)
    manner if Y is 2, 4, or 8.  (allows more shadd insns and shifted indexed
    addressing modes to be used).
 
+   Note that the addresses passed into hppa_legitimize_address always
+   come from a MEM, so we only have to match the MULT form on incoming
+   addresses.  But to be future proof we also match the ASHIFT form.
+
+   However, this routine always places those shift-add sequences into
+   registers, so we have to generate the ASHIFT form as our output.
+
    Put X and Z into registers.  Then put the entire expression into
    a register.  */
 
@@ -1138,18 +1162,21 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       return plus_constant (Pmode, ptr_reg, offset - newoffset);
     }
 
-  /* Handle (plus (mult (a) (shadd_constant)) (b)).  */
+  /* Handle (plus (mult (a) (mem_shadd_constant)) (b)).  */
 
-  if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
-      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-      && pa_shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))
+  if (GET_CODE (x) == PLUS
+      && mem_shadd_or_shadd_rtx_p (XEXP (x, 0))
       && (OBJECT_P (XEXP (x, 1))
          || GET_CODE (XEXP (x, 1)) == SUBREG)
       && GET_CODE (XEXP (x, 1)) != CONST)
     {
-      int val = INTVAL (XEXP (XEXP (x, 0), 1));
-      rtx reg1, reg2;
+      /* If we were given a MULT, we must fix the constant
+        as we're going to create the ASHIFT form.  */
+      int shift_val = INTVAL (XEXP (XEXP (x, 0), 1));
+      if (GET_CODE (XEXP (x, 0)) == MULT)
+       shift_val = exact_log2 (shift_val);
 
+      rtx reg1, reg2;
       reg1 = XEXP (x, 1);
       if (GET_CODE (reg1) != REG)
        reg1 = force_reg (Pmode, force_operand (reg1, 0));
@@ -1158,26 +1185,30 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       if (GET_CODE (reg2) != REG)
         reg2 = force_reg (Pmode, force_operand (reg2, 0));
 
-      return force_reg (Pmode, gen_rtx_PLUS (Pmode,
-                                            gen_rtx_MULT (Pmode,
-                                                          reg2,
-                                                          GEN_INT (val)),
-                                            reg1));
+      return force_reg (Pmode,
+                       gen_rtx_PLUS (Pmode,
+                                     gen_rtx_ASHIFT (Pmode, reg2,
+                                                     GEN_INT (shift_val)),
+                                     reg1));
     }
 
-  /* Similarly for (plus (plus (mult (a) (shadd_constant)) (b)) (c)).
+  /* Similarly for (plus (plus (mult (a) (mem_shadd_constant)) (b)) (c)).
 
      Only do so for floating point modes since this is more speculative
      and we lose if it's an integer store.  */
   if (GET_CODE (x) == PLUS
       && GET_CODE (XEXP (x, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
-      && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
-      && pa_shadd_constant_p (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)))
+      && mem_shadd_or_shadd_rtx_p (XEXP (XEXP (x, 0), 0))
       && (mode == SFmode || mode == DFmode))
     {
+      int shift_val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
+
+      /* If we were given a MULT, we must fix the constant
+        as we're going to create the ASHIFT form.  */
+      if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
+       shift_val = exact_log2 (shift_val);
 
-      /* First, try and figure out what to use as a base register.  */
+      /* Try and figure out what to use as a base register.  */
       rtx reg1, reg2, base, idx;
 
       reg1 = XEXP (XEXP (x, 0), 1);
@@ -1201,9 +1232,9 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
        {
          base = reg1;
          idx = gen_rtx_PLUS (Pmode,
-                             gen_rtx_MULT (Pmode,
-                                           XEXP (XEXP (XEXP (x, 0), 0), 0),
-                                           XEXP (XEXP (XEXP (x, 0), 0), 1)),
+                             gen_rtx_ASHIFT (Pmode,
+                                             XEXP (XEXP (XEXP (x, 0), 0), 0),
+                                             GEN_INT (shift_val)),
                              XEXP (x, 1));
        }
       else if (GET_CODE (reg2) == REG
@@ -1225,8 +1256,8 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
        {
          /* Divide the CONST_INT by the scale factor, then add it to A.  */
          int val = INTVAL (XEXP (idx, 1));
+         val /= (1 << shift_val);
 
-         val /= INTVAL (XEXP (XEXP (idx, 0), 1));
          reg1 = XEXP (XEXP (idx, 0), 0);
          if (GET_CODE (reg1) != REG)
            reg1 = force_reg (Pmode, force_operand (reg1, 0));
@@ -1237,8 +1268,8 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
          return
            force_reg
              (Pmode, gen_rtx_PLUS (Pmode,
-                                   gen_rtx_MULT (Pmode, reg1,
-                                                 XEXP (XEXP (idx, 0), 1)),
+                                   gen_rtx_ASHIFT (Pmode, reg1,
+                                                   GEN_INT (shift_val)),
                                    base));
        }
 
@@ -1247,7 +1278,6 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
          && INTVAL (XEXP (idx, 1)) <= 4096
          && INTVAL (XEXP (idx, 1)) >= -4096)
        {
-         int val = INTVAL (XEXP (XEXP (idx, 0), 1));
          rtx reg1, reg2;
 
          reg1 = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, XEXP (idx, 1)));
@@ -1256,11 +1286,11 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
          if (GET_CODE (reg2) != CONST_INT)
            reg2 = force_reg (Pmode, force_operand (reg2, 0));
 
-         return force_reg (Pmode, gen_rtx_PLUS (Pmode,
-                                                gen_rtx_MULT (Pmode,
-                                                              reg2,
-                                                              GEN_INT (val)),
-                                                reg1));
+         return force_reg (Pmode,
+                           gen_rtx_PLUS (Pmode,
+                                         gen_rtx_ASHIFT (Pmode, reg2,
+                                                         GEN_INT (shift_val)),
+                                         reg1));
        }
 
       /* Get the index into a register, then add the base + index and
@@ -1278,8 +1308,8 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
 
       reg1 = force_reg (Pmode,
                        gen_rtx_PLUS (Pmode,
-                                     gen_rtx_MULT (Pmode, reg1,
-                                                   XEXP (XEXP (idx, 0), 1)),
+                                     gen_rtx_ASHIFT (Pmode, reg1,
+                                                     GEN_INT (shift_val)),
                                      reg2));
 
       /* Add the result to our base register and return.  */
@@ -1315,7 +1345,7 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)
        {
          /* See if this looks like
-               (plus (mult (reg) (shadd_const))
+               (plus (mult (reg) (mem_shadd_const))
                      (const (plus (symbol_ref) (const_int))))
 
             Where const_int is small.  In that case the const
@@ -1324,14 +1354,18 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
             If const_int is big, but can be divided evenly by shadd_const
             and added to (reg).  This allows more scaled indexed addresses.  */
          if (GET_CODE (XEXP (y, 0)) == SYMBOL_REF
-             && GET_CODE (XEXP (x, 0)) == MULT
+             && mem_shadd_or_shadd_rtx_p (XEXP (x, 0))
              && GET_CODE (XEXP (y, 1)) == CONST_INT
              && INTVAL (XEXP (y, 1)) >= -4096
-             && INTVAL (XEXP (y, 1)) <= 4095
-             && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-             && pa_shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
+             && INTVAL (XEXP (y, 1)) <= 4095)
            {
-             int val = INTVAL (XEXP (XEXP (x, 0), 1));
+             int shift_val = INTVAL (XEXP (XEXP (x, 0), 1));
+
+             /* If we were given a MULT, we must fix the constant
+                as we're going to create the ASHIFT form.  */
+             if (GET_CODE (XEXP (x, 0)) == MULT)
+               shift_val = exact_log2 (shift_val);
+
              rtx reg1, reg2;
 
              reg1 = XEXP (x, 1);
@@ -1342,21 +1376,27 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
              if (GET_CODE (reg2) != REG)
                reg2 = force_reg (Pmode, force_operand (reg2, 0));
 
-             return force_reg (Pmode,
-                               gen_rtx_PLUS (Pmode,
-                                             gen_rtx_MULT (Pmode,
-                                                           reg2,
-                                                           GEN_INT (val)),
-                                             reg1));
+             return
+               force_reg (Pmode,
+                          gen_rtx_PLUS (Pmode,
+                                        gen_rtx_ASHIFT (Pmode,
+                                                        reg2,
+                                                        GEN_INT (shift_val)),
+                                        reg1));
            }
          else if ((mode == DFmode || mode == SFmode)
                   && GET_CODE (XEXP (y, 0)) == SYMBOL_REF
-                  && GET_CODE (XEXP (x, 0)) == MULT
+                  && mem_shadd_or_shadd_rtx_p (XEXP (x, 0))
                   && GET_CODE (XEXP (y, 1)) == CONST_INT
-                  && INTVAL (XEXP (y, 1)) % INTVAL (XEXP (XEXP (x, 0), 1)) == 0
-                  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-                  && pa_shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
+                  && INTVAL (XEXP (y, 1)) % (1 << INTVAL (XEXP (XEXP (x, 0), 1))) == 0)
            {
+             int shift_val = INTVAL (XEXP (XEXP (x, 0), 1));
+
+             /* If we were given a MULT, we must fix the constant
+                as we're going to create the ASHIFT form.  */
+             if (GET_CODE (XEXP (x, 0)) == MULT)
+               shift_val = exact_log2 (shift_val);
+
              regx1
                = force_reg (Pmode, GEN_INT (INTVAL (XEXP (y, 1))
                                             / INTVAL (XEXP (XEXP (x, 0), 1))));
@@ -1368,8 +1408,8 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
              return
                force_reg (Pmode,
                           gen_rtx_PLUS (Pmode,
-                                        gen_rtx_MULT (Pmode, regx2,
-                                                      XEXP (XEXP (x, 0), 1)),
+                                        gen_rtx_ASHIFT (Pmode, regx2,
+                                                        GEN_INT (shift_val)),
                                         force_reg (Pmode, XEXP (y, 0))));
            }
          else if (GET_CODE (XEXP (y, 1)) == CONST_INT