This is the last of the infrastructure patches that I have currently done.
This adds a new reg_addr flag to note whether the d-form address is a ds-form
(bottom 2 bits must be 0).  At present, nothing uses this, but I have plans for
it in the future.

2018-03-22  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        * config/rs6000/rs6000.c (addr_mask_type): Grow mask to 16 bits.
        (RELOAD_REG_DS_OFFSET): New mask for DS-form addresses.
        (mode_supports_ds_form): New helper function to return if a reload
        register class uses DS-form addresses.
        (rs6000_debug_addr_mask): Print if we have DS-form addresses.
        (rs6000_setup_reg_addr_masks): Note which reload register classes
        use DS-form addresses.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 258782)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -503,16 +503,17 @@ static const struct reload_reg_map_type 
 /* Mask bits for each register class, indexed per mode.  Historically the
    compiler has been more restrictive which types can do PRE_MODIFY instead of
    PRE_INC and PRE_DEC, so keep track of sepaate bits for these two.  */
-typedef unsigned char addr_mask_type;
+typedef unsigned short addr_mask_type;
 
-#define RELOAD_REG_VALID       0x01    /* Mode valid in register..  */
-#define RELOAD_REG_MULTIPLE    0x02    /* Mode takes multiple registers.  */
-#define RELOAD_REG_INDEXED     0x04    /* Reg+reg addressing.  */
-#define RELOAD_REG_OFFSET      0x08    /* Reg+offset addressing. */
-#define RELOAD_REG_PRE_INCDEC  0x10    /* PRE_INC/PRE_DEC valid.  */
-#define RELOAD_REG_PRE_MODIFY  0x20    /* PRE_MODIFY valid.  */
-#define RELOAD_REG_AND_M16     0x40    /* AND -16 addressing.  */
-#define RELOAD_REG_QUAD_OFFSET 0x80    /* quad offset is limited.  */
+#define RELOAD_REG_VALID       0x001   /* Mode valid in register..  */
+#define RELOAD_REG_MULTIPLE    0x002   /* Mode takes multiple registers.  */
+#define RELOAD_REG_INDEXED     0x004   /* Reg+reg addressing.  */
+#define RELOAD_REG_OFFSET      0x008   /* Reg+offset addressing. */
+#define RELOAD_REG_PRE_INCDEC  0x010   /* PRE_INC/PRE_DEC valid.  */
+#define RELOAD_REG_PRE_MODIFY  0x020   /* PRE_MODIFY valid.  */
+#define RELOAD_REG_AND_M16     0x040   /* AND -16 addressing.  */
+#define RELOAD_REG_QUAD_OFFSET 0x080   /* quad offset is limited.  */
+#define RELOAD_REG_DS_OFFSET   0x100   /* DS-form (bottom 2 bits 0).  */
 
 /* Register type masks based on the type, of valid addressing modes.  */
 struct rs6000_reg_addr {
@@ -565,6 +566,16 @@ mode_supports_d_form (machine_mode mode,
   return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_OFFSET) != 0);
 }
 
+/* Return true if we have DS-form addressing in a given reload register class
+   or if some reload register class supports it.  DS-form addressing must have
+   the bottom 2 bits set to 0.  */
+static inline bool
+mode_supports_ds_form (machine_mode mode,
+                      enum rs6000_reload_reg_type rt = RELOAD_REG_ANY)
+{
+  return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_DS_OFFSET) != 0);
+}
+
 /* Return true if we have DQ-form addressing in a given reload register class
    or if some reload register class supports it.  DQ-form addressing must have
    the bottom 4 bits set to 0.  */
@@ -2349,6 +2360,8 @@ rs6000_debug_addr_mask (addr_mask_type m
 
   if ((mask & RELOAD_REG_QUAD_OFFSET) != 0)
     *p++ = 'O';
+  else if ((mask & RELOAD_REG_DS_OFFSET) != 0)
+    *p++ = 'O';
   else if ((mask & RELOAD_REG_OFFSET) != 0)
     *p++ = 'o';
   else if (keep_spaces)
@@ -3035,27 +3048,40 @@ rs6000_setup_reg_addr_masks (void)
 
          /* GPR and FPR registers can do REG+OFFSET addressing, except
             possibly for SDmode.  ISA 3.0 (i.e. power9) adds D-form addressing
-            for 64-bit scalars and 32-bit SFmode to altivec registers.  */
-         if ((addr_mask != 0) && !indexed_only_p
-             && msize <= 8
-             && (rc == RELOAD_REG_GPR
-                 || ((msize == 8 || m2 == SFmode)
-                     && (rc == RELOAD_REG_FPR
-                         || (rc == RELOAD_REG_VMX && TARGET_P9_VECTOR)))))
-           addr_mask |= RELOAD_REG_OFFSET;
-
-         /* VSX registers can do REG+OFFSET addresssing if ISA 3.0
-            instructions are enabled.  The offset for 128-bit VSX registers is
-            only 12-bits.  While GPRs can handle the full offset range, VSX
-            registers can only handle the restricted range.  */
-         else if ((addr_mask != 0) && !indexed_only_p
-                  && msize == 16 && TARGET_P9_VECTOR
-                  && (ALTIVEC_OR_VSX_VECTOR_MODE (m2)
-                      || (m2 == TImode && TARGET_VSX)))
-           {
-             addr_mask |= RELOAD_REG_OFFSET;
-             if (rc == RELOAD_REG_FPR || rc == RELOAD_REG_VMX)
-               addr_mask |= RELOAD_REG_QUAD_OFFSET;
+            for 64-bit scalars and 32-bit SFmode to altivec registers.
+
+            64-bit GPR and ISA 3.0 D-form use DS-form addressing with the
+            bottom 2 bits set to 0.  */
+         if ((addr_mask != 0) && !indexed_only_p)
+           {
+             if (msize <= 8 && rc == RELOAD_REG_GPR)
+               {
+                 if (msize == 8)
+                   addr_mask |= RELOAD_REG_OFFSET | RELOAD_REG_DS_OFFSET;
+                 else
+                   addr_mask |= RELOAD_REG_OFFSET;
+               }
+             else if (msize == 8 || m2 == SFmode)
+               {
+                 if  (rc == RELOAD_REG_FPR)
+                   addr_mask |= RELOAD_REG_OFFSET;
+                 else if (rc == RELOAD_REG_VMX && TARGET_P9_VECTOR)
+                   addr_mask |= RELOAD_REG_OFFSET | RELOAD_REG_DS_OFFSET;
+               }
+
+             /* VSX registers can do REG+OFFSET addresssing if ISA 3.0
+                instructions are enabled.  The offset for 128-bit VSX
+                registers is only 12-bits.  While GPRs use DS offsets for
+                64-bit, VSX registers can only handle the DQ offsets.  */
+             else if (msize == 16 && TARGET_P9_VECTOR
+                      && (ALTIVEC_OR_VSX_VECTOR_MODE (m2)
+                          || (m2 == TImode && TARGET_VSX)))
+               {
+                 if (rc == RELOAD_REG_GPR)
+                   addr_mask |= RELOAD_REG_OFFSET | RELOAD_REG_DS_OFFSET;
+                 else
+                   addr_mask |= RELOAD_REG_OFFSET | RELOAD_REG_QUAD_OFFSET;
+               }
            }
 
          /* VMX registers can do (REG & -16) and ((REG+REG) & -16)

Reply via email to