I am starting to work on cleaning up the memory addressing support in the GCC 9
time frame.  At the moment, I am working on upgrading the infrastructure to
allow in the future to prevent splitting memory on 64-bit LE systems too early,
rework the fusion support, and provide a pathway for future processor support.

The first patch in the series moves most of the reg_addr structure from
rs6000.c to rs6000-protos.h, so that in the next patch, we can start splitting
some of the address code to other files.

In addition to just moving the reg_addr stuff to be global, there are a few
minor changes in this patch:

    1)  I was playing with making r12 be fixed with a new option (not in this
        set of patches), and I noticed it wasn't reflected in the -mdebug=reg
        debug dump, due to the debug dump being done before the conditional
        registers are setup.  I made the debug dump set conditional registers.

    2)  I renamed some of the mode_suppports helper functions to be more
        consistent the instruction documentation (i.e. there are helper
        functions for normal d-form register+offset instructions, ds-form where
        the bottom 2 bits must be 0 and dq-form where the bottom 4 bits must be
        0).  I added optional arguments to the helper functions, so that
        secondary reload in the future can narrow down whether a particular
        register class has particular support.

    3)  I did a simplification in setting up the reg_addr address masks, where
        instead of 3 states which two set INDEXED and the other sets MULTIPLE
        register, it only has 1 place where it sets INDEXED.

I have tested this with full bootstrap and make check on a little endian power8
with no regressions.  Since we are in stage4 currently, I am not asking for
permission to check it in, but if you have any comments on how you would like
to see the eventual patches when stage1 opens up, let me know.  It would be
simpler to make the changes now, rather than when the number of patches have
accumulated.

The second patch that I will submit shortly will move the
rs6000_output_move_128bit function to a new file (rs6000-output.c).

The third patch that I will submit will be to move the movdi patterns to a
separate function (rs6000_output_move_64bit) also in rs6000-output.c, so that
in the future we can use C++ code to check on constraints, etc.

I haven't written it yet, but the fourth patch is likely to similarly move DF
and DD output templates to use the same function.  One thing I plan to do for
DF/DD is to structure the comments about the alternatives so that it is more
readable, much like I've done for movdi, etc.

I likely will remove the undocumented toc-fusion all together, and eventually
rework the p8/p9 fusion support.

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

        * config/rs6000/rs6000-protos.h (regno_or_subregno): Add
        declaration.
        (enum rs6000_reg_type): Move the basic reg_addr support from
        rs6000.c to rs6000-protos.h, except for the parts that store
        insn_code's for the register allocator to allow future patches to
        move parts of rs6000.c to other files.  Change the bool flags to
        bit-fields.  Add a flag to indicate the mode/reload register class
        uses DS-form (14-bit offset) addresses.
        (reg_class_to_reg_type): Likwise.
        (IS_STD_REG_TYPE): Likwise.
        (IS_FP_VECT_REG_TYPE): Likwise.
        (enum rs6000_reload_reg_type): Likwise.
        (struct rs6000_reg_addr): Likwise.
        (reg_addr): Likwise.
        (RELOAD_REG_*): Likewise.
        (mode_supports_pre_incdec_p): Move the mode supports helper
        functions to rs6000-protos.h.  Add an optional argument to use a
        particular reload register class instead of RELOAD_REG_ANY.
        Rename mode_supports_vsx_dform_quad -> mode_supports_dq_form.  Add
        mode_supports_ds_form for DS-form addresses.  Add
        mode_supports_x_form for X-form (indexed) addresses.
        (mode_supports_pre_modify_p): Likewise.
        (mode_supports_d_form): Likewise.
        (mode_supports_ds_form): Likewise.
        (mode_supports_dq_form): Likewise.
        (mode_supports_x_form): Likewise.
        * config/rs6000/rs6000.c (enum rs6000_reg_type): Move basic
        reg_addr support to rs6000-protos.h.
        (IS_STD_REG_TYPE): Likewise.
        (IS_FP_VECT_REG_TYPE): Likewise.
        (enum rs6000_reload_reg_typ): Likewise.
        (reg_class_to_reg_type): Make global.
        (addr_mask_type): Move basic reg_addr support to rs6000-protos.h.
        (reg_addr): Make global.
        (RELOAD_REG_VALID): Move basic reg_addr support to
        rs6000-protos.h.
        (RELOAD_REG_*): Likewise.
        (struct rs6000_insn_functions): New structure that includes the
        parts of the old reg_addr structure that did not move to
        rs6000-protos.h because it contains insn codes.
        (rs6000_insns): Likewise.
        (mode_supports_pre_modify_p): Move to rs6000-protos.h.
        (mode_supports_pre_modify_p): Likewise.
        (mode_supports_vmx_dform): Likewise.
        (mode_supports_vsx_dform_quad): Likewise.
        (rs6000_conditional_register_usage): Add forward declaration.
        (rs6000_debug_addr_mask): Print whether the mode/reload register
        class uses DS-form memory instructions.
        (rs6000_debug_print_mode): Call rs6000_conditional_register_usage
        in order to print the status of the registers properly.  Use
        rs6000_insns instead of reg_addr for the insn code elements.
        (rs6000_setup_reg_addr_masks): Simplify the code to set whether a
        mode uses multiple registers or provides indexed mode.  Don't
        allow update addresses on modes that only support indexed mode.
        Note that DI/SI in 64-bit use DS-form addresses as well as ISA 3.0
        scalar altivec offset references.
        (rs6000_init_hard_regno_mode_ok): Clear rs6000_insns.  Change to
        use rs6000_insns instead of reg_addr for saving the insn codes for
        secondary reload and fusion support.
        (regno_or_subregno): Make global.
        (quad_address_p): Rename mode_supports_vsx_dform_quad to
        mode_supports_dq_form.
        (reg_offset_addressing_ok_p): Likewise.
        (offsettable_ok_by_alignment): Likewise.
        (rs6000_legitimate_offset_address_p): Likewise.
        (legitimate_lo_sum_address_p): Likewise.
        (rs6000_legitimize_address): Likewise.
        (rs6000_legitimize_reload_address): Likewise.
        (rs6000_legitimate_address_p): Likewise.
        (rs6000_secondary_reload_direct_move): Use rs6000_insns to pick up
        secondary reload and fusion insn codes instead of reg_addr.
        (rs6000_secondary_reload): Likewise.
        (rs6000_secondary_reload_inner): Rename
        mode_supports_vsx_dform_quad to mode_supports_dq_form.  Use
        mode_supports_d_form with RELOAD_REG_VMX instead of calling
        mode_supports_vmx_dform.
        (rs6000_preferred_reload_class): Likewise.
        (rs6000_secondary_reload_class): Likewise.
        (rs6000_output_move_128bit): Likewise.


-- 
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-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h   (revision 258530)
+++ gcc/config/rs6000/rs6000-protos.h   (working copy)
@@ -61,6 +61,7 @@ extern void paired_expand_vector_init (r
 extern void rs6000_expand_vector_set (rtx, rtx, int);
 extern void rs6000_expand_vector_extract (rtx, rtx, rtx);
 extern void rs6000_split_vec_extract_var (rtx, rtx, rtx, rtx, rtx);
+extern int regno_or_subregno (rtx);
 extern rtx rs6000_adjust_vec_address (rtx, rtx, rtx, rtx, machine_mode);
 extern void rs6000_split_v4si_init (rtx []);
 extern void altivec_expand_vec_perm_le (rtx op[4]);
@@ -258,4 +259,116 @@ extern bool rs6000_quadword_masked_addre
 extern rtx rs6000_gen_lvx (enum machine_mode, rtx, rtx);
 extern rtx rs6000_gen_stvx (enum machine_mode, rtx, rtx);
 
+
+/* Simplfy register classes into simpler classifications.  We assume
+   GPR_REG_TYPE - FPR_REG_TYPE are ordered so that we can use a simple range
+   check for standard register classes (gpr/floating/altivec/vsx) and
+   floating/vector classes (float/altivec/vsx).  */
+
+enum rs6000_reg_type {
+  NO_REG_TYPE,
+  PSEUDO_REG_TYPE,
+  GPR_REG_TYPE,
+  VSX_REG_TYPE,
+  ALTIVEC_REG_TYPE,
+  FPR_REG_TYPE,
+  SPR_REG_TYPE,
+  CR_REG_TYPE
+};
+
+/* Map register class to register type.  */
+extern enum rs6000_reg_type reg_class_to_reg_type[];
+
+/* First/last register type for the 'normal' register types (i.e. general
+   purpose, floating point, altivec, and VSX registers).  */
+#define IS_STD_REG_TYPE(RTYPE) IN_RANGE(RTYPE, GPR_REG_TYPE, FPR_REG_TYPE)
+
+#define IS_FP_VECT_REG_TYPE(RTYPE) IN_RANGE(RTYPE, VSX_REG_TYPE, FPR_REG_TYPE)
+
+/* Register classes we care about in secondary reload or go if legitimate
+   address.  We only need to worry about GPR, FPR, and Altivec registers here,
+   along an ANY field that is the OR of the 3 register classes.  */
+
+enum rs6000_reload_reg_type {
+  RELOAD_REG_GPR,                      /* General purpose registers.  */
+  RELOAD_REG_FPR,                      /* Traditional floating point regs.  */
+  RELOAD_REG_VMX,                      /* Altivec (VMX) registers.  */
+  RELOAD_REG_ANY,                      /* OR of GPR, FPR, Altivec masks.  */
+  N_RELOAD_REG
+};
+
+/* 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 short addr_mask_type;
+
+#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   /* Bottom 4 bits must be 0.  */
+#define RELOAD_REG_DS_OFFSET   0x100   /* Bottom 2 bits must be 0.  */
+
+/* Register type masks based on the type, of valid addressing modes.  */
+struct rs6000_reg_addr {
+  addr_mask_type addr_mask[(int)N_RELOAD_REG]; /* Valid address masks.  */
+  unsigned char scalar_in_vmx_p        : 1;            /* Scalar can go in 
VMX.  */
+  unsigned char fused_toc      : 1;            /* Mode supports TOC fusion.  */
+};
+
+extern struct rs6000_reg_addr reg_addr[];
+
+/* Helper function to say whether a mode supports PRE_INC or PRE_DEC.  */
+static inline bool
+mode_supports_pre_incdec_p (machine_mode mode,
+                           enum rs6000_reload_reg_type rt = RELOAD_REG_ANY)
+{
+  return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_PRE_INCDEC) != 0);
+}
+
+/* Helper function to say whether a mode supports PRE_MODIFY.  */
+static inline bool
+mode_supports_pre_modify_p (machine_mode mode,
+                           enum rs6000_reload_reg_type rt = RELOAD_REG_ANY)
+{
+  return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_PRE_MODIFY) != 0);
+}
+
+/* Return true if we have offset addressing (d-form).  The offset may be 12 bit
+   (dq-form), 14 bits (ds-form), or 16 (d-form) bits.  */
+static inline bool
+mode_supports_d_form (machine_mode mode,
+                     enum rs6000_reload_reg_type rt = RELOAD_REG_ANY)
+{
+  return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_OFFSET) != 0);
+}
+
+/* Return true if we have DS-form addressing in any registers where the bottom
+   2 bits must be 0 (i.e. LD, ST, etc.).  */
+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.  The bottom 4 bits must be 0.  */
+static inline bool
+mode_supports_dq_form (machine_mode mode,
+                      enum rs6000_reload_reg_type rt = RELOAD_REG_ANY)
+{
+  return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_QUAD_OFFSET) != 0);
+}
+
+/* Return true if we have indexed addressing (x-form).  */
+static inline bool
+mode_supports_x_form (machine_mode mode,
+                     enum rs6000_reload_reg_type rt = RELOAD_REG_ANY)
+{
+  return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_INDEXED) != 0);
+}
+
 #endif  /* rs6000-protos.h */
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 258531)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -443,43 +443,8 @@ bool cpu_builtin_p;
    don't link in rs6000-c.c, so we can't call it directly.  */
 void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, HOST_WIDE_INT);
 
-/* Simplfy register classes into simpler classifications.  We assume
-   GPR_REG_TYPE - FPR_REG_TYPE are ordered so that we can use a simple range
-   check for standard register classes (gpr/floating/altivec/vsx) and
-   floating/vector classes (float/altivec/vsx).  */
-
-enum rs6000_reg_type {
-  NO_REG_TYPE,
-  PSEUDO_REG_TYPE,
-  GPR_REG_TYPE,
-  VSX_REG_TYPE,
-  ALTIVEC_REG_TYPE,
-  FPR_REG_TYPE,
-  SPR_REG_TYPE,
-  CR_REG_TYPE
-};
-
 /* Map register class to register type.  */
-static enum rs6000_reg_type reg_class_to_reg_type[N_REG_CLASSES];
-
-/* First/last register type for the 'normal' register types (i.e. general
-   purpose, floating point, altivec, and VSX registers).  */
-#define IS_STD_REG_TYPE(RTYPE) IN_RANGE(RTYPE, GPR_REG_TYPE, FPR_REG_TYPE)
-
-#define IS_FP_VECT_REG_TYPE(RTYPE) IN_RANGE(RTYPE, VSX_REG_TYPE, FPR_REG_TYPE)
-
-
-/* Register classes we care about in secondary reload or go if legitimate
-   address.  We only need to worry about GPR, FPR, and Altivec registers here,
-   along an ANY field that is the OR of the 3 register classes.  */
-
-enum rs6000_reload_reg_type {
-  RELOAD_REG_GPR,                      /* General purpose registers.  */
-  RELOAD_REG_FPR,                      /* Traditional floating point regs.  */
-  RELOAD_REG_VMX,                      /* Altivec (VMX) registers.  */
-  RELOAD_REG_ANY,                      /* OR of GPR, FPR, Altivec masks.  */
-  N_RELOAD_REG
-};
+enum rs6000_reg_type reg_class_to_reg_type[N_REG_CLASSES];
 
 /* For setting up register classes, loop through the 3 register classes mapping
    into real registers, and skip the ANY class, which is just an OR of the
@@ -500,22 +465,12 @@ static const struct reload_reg_map_type 
   { "Any",     -1 },                   /* RELOAD_REG_ANY.  */
 };
 
-/* 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;
-
-#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.  */
-
 /* Register type masks based on the type, of valid addressing modes.  */
-struct rs6000_reg_addr {
+struct rs6000_reg_addr reg_addr[NUM_MACHINE_MODES];
+
+/* Insns to use for loading/storing various register types, and for creating
+   various combined fusion instructions.  */
+struct rs6000_insn_functions {
   enum insn_code reload_load;          /* INSN to reload for loading. */
   enum insn_code reload_store;         /* INSN to reload for storing.  */
   enum insn_code reload_fpr_gpr;       /* INSN to move from FPR to GPR.  */
@@ -530,28 +485,9 @@ struct rs6000_reg_addr {
                                           or stores for each reg. class.  */   
                                   
   enum insn_code fusion_addis_ld[(int)N_RELOAD_REG];
   enum insn_code fusion_addis_st[(int)N_RELOAD_REG];
-  addr_mask_type addr_mask[(int)N_RELOAD_REG]; /* Valid address masks.  */
-  bool scalar_in_vmx_p;                        /* Scalar value can go in VMX.  
*/
-  bool fused_toc;                      /* Mode supports TOC fusion.  */
 };
 
-static struct rs6000_reg_addr reg_addr[NUM_MACHINE_MODES];
-
-/* Helper function to say whether a mode supports PRE_INC or PRE_DEC.  */
-static inline bool
-mode_supports_pre_incdec_p (machine_mode mode)
-{
-  return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_INCDEC)
-         != 0);
-}
-
-/* Helper function to say whether a mode supports PRE_MODIFY.  */
-static inline bool
-mode_supports_pre_modify_p (machine_mode mode)
-{
-  return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_MODIFY)
-         != 0);
-}
+static struct rs6000_insn_functions rs6000_insns[NUM_MACHINE_MODES];
 
 /* Given that there exists at least one variable that is set (produced)
    by OUT_INSN and read (consumed) by IN_INSN, return true iff
@@ -638,23 +574,6 @@ rs6000_store_data_bypass_p (rtx_insn *ou
   return store_data_bypass_p (out_insn, in_insn);
 }
 
-/* Return true if we have D-form addressing in altivec registers.  */
-static inline bool
-mode_supports_vmx_dform (machine_mode mode)
-{
-  return ((reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_OFFSET) != 0);
-}
-
-/* Return true if we have D-form addressing in VSX registers.  This addressing
-   is more limited than normal d-form addressing in that the offset must be
-   aligned on a 16-byte boundary.  */
-static inline bool
-mode_supports_vsx_dform_quad (machine_mode mode)
-{
-  return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_QUAD_OFFSET)
-         != 0);
-}
-
 
 /* Processor costs (relative to an add) */
 
@@ -1395,6 +1314,7 @@ static bool rs6000_debug_can_change_mode
                                                reg_class_t);
 static bool rs6000_save_toc_in_prologue_p (void);
 static rtx rs6000_internal_arg_pointer (void);
+static void rs6000_conditional_register_usage (void);
 
 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, machine_mode, int, int,
                                             int, int *)
@@ -2224,6 +2144,10 @@ rs6000_debug_reg_print (int first_regno,
 {
   int r, m;
 
+  /* Insure the conditional registers are up to date when printing the debug
+     information.  */
+  rs6000_conditional_register_usage ();
+
   for (r = first_regno; r <= last_regno; ++r)
     {
       const char *comma = "";
@@ -2344,6 +2268,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++ = 'D';
   else if ((mask & RELOAD_REG_OFFSET) != 0)
     *p++ = 'o';
   else if (keep_spaces)
@@ -2382,11 +2308,11 @@ rs6000_debug_print_mode (ssize_t m)
     fprintf (stderr, " %s: %s", reload_reg_map[rc].name,
             rs6000_debug_addr_mask (reg_addr[m].addr_mask[rc], true));
 
-  if ((reg_addr[m].reload_store != CODE_FOR_nothing)
-      || (reg_addr[m].reload_load != CODE_FOR_nothing))
+  if ((rs6000_insns[m].reload_store != CODE_FOR_nothing)
+      || (rs6000_insns[m].reload_load != CODE_FOR_nothing))
     fprintf (stderr, "  Reload=%c%c",
-            (reg_addr[m].reload_store != CODE_FOR_nothing) ? 's' : '*',
-            (reg_addr[m].reload_load != CODE_FOR_nothing) ? 'l' : '*');
+            (rs6000_insns[m].reload_store != CODE_FOR_nothing) ? 's' : '*',
+            (rs6000_insns[m].reload_load != CODE_FOR_nothing) ? 'l' : '*');
   else
     spaces += sizeof ("  Reload=sl") - 1;
 
@@ -2398,7 +2324,7 @@ rs6000_debug_print_mode (ssize_t m)
   else
     spaces += sizeof ("  Upper=y") - 1;
 
-  fuse_extra_p = ((reg_addr[m].fusion_gpr_ld != CODE_FOR_nothing)
+  fuse_extra_p = (rs6000_insns[m].fusion_gpr_ld != CODE_FOR_nothing
                  || reg_addr[m].fused_toc);
   if (!fuse_extra_p)
     {
@@ -2406,11 +2332,11 @@ rs6000_debug_print_mode (ssize_t m)
        {
          if (rc != RELOAD_REG_ANY)
            {
-             if (reg_addr[m].fusion_addi_ld[rc]     != CODE_FOR_nothing
-                 || reg_addr[m].fusion_addi_ld[rc]  != CODE_FOR_nothing
-                 || reg_addr[m].fusion_addi_st[rc]  != CODE_FOR_nothing
-                 || reg_addr[m].fusion_addis_ld[rc] != CODE_FOR_nothing
-                 || reg_addr[m].fusion_addis_st[rc] != CODE_FOR_nothing)
+             if (rs6000_insns[m].fusion_addi_ld[rc]     != CODE_FOR_nothing
+                 || rs6000_insns[m].fusion_addi_ld[rc]  != CODE_FOR_nothing
+                 || rs6000_insns[m].fusion_addi_st[rc]  != CODE_FOR_nothing
+                 || rs6000_insns[m].fusion_addis_ld[rc] != CODE_FOR_nothing
+                 || rs6000_insns[m].fusion_addis_st[rc] != CODE_FOR_nothing)
                {
                  fuse_extra_p = true;
                  break;
@@ -2430,16 +2356,16 @@ rs6000_debug_print_mode (ssize_t m)
            {
              char load, store;
 
-             if (reg_addr[m].fusion_addis_ld[rc] != CODE_FOR_nothing)
+             if (rs6000_insns[m].fusion_addis_ld[rc] != CODE_FOR_nothing)
                load = 'l';
-             else if (reg_addr[m].fusion_addi_ld[rc] != CODE_FOR_nothing)
+             else if (rs6000_insns[m].fusion_addi_ld[rc] != CODE_FOR_nothing)
                load = 'L';
              else
                load = '-';
 
-             if (reg_addr[m].fusion_addis_st[rc] != CODE_FOR_nothing)
+             if (rs6000_insns[m].fusion_addis_st[rc] != CODE_FOR_nothing)
                store = 's';
-             else if (reg_addr[m].fusion_addi_st[rc] != CODE_FOR_nothing)
+             else if (rs6000_insns[m].fusion_addi_st[rc] != CODE_FOR_nothing)
                store = 'S';
              else
                store = '-';
@@ -2455,7 +2381,7 @@ rs6000_debug_print_mode (ssize_t m)
            }
        }
 
-      if (reg_addr[m].fusion_gpr_ld != CODE_FOR_nothing)
+      if (rs6000_insns[m].fusion_gpr_ld != CODE_FOR_nothing)
        {
          fprintf (stderr, "%*sP8gpr", (spaces + 1), "");
          spaces = 0;
@@ -2951,8 +2877,11 @@ rs6000_setup_reg_addr_masks (void)
 
       /* SDmode is special in that we want to access it only via REG+REG
         addressing on power7 and above, since we want to use the LFIWZX and
-        STFIWZX instructions to load it.  */
-      bool indexed_only_p = (m == SDmode && TARGET_NO_SDMODE_STACK);
+        STFIWZX instructions to load it.  Paired floating point is also
+        only indexed mode.  */
+      bool indexed_only_p = ((m == E_SDmode && TARGET_NO_SDMODE_STACK)
+                            || (TARGET_PAIRED_FLOAT
+                                && (m == E_V2SImode || m == E_V2SFmode)));
 
       any_addr_mask = 0;
       for (rc = FIRST_RELOAD_REG_CLASS; rc <= LAST_RELOAD_REG_CLASS; rc++)
@@ -2972,11 +2901,8 @@ rs6000_setup_reg_addr_masks (void)
 
              /* Indicate if the mode takes more than 1 physical register.  If
                 it takes a single register, indicate it can do REG+REG
-                addressing.  Small integers in VSX registers can only do
-                REG+REG addressing.  */
-             if (small_int_vsx_p)
-               addr_mask |= RELOAD_REG_INDEXED;
-             else if (nregs > 1 || m == BLKmode || complex_p)
+                addressing.  */
+             if (nregs > 1 || m == BLKmode || complex_p)
                addr_mask |= RELOAD_REG_MULTIPLE;
              else
                addr_mask |= RELOAD_REG_INDEXED;
@@ -3001,7 +2927,8 @@ rs6000_setup_reg_addr_masks (void)
                  && !complex_p
                  && (m != E_DFmode || !TARGET_VSX)
                  && (m != E_SFmode || !TARGET_P8_VECTOR)
-                 && !small_int_vsx_p)
+                 && !small_int_vsx_p
+                 && !indexed_only_p)
                {
                  addr_mask |= RELOAD_REG_PRE_INCDEC;
 
@@ -3053,6 +2980,22 @@ rs6000_setup_reg_addr_masks (void)
                addr_mask |= RELOAD_REG_QUAD_OFFSET;
            }
 
+         /* LD and STD are DS-form instructions, which must have the bottom 2
+            bits be 0.  However, since DFmode is primarily used in the
+            floating point/vector registers, don't restrict the offsets in ISA
+            2.xx.  */
+         if (rc == RELOAD_REG_GPR && msize == 8 && TARGET_POWERPC64
+             && (addr_mask & RELOAD_REG_OFFSET) != 0
+             && INTEGRAL_MODE_P (m2))
+           addr_mask |= RELOAD_REG_DS_OFFSET;
+
+         /* ISA 3.0 LXSD, LXSSP, STXSD, STXSSP altivec load/store instructions
+            are DS-FORM.  */
+         else if (rc == RELOAD_REG_VMX && TARGET_P9_VECTOR
+                  && (addr_mask & RELOAD_REG_OFFSET) != 0
+                  && (msize == 8 ||  m2 == SFmode))
+           addr_mask |= RELOAD_REG_DS_OFFSET;
+
          /* VMX registers can do (REG & -16) and ((REG+REG) & -16)
             addressing on 128-bit types.  */
          if (rc == RELOAD_REG_VMX && msize == 16
@@ -3142,6 +3085,7 @@ rs6000_init_hard_regno_mode_ok (bool glo
 
   gcc_assert ((int)CODE_FOR_nothing == 0);
   memset ((void *) &reg_addr[0], '\0', sizeof (reg_addr));
+  memset ((void *) &rs6000_insns, '\0', sizeof (rs6000_insns));
 
   gcc_assert ((int)NO_REGS == 0);
   memset ((void *) &rs6000_constraints[0], '\0', sizeof (rs6000_constraints));
@@ -3394,142 +3338,167 @@ rs6000_init_hard_regno_mode_ok (bool glo
     {
       if (TARGET_64BIT)
        {
-         reg_addr[V16QImode].reload_store = CODE_FOR_reload_v16qi_di_store;
-         reg_addr[V16QImode].reload_load  = CODE_FOR_reload_v16qi_di_load;
-         reg_addr[V8HImode].reload_store  = CODE_FOR_reload_v8hi_di_store;
-         reg_addr[V8HImode].reload_load   = CODE_FOR_reload_v8hi_di_load;
-         reg_addr[V4SImode].reload_store  = CODE_FOR_reload_v4si_di_store;
-         reg_addr[V4SImode].reload_load   = CODE_FOR_reload_v4si_di_load;
-         reg_addr[V2DImode].reload_store  = CODE_FOR_reload_v2di_di_store;
-         reg_addr[V2DImode].reload_load   = CODE_FOR_reload_v2di_di_load;
-         reg_addr[V1TImode].reload_store  = CODE_FOR_reload_v1ti_di_store;
-         reg_addr[V1TImode].reload_load   = CODE_FOR_reload_v1ti_di_load;
-         reg_addr[V4SFmode].reload_store  = CODE_FOR_reload_v4sf_di_store;
-         reg_addr[V4SFmode].reload_load   = CODE_FOR_reload_v4sf_di_load;
-         reg_addr[V2DFmode].reload_store  = CODE_FOR_reload_v2df_di_store;
-         reg_addr[V2DFmode].reload_load   = CODE_FOR_reload_v2df_di_load;
-         reg_addr[DFmode].reload_store    = CODE_FOR_reload_df_di_store;
-         reg_addr[DFmode].reload_load     = CODE_FOR_reload_df_di_load;
-         reg_addr[DDmode].reload_store    = CODE_FOR_reload_dd_di_store;
-         reg_addr[DDmode].reload_load     = CODE_FOR_reload_dd_di_load;
-         reg_addr[SFmode].reload_store    = CODE_FOR_reload_sf_di_store;
-         reg_addr[SFmode].reload_load     = CODE_FOR_reload_sf_di_load;
+         rs6000_insns[V16QImode].reload_store = CODE_FOR_reload_v16qi_di_store;
+         rs6000_insns[V16QImode].reload_load  = CODE_FOR_reload_v16qi_di_load;
+         rs6000_insns[V8HImode].reload_store  = CODE_FOR_reload_v8hi_di_store;
+         rs6000_insns[V8HImode].reload_load   = CODE_FOR_reload_v8hi_di_load;
+         rs6000_insns[V4SImode].reload_store  = CODE_FOR_reload_v4si_di_store;
+         rs6000_insns[V4SImode].reload_load   = CODE_FOR_reload_v4si_di_load;
+         rs6000_insns[V2DImode].reload_store  = CODE_FOR_reload_v2di_di_store;
+         rs6000_insns[V2DImode].reload_load   = CODE_FOR_reload_v2di_di_load;
+         rs6000_insns[V1TImode].reload_store  = CODE_FOR_reload_v1ti_di_store;
+         rs6000_insns[V1TImode].reload_load   = CODE_FOR_reload_v1ti_di_load;
+         rs6000_insns[V4SFmode].reload_store  = CODE_FOR_reload_v4sf_di_store;
+         rs6000_insns[V4SFmode].reload_load   = CODE_FOR_reload_v4sf_di_load;
+         rs6000_insns[V2DFmode].reload_store  = CODE_FOR_reload_v2df_di_store;
+         rs6000_insns[V2DFmode].reload_load   = CODE_FOR_reload_v2df_di_load;
+         rs6000_insns[DFmode].reload_store    = CODE_FOR_reload_df_di_store;
+         rs6000_insns[DFmode].reload_load     = CODE_FOR_reload_df_di_load;
+         rs6000_insns[DDmode].reload_store    = CODE_FOR_reload_dd_di_store;
+         rs6000_insns[DDmode].reload_load     = CODE_FOR_reload_dd_di_load;
+         rs6000_insns[SFmode].reload_store    = CODE_FOR_reload_sf_di_store;
+         rs6000_insns[SFmode].reload_load     = CODE_FOR_reload_sf_di_load;
 
          if (FLOAT128_VECTOR_P (KFmode))
            {
-             reg_addr[KFmode].reload_store = CODE_FOR_reload_kf_di_store;
-             reg_addr[KFmode].reload_load  = CODE_FOR_reload_kf_di_load;
+             rs6000_insns[KFmode].reload_store = CODE_FOR_reload_kf_di_store;
+             rs6000_insns[KFmode].reload_load  = CODE_FOR_reload_kf_di_load;
            }
 
          if (FLOAT128_VECTOR_P (TFmode))
            {
-             reg_addr[TFmode].reload_store = CODE_FOR_reload_tf_di_store;
-             reg_addr[TFmode].reload_load  = CODE_FOR_reload_tf_di_load;
+             rs6000_insns[TFmode].reload_store = CODE_FOR_reload_tf_di_store;
+             rs6000_insns[TFmode].reload_load  = CODE_FOR_reload_tf_di_load;
            }
 
          /* Only provide a reload handler for SDmode if lfiwzx/stfiwx are
             available.  */
          if (TARGET_NO_SDMODE_STACK)
            {
-             reg_addr[SDmode].reload_store = CODE_FOR_reload_sd_di_store;
-             reg_addr[SDmode].reload_load  = CODE_FOR_reload_sd_di_load;
+             rs6000_insns[SDmode].reload_store = CODE_FOR_reload_sd_di_store;
+             rs6000_insns[SDmode].reload_load  = CODE_FOR_reload_sd_di_load;
            }
 
          if (TARGET_VSX)
            {
-             reg_addr[TImode].reload_store  = CODE_FOR_reload_ti_di_store;
-             reg_addr[TImode].reload_load   = CODE_FOR_reload_ti_di_load;
+             rs6000_insns[TImode].reload_store  = CODE_FOR_reload_ti_di_store;
+             rs6000_insns[TImode].reload_load   = CODE_FOR_reload_ti_di_load;
            }
 
          if (TARGET_DIRECT_MOVE && !TARGET_DIRECT_MOVE_128)
            {
-             reg_addr[TImode].reload_gpr_vsx    = 
CODE_FOR_reload_gpr_from_vsxti;
-             reg_addr[V1TImode].reload_gpr_vsx  = 
CODE_FOR_reload_gpr_from_vsxv1ti;
-             reg_addr[V2DFmode].reload_gpr_vsx  = 
CODE_FOR_reload_gpr_from_vsxv2df;
-             reg_addr[V2DImode].reload_gpr_vsx  = 
CODE_FOR_reload_gpr_from_vsxv2di;
-             reg_addr[V4SFmode].reload_gpr_vsx  = 
CODE_FOR_reload_gpr_from_vsxv4sf;
-             reg_addr[V4SImode].reload_gpr_vsx  = 
CODE_FOR_reload_gpr_from_vsxv4si;
-             reg_addr[V8HImode].reload_gpr_vsx  = 
CODE_FOR_reload_gpr_from_vsxv8hi;
-             reg_addr[V16QImode].reload_gpr_vsx = 
CODE_FOR_reload_gpr_from_vsxv16qi;
-             reg_addr[SFmode].reload_gpr_vsx    = 
CODE_FOR_reload_gpr_from_vsxsf;
-
-             reg_addr[TImode].reload_vsx_gpr    = 
CODE_FOR_reload_vsx_from_gprti;
-             reg_addr[V1TImode].reload_vsx_gpr  = 
CODE_FOR_reload_vsx_from_gprv1ti;
-             reg_addr[V2DFmode].reload_vsx_gpr  = 
CODE_FOR_reload_vsx_from_gprv2df;
-             reg_addr[V2DImode].reload_vsx_gpr  = 
CODE_FOR_reload_vsx_from_gprv2di;
-             reg_addr[V4SFmode].reload_vsx_gpr  = 
CODE_FOR_reload_vsx_from_gprv4sf;
-             reg_addr[V4SImode].reload_vsx_gpr  = 
CODE_FOR_reload_vsx_from_gprv4si;
-             reg_addr[V8HImode].reload_vsx_gpr  = 
CODE_FOR_reload_vsx_from_gprv8hi;
-             reg_addr[V16QImode].reload_vsx_gpr = 
CODE_FOR_reload_vsx_from_gprv16qi;
-             reg_addr[SFmode].reload_vsx_gpr    = 
CODE_FOR_reload_vsx_from_gprsf;
+             rs6000_insns[TImode].reload_gpr_vsx
+               = CODE_FOR_reload_gpr_from_vsxti;
+             rs6000_insns[V1TImode].reload_gpr_vsx
+               = CODE_FOR_reload_gpr_from_vsxv1ti;
+             rs6000_insns[V2DFmode].reload_gpr_vsx
+               = CODE_FOR_reload_gpr_from_vsxv2df;
+             rs6000_insns[V2DImode].reload_gpr_vsx
+               = CODE_FOR_reload_gpr_from_vsxv2di;
+             rs6000_insns[V4SFmode].reload_gpr_vsx
+               = CODE_FOR_reload_gpr_from_vsxv4sf;
+             rs6000_insns[V4SImode].reload_gpr_vsx
+               = CODE_FOR_reload_gpr_from_vsxv4si;
+             rs6000_insns[V8HImode].reload_gpr_vsx
+               = CODE_FOR_reload_gpr_from_vsxv8hi;
+             rs6000_insns[V16QImode].reload_gpr_vsx
+               = CODE_FOR_reload_gpr_from_vsxv16qi;
+             rs6000_insns[SFmode].reload_gpr_vsx
+               = CODE_FOR_reload_gpr_from_vsxsf;
+
+             rs6000_insns[TImode].reload_vsx_gpr
+               = CODE_FOR_reload_vsx_from_gprti;
+             rs6000_insns[V1TImode].reload_vsx_gpr
+               = CODE_FOR_reload_vsx_from_gprv1ti;
+             rs6000_insns[V2DFmode].reload_vsx_gpr
+               = CODE_FOR_reload_vsx_from_gprv2df;
+             rs6000_insns[V2DImode].reload_vsx_gpr
+               = CODE_FOR_reload_vsx_from_gprv2di;
+             rs6000_insns[V4SFmode].reload_vsx_gpr
+               = CODE_FOR_reload_vsx_from_gprv4sf;
+             rs6000_insns[V4SImode].reload_vsx_gpr
+               = CODE_FOR_reload_vsx_from_gprv4si;
+             rs6000_insns[V8HImode].reload_vsx_gpr
+               = CODE_FOR_reload_vsx_from_gprv8hi;
+             rs6000_insns[V16QImode].reload_vsx_gpr
+               = CODE_FOR_reload_vsx_from_gprv16qi;
+             rs6000_insns[SFmode].reload_vsx_gpr
+               = CODE_FOR_reload_vsx_from_gprsf;
 
              if (FLOAT128_VECTOR_P (KFmode))
                {
-                 reg_addr[KFmode].reload_gpr_vsx = 
CODE_FOR_reload_gpr_from_vsxkf;
-                 reg_addr[KFmode].reload_vsx_gpr = 
CODE_FOR_reload_vsx_from_gprkf;
+                 rs6000_insns[KFmode].reload_gpr_vsx
+                   = CODE_FOR_reload_gpr_from_vsxkf;
+                 rs6000_insns[KFmode].reload_vsx_gpr
+                   = CODE_FOR_reload_vsx_from_gprkf;
                }
 
              if (FLOAT128_VECTOR_P (TFmode))
                {
-                 reg_addr[TFmode].reload_gpr_vsx = 
CODE_FOR_reload_gpr_from_vsxtf;
-                 reg_addr[TFmode].reload_vsx_gpr = 
CODE_FOR_reload_vsx_from_gprtf;
+                 rs6000_insns[TFmode].reload_gpr_vsx
+                   = CODE_FOR_reload_gpr_from_vsxtf;
+                 rs6000_insns[TFmode].reload_vsx_gpr
+                   = CODE_FOR_reload_vsx_from_gprtf;
                }
            }
        }
       else
        {
-         reg_addr[V16QImode].reload_store = CODE_FOR_reload_v16qi_si_store;
-         reg_addr[V16QImode].reload_load  = CODE_FOR_reload_v16qi_si_load;
-         reg_addr[V8HImode].reload_store  = CODE_FOR_reload_v8hi_si_store;
-         reg_addr[V8HImode].reload_load   = CODE_FOR_reload_v8hi_si_load;
-         reg_addr[V4SImode].reload_store  = CODE_FOR_reload_v4si_si_store;
-         reg_addr[V4SImode].reload_load   = CODE_FOR_reload_v4si_si_load;
-         reg_addr[V2DImode].reload_store  = CODE_FOR_reload_v2di_si_store;
-         reg_addr[V2DImode].reload_load   = CODE_FOR_reload_v2di_si_load;
-         reg_addr[V1TImode].reload_store  = CODE_FOR_reload_v1ti_si_store;
-         reg_addr[V1TImode].reload_load   = CODE_FOR_reload_v1ti_si_load;
-         reg_addr[V4SFmode].reload_store  = CODE_FOR_reload_v4sf_si_store;
-         reg_addr[V4SFmode].reload_load   = CODE_FOR_reload_v4sf_si_load;
-         reg_addr[V2DFmode].reload_store  = CODE_FOR_reload_v2df_si_store;
-         reg_addr[V2DFmode].reload_load   = CODE_FOR_reload_v2df_si_load;
-         reg_addr[DFmode].reload_store    = CODE_FOR_reload_df_si_store;
-         reg_addr[DFmode].reload_load     = CODE_FOR_reload_df_si_load;
-         reg_addr[DDmode].reload_store    = CODE_FOR_reload_dd_si_store;
-         reg_addr[DDmode].reload_load     = CODE_FOR_reload_dd_si_load;
-         reg_addr[SFmode].reload_store    = CODE_FOR_reload_sf_si_store;
-         reg_addr[SFmode].reload_load     = CODE_FOR_reload_sf_si_load;
+         rs6000_insns[V16QImode].reload_store = CODE_FOR_reload_v16qi_si_store;
+         rs6000_insns[V16QImode].reload_load  = CODE_FOR_reload_v16qi_si_load;
+         rs6000_insns[V8HImode].reload_store  = CODE_FOR_reload_v8hi_si_store;
+         rs6000_insns[V8HImode].reload_load   = CODE_FOR_reload_v8hi_si_load;
+         rs6000_insns[V4SImode].reload_store  = CODE_FOR_reload_v4si_si_store;
+         rs6000_insns[V4SImode].reload_load   = CODE_FOR_reload_v4si_si_load;
+         rs6000_insns[V2DImode].reload_store  = CODE_FOR_reload_v2di_si_store;
+         rs6000_insns[V2DImode].reload_load   = CODE_FOR_reload_v2di_si_load;
+         rs6000_insns[V1TImode].reload_store  = CODE_FOR_reload_v1ti_si_store;
+         rs6000_insns[V1TImode].reload_load   = CODE_FOR_reload_v1ti_si_load;
+         rs6000_insns[V4SFmode].reload_store  = CODE_FOR_reload_v4sf_si_store;
+         rs6000_insns[V4SFmode].reload_load   = CODE_FOR_reload_v4sf_si_load;
+         rs6000_insns[V2DFmode].reload_store  = CODE_FOR_reload_v2df_si_store;
+         rs6000_insns[V2DFmode].reload_load   = CODE_FOR_reload_v2df_si_load;
+         rs6000_insns[DFmode].reload_store    = CODE_FOR_reload_df_si_store;
+         rs6000_insns[DFmode].reload_load     = CODE_FOR_reload_df_si_load;
+         rs6000_insns[DDmode].reload_store    = CODE_FOR_reload_dd_si_store;
+         rs6000_insns[DDmode].reload_load     = CODE_FOR_reload_dd_si_load;
+         rs6000_insns[SFmode].reload_store    = CODE_FOR_reload_sf_si_store;
+         rs6000_insns[SFmode].reload_load     = CODE_FOR_reload_sf_si_load;
 
          if (FLOAT128_VECTOR_P (KFmode))
            {
-             reg_addr[KFmode].reload_store = CODE_FOR_reload_kf_si_store;
-             reg_addr[KFmode].reload_load  = CODE_FOR_reload_kf_si_load;
+             rs6000_insns[KFmode].reload_store = CODE_FOR_reload_kf_si_store;
+             rs6000_insns[KFmode].reload_load  = CODE_FOR_reload_kf_si_load;
            }
 
          if (FLOAT128_IEEE_P (TFmode))
            {
-             reg_addr[TFmode].reload_store = CODE_FOR_reload_tf_si_store;
-             reg_addr[TFmode].reload_load  = CODE_FOR_reload_tf_si_load;
+             rs6000_insns[TFmode].reload_store = CODE_FOR_reload_tf_si_store;
+             rs6000_insns[TFmode].reload_load  = CODE_FOR_reload_tf_si_load;
            }
 
          /* Only provide a reload handler for SDmode if lfiwzx/stfiwx are
             available.  */
          if (TARGET_NO_SDMODE_STACK)
            {
-             reg_addr[SDmode].reload_store = CODE_FOR_reload_sd_si_store;
-             reg_addr[SDmode].reload_load  = CODE_FOR_reload_sd_si_load;
+             rs6000_insns[SDmode].reload_store = CODE_FOR_reload_sd_si_store;
+             rs6000_insns[SDmode].reload_load  = CODE_FOR_reload_sd_si_load;
            }
 
          if (TARGET_VSX)
            {
-             reg_addr[TImode].reload_store  = CODE_FOR_reload_ti_si_store;
-             reg_addr[TImode].reload_load   = CODE_FOR_reload_ti_si_load;
+             rs6000_insns[TImode].reload_store  = CODE_FOR_reload_ti_si_store;
+             rs6000_insns[TImode].reload_load   = CODE_FOR_reload_ti_si_load;
            }
 
          if (TARGET_DIRECT_MOVE)
            {
-             reg_addr[DImode].reload_fpr_gpr = CODE_FOR_reload_fpr_from_gprdi;
-             reg_addr[DDmode].reload_fpr_gpr = CODE_FOR_reload_fpr_from_gprdd;
-             reg_addr[DFmode].reload_fpr_gpr = CODE_FOR_reload_fpr_from_gprdf;
+             rs6000_insns[DImode].reload_fpr_gpr
+               = CODE_FOR_reload_fpr_from_gprdi;
+             rs6000_insns[DDmode].reload_fpr_gpr
+               = CODE_FOR_reload_fpr_from_gprdd;
+             rs6000_insns[DFmode].reload_fpr_gpr
+               = CODE_FOR_reload_fpr_from_gprdf;
            }
        }
 
@@ -3552,11 +3521,11 @@ rs6000_init_hard_regno_mode_ok (bool glo
   /* Setup the fusion operations.  */
   if (TARGET_P8_FUSION)
     {
-      reg_addr[QImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_qi;
-      reg_addr[HImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_hi;
-      reg_addr[SImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_si;
+      rs6000_insns[QImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_qi;
+      rs6000_insns[HImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_hi;
+      rs6000_insns[SImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_si;
       if (TARGET_64BIT)
-       reg_addr[DImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_di;
+       rs6000_insns[DImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_di;
     }
 
   if (TARGET_P9_FUSION)
@@ -3649,14 +3618,14 @@ rs6000_init_hard_regno_mode_ok (bool glo
          if (rtype == RELOAD_REG_FPR && !TARGET_HARD_FLOAT)
            continue;
 
-         reg_addr[xmode].fusion_addis_ld[rtype] = addis_insns[i].load;
-         reg_addr[xmode].fusion_addis_st[rtype] = addis_insns[i].store;
+         rs6000_insns[xmode].fusion_addis_ld[rtype] = addis_insns[i].load;
+         rs6000_insns[xmode].fusion_addis_st[rtype] = addis_insns[i].store;
 
          if (rtype == RELOAD_REG_FPR && TARGET_P9_VECTOR)
            {
-             reg_addr[xmode].fusion_addis_ld[RELOAD_REG_VMX]
+             rs6000_insns[xmode].fusion_addis_ld[RELOAD_REG_VMX]
                = addis_insns[i].load;
-             reg_addr[xmode].fusion_addis_st[RELOAD_REG_VMX]
+             rs6000_insns[xmode].fusion_addis_st[RELOAD_REG_VMX]
                = addis_insns[i].store;
            }
        }
@@ -7427,7 +7396,7 @@ rs6000_expand_vector_extract (rtx target
 }
 
 /* Helper function to return the register number of a RTX.  */
-static inline int
+int
 regno_or_subregno (rtx op)
 {
   if (REG_P (op))
@@ -8107,7 +8076,7 @@ quad_address_p (rtx addr, machine_mode m
   if (legitimate_indirect_address_p (addr, strict))
     return true;
 
-  if (VECTOR_MODE_P (mode) && !mode_supports_vsx_dform_quad (mode))
+  if (VECTOR_MODE_P (mode) && !mode_supports_dq_form (mode))
     return false;
 
   if (GET_CODE (addr) != PLUS)
@@ -8289,7 +8258,7 @@ reg_offset_addressing_ok_p (machine_mode
         IEEE 128-bit floating point that is passed in a single vector
         register.  */
       if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
-       return mode_supports_vsx_dform_quad (mode);
+       return mode_supports_dq_form (mode);
       break;
 
     case E_V2SImode:
@@ -8356,7 +8325,7 @@ offsettable_ok_by_alignment (rtx op, HOS
 
   /* ISA 3.0 vector d-form addressing is restricted, don't allow
      SYMBOL_REF.  */
-  if (mode_supports_vsx_dform_quad (mode))
+  if (mode_supports_dq_form (mode))
     return false;
 
   dsize = GET_MODE_SIZE (mode);
@@ -8527,7 +8496,7 @@ rs6000_legitimate_offset_address_p (mach
     return false;
   if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
     return false;
-  if (mode_supports_vsx_dform_quad (mode))
+  if (mode_supports_dq_form (mode))
     return quad_address_p (x, mode, strict);
   if (!reg_offset_addressing_ok_p (mode))
     return virtual_stack_registers_memory_p (x);
@@ -8645,7 +8614,7 @@ legitimate_lo_sum_address_p (machine_mod
   if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
     return false;
   /* quad word addresses are restricted, and we can't use LO_SUM.  */
-  if (mode_supports_vsx_dform_quad (mode))
+  if (mode_supports_dq_form (mode))
     return false;
   x = XEXP (x, 1);
 
@@ -8710,7 +8679,7 @@ rs6000_legitimize_address (rtx x, rtx ol
   unsigned int extra;
 
   if (!reg_offset_addressing_ok_p (mode)
-      || mode_supports_vsx_dform_quad (mode))
+      || mode_supports_dq_form (mode))
     {
       if (virtual_stack_registers_memory_p (x))
        return x;
@@ -9454,7 +9423,7 @@ rs6000_legitimize_reload_address (rtx x,
                                  int ind_levels ATTRIBUTE_UNUSED, int *win)
 {
   bool reg_offset_p = reg_offset_addressing_ok_p (mode);
-  bool quad_offset_p = mode_supports_vsx_dform_quad (mode);
+  bool quad_offset_p = mode_supports_dq_form (mode);
 
   /* Nasty hack for vsx_splat_v2df/v2di load from mem, which takes a
      DFmode/DImode MEM.  Ditto for ISA 3.0 vsx_splat_v4sf/v4si.  */
@@ -9742,7 +9711,7 @@ static bool
 rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
 {
   bool reg_offset_p = reg_offset_addressing_ok_p (mode);
-  bool quad_offset_p = mode_supports_vsx_dform_quad (mode);
+  bool quad_offset_p = mode_supports_dq_form (mode);
 
   /* If this is an unaligned stvx/ldvx type address, discard the outer AND.  */
   if (VECTOR_MEM_ALTIVEC_P (mode)
@@ -19913,7 +19882,7 @@ rs6000_secondary_reload_direct_move (enu
       if (to_type == VSX_REG_TYPE && from_type == GPR_REG_TYPE)
        {
          cost = 3;                     /* 2 mtvsrd's, 1 xxpermdi.  */
-         icode = reg_addr[mode].reload_vsx_gpr;
+         icode = rs6000_insns[mode].reload_vsx_gpr;
        }
 
       /* Handle moving 128-bit values from VSX point registers to GPRs on
@@ -19922,7 +19891,7 @@ rs6000_secondary_reload_direct_move (enu
       else if (to_type == GPR_REG_TYPE && from_type == VSX_REG_TYPE)
        {
          cost = 3;                     /* 2 mfvsrd's, 1 xxpermdi.  */
-         icode = reg_addr[mode].reload_gpr_vsx;
+         icode = rs6000_insns[mode].reload_gpr_vsx;
        }
     }
 
@@ -19931,13 +19900,13 @@ rs6000_secondary_reload_direct_move (enu
       if (to_type == GPR_REG_TYPE && from_type == VSX_REG_TYPE)
        {
          cost = 3;                     /* xscvdpspn, mfvsrd, and.  */
-         icode = reg_addr[mode].reload_gpr_vsx;
+         icode = rs6000_insns[mode].reload_gpr_vsx;
        }
 
       else if (to_type == VSX_REG_TYPE && from_type == GPR_REG_TYPE)
        {
          cost = 2;                     /* mtvsrz, xscvspdpn.  */
-         icode = reg_addr[mode].reload_vsx_gpr;
+         icode = rs6000_insns[mode].reload_vsx_gpr;
        }
     }
 
@@ -19953,7 +19922,7 @@ rs6000_secondary_reload_direct_move (enu
       if (to_type == VSX_REG_TYPE && from_type == GPR_REG_TYPE && !altivec_p)
        {
          cost = 3;                     /* 2 mtvsrwz's, 1 fmrgow.  */
-         icode = reg_addr[mode].reload_fpr_gpr;
+         icode = rs6000_insns[mode].reload_fpr_gpr;
        }
     }
 
@@ -20045,8 +20014,8 @@ rs6000_secondary_reload (bool in_p,
   sri->t_icode = CODE_FOR_nothing;
   sri->extra_cost = 0;
   icode = ((in_p)
-          ? reg_addr[mode].reload_load
-          : reg_addr[mode].reload_store);
+          ? rs6000_insns[mode].reload_load
+          : rs6000_insns[mode].reload_store);
 
   if (REG_P (x) || register_operand (x, mode))
     {
@@ -20081,7 +20050,7 @@ rs6000_secondary_reload (bool in_p,
      point register, unless we have D-form addressing.  Also make sure that
      non-zero constants use a FPR.  */
   if (!done_p && reg_addr[mode].scalar_in_vmx_p
-      && !mode_supports_vmx_dform (mode)
+      && !mode_supports_d_form (mode, RELOAD_REG_VMX)
       && (rclass == VSX_REGS || rclass == ALTIVEC_REGS)
       && (memory_p || (GET_CODE (x) == CONST_DOUBLE)))
     {
@@ -20409,7 +20378,7 @@ rs6000_secondary_reload_inner (rtx reg, 
            }
        }
 
-      else if (mode_supports_vsx_dform_quad (mode) && CONST_INT_P (op1))
+      else if (mode_supports_dq_form (mode) && CONST_INT_P (op1))
        {
          if (((addr_mask & RELOAD_REG_QUAD_OFFSET) == 0)
              || !quad_address_p (addr, mode, false))
@@ -20450,7 +20419,7 @@ rs6000_secondary_reload_inner (rtx reg, 
        }
 
       /* Quad offsets are restricted and can't handle normal addresses.  */
-      else if (mode_supports_vsx_dform_quad (mode))
+      else if (mode_supports_dq_form (mode))
        {
          emit_insn (gen_rtx_SET (scratch, addr));
          new_addr = scratch;
@@ -20644,8 +20613,8 @@ rs6000_preferred_reload_class (rtx x, en
        }
 
       /* D-form addressing can easily reload the value.  */
-      if (mode_supports_vmx_dform (mode)
-         || mode_supports_vsx_dform_quad (mode))
+      if (mode_supports_d_form (mode, RELOAD_REG_VMX)
+         || mode_supports_dq_form (mode))
        return rclass;
 
       /* If this is a scalar floating point value and we don't have D-form
@@ -20801,7 +20770,7 @@ rs6000_secondary_reload_class (enum reg_
      instead of reloading the secondary memory address for Altivec moves.  */
   if (TARGET_VSX
       && GET_MODE_SIZE (mode) < 16
-      && !mode_supports_vmx_dform (mode)
+      && !mode_supports_d_form (mode, RELOAD_REG_VMX)
       && (((rclass == GENERAL_REGS || rclass == BASE_REGS)
            && (regno >= 0 && ALTIVEC_REGNO_P (regno)))
           || ((rclass == VSX_REGS || rclass == ALTIVEC_REGS)
@@ -21048,7 +21017,7 @@ rs6000_output_move_128bit (rtx operands[
 
       else if (TARGET_VSX && dest_vsx_p)
        {
-         if (mode_supports_vsx_dform_quad (mode)
+         if (mode_supports_dq_form (mode)
              && quad_address_p (XEXP (src, 0), mode, true))
            return "lxv %x0,%1";
 
@@ -21086,7 +21055,7 @@ rs6000_output_move_128bit (rtx operands[
 
       else if (TARGET_VSX && src_vsx_p)
        {
-         if (mode_supports_vsx_dform_quad (mode)
+         if (mode_supports_dq_form (mode)
              && quad_address_p (XEXP (dest, 0), mode, true))
            return "stxv %x1,%0";
 

Reply via email to