PR90689, ICE in extract_insn on ppc64le
[platform/upstream/gcc.git] / gcc / config / rs6000 / rs6000.c
index 497a157..95cf9d6 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines used for code generation on IBM RS/6000.
-   Copyright (C) 1991-2018 Free Software Foundation, Inc.
+   Copyright (C) 1991-2019 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
    This file is part of GCC.
@@ -81,6 +81,8 @@
 #include "case-cfn-macros.h"
 #include "ppc-auxv.h"
 #include "tree-ssa-propagate.h"
+#include "tree-vrp.h"
+#include "tree-ssanames.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -1364,11 +1366,8 @@ static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree,
                                       bool, bool);
 #if TARGET_MACHO
 static void macho_branch_islands (void);
+static tree get_prev_label (tree);
 #endif
-static rtx rs6000_legitimize_reload_address (rtx, machine_mode, int, int,
-                                            int, int *);
-static rtx rs6000_debug_legitimize_reload_address (rtx, machine_mode, int,
-                                                  int, int, int *);
 static bool rs6000_mode_dependent_address (const_rtx);
 static bool rs6000_debug_mode_dependent_address (const_rtx);
 static bool rs6000_offsettable_memref_p (rtx, machine_mode, bool);
@@ -1389,10 +1388,6 @@ static bool rs6000_debug_can_change_mode_class (machine_mode,
 static bool rs6000_save_toc_in_prologue_p (void);
 static rtx rs6000_internal_arg_pointer (void);
 
-rtx (*rs6000_legitimize_reload_address_ptr) (rtx, machine_mode, int, int,
-                                            int, int *)
-  = rs6000_legitimize_reload_address;
-
 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
   = rs6000_mode_dependent_address;
 
@@ -1461,53 +1456,53 @@ static GTY (()) hash_table<builtin_hasher> *builtin_hash_table;
 /* Default register names.  */
 char rs6000_reg_names[][8] =
 {
+  /* GPRs */
+      "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
+      "8",  "9", "10", "11", "12", "13", "14", "15",
+     "16", "17", "18", "19", "20", "21", "22", "23",
+     "24", "25", "26", "27", "28", "29", "30", "31",
+  /* FPRs */
       "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
       "8",  "9", "10", "11", "12", "13", "14", "15",
      "16", "17", "18", "19", "20", "21", "22", "23",
      "24", "25", "26", "27", "28", "29", "30", "31",
+  /* VRs */
       "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
       "8",  "9", "10", "11", "12", "13", "14", "15",
      "16", "17", "18", "19", "20", "21", "22", "23",
      "24", "25", "26", "27", "28", "29", "30", "31",
-     "mq", "lr", "ctr","ap",
+  /* lr ctr ca ap */
+     "lr", "ctr", "ca", "ap",
+  /* cr0..cr7 */
       "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
-      "ca",
-      /* AltiVec registers.  */
-      "0",  "1",  "2",  "3",  "4",  "5",  "6", "7",
-      "8",  "9",  "10", "11", "12", "13", "14", "15",
-      "16", "17", "18", "19", "20", "21", "22", "23",
-      "24", "25", "26", "27", "28", "29", "30", "31",
-      "vrsave", "vscr",
-      /* Soft frame pointer.  */
-      "sfp",
-      /* HTM SPR registers.  */
-      "tfhar", "tfiar", "texasr"
+  /* vrsave vscr sfp */
+      "vrsave", "vscr", "sfp",
 };
 
 #ifdef TARGET_REGNAMES
 static const char alt_reg_names[][8] =
 {
-   "%r0",   "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
-   "%r8",   "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
-  "%r16",  "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
-  "%r24",  "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
-   "%f0",   "%f1",  "%f2",  "%f3",  "%f4",  "%f5",  "%f6",  "%f7",
-   "%f8",   "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
-  "%f16",  "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
-  "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
-    "mq",    "lr",  "ctr",   "ap",
-  "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
-   "ca",
-  /* AltiVec registers.  */
-   "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",
+  /* GPRs */
+   "%r0",  "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
+   "%r8",  "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
+  "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
+  "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
+  /* FPRs */
+   "%f0",  "%f1",  "%f2",  "%f3",  "%f4",  "%f5",  "%f6",  "%f7",
+   "%f8",  "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
+  "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
+  "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
+  /* VRs */
+   "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6",  "%v7",
    "%v8",  "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
   "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
   "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
-  "vrsave", "vscr",
-  /* Soft frame pointer.  */
-  "sfp",
-  /* HTM SPR registers.  */
-  "tfhar", "tfiar", "texasr"
+  /* lr ctr ca ap */
+    "lr",  "ctr",   "ca",   "ap",
+  /* cr0..cr7 */
+  "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
+  /* vrsave vscr sfp */
+  "vrsave", "vscr", "sfp",
 };
 #endif
 
@@ -1734,6 +1729,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
 #undef TARGET_MEMORY_MOVE_COST
 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
+#undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS
+#define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS \
+  rs6000_ira_change_pseudo_allocno_class
 #undef TARGET_CANNOT_COPY_INSN_P
 #define TARGET_CANNOT_COPY_INSN_P rs6000_cannot_copy_insn_p
 #undef TARGET_RTX_COSTS
@@ -2196,7 +2194,8 @@ rs6000_modes_tieable_p (machine_mode mode1, machine_mode mode2)
 /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  */
 
 static bool
-rs6000_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode)
+rs6000_hard_regno_call_part_clobbered (rtx_insn *insn ATTRIBUTE_UNUSED,
+                                      unsigned int regno, machine_mode mode)
 {
   if (TARGET_32BIT
       && TARGET_POWERPC64
@@ -2509,67 +2508,37 @@ rs6000_debug_reg_global (void)
           "f  reg_class = %s\n"
           "v  reg_class = %s\n"
           "wa reg_class = %s\n"
-          "wb reg_class = %s\n"
           "wd reg_class = %s\n"
           "we reg_class = %s\n"
           "wf reg_class = %s\n"
-          "wg reg_class = %s\n"
-          "wh reg_class = %s\n"
           "wi reg_class = %s\n"
-          "wj reg_class = %s\n"
-          "wk reg_class = %s\n"
-          "wl reg_class = %s\n"
-          "wm reg_class = %s\n"
-          "wo reg_class = %s\n"
           "wp reg_class = %s\n"
           "wq reg_class = %s\n"
           "wr reg_class = %s\n"
           "ws reg_class = %s\n"
           "wt reg_class = %s\n"
-          "wu reg_class = %s\n"
           "wv reg_class = %s\n"
           "ww reg_class = %s\n"
           "wx reg_class = %s\n"
-          "wy reg_class = %s\n"
-          "wz reg_class = %s\n"
           "wA reg_class = %s\n"
-          "wH reg_class = %s\n"
-          "wI reg_class = %s\n"
-          "wJ reg_class = %s\n"
-          "wK reg_class = %s\n"
           "\n",
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wb]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_we]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wg]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wh]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wi]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wj]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wk]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wl]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wm]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wo]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wp]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wq]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wr]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wt]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wu]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wv]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ww]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wx]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wy]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wz]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wA]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wH]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wI]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wJ]],
-          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wK]]);
+          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wA]]);
 
   nl = "\n";
   for (m = 0; m < NUM_MACHINE_MODES; ++m)
@@ -2992,7 +2961,7 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
   for (r = 32; r < 64; ++r)
     rs6000_regno_regclass[r] = FLOAT_REGS;
 
-  for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
+  for (r = 64; HARD_REGISTER_NUM_P (r); ++r)
     rs6000_regno_regclass[r] = NO_REGS;
 
   for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
@@ -3007,9 +2976,6 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
   rs6000_regno_regclass[CA_REGNO] = NO_REGS;
   rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
   rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
-  rs6000_regno_regclass[TFHAR_REGNO] = SPR_REGS;
-  rs6000_regno_regclass[TFIAR_REGNO] = SPR_REGS;
-  rs6000_regno_regclass[TEXASR_REGNO] = SPR_REGS;
   rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
   rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
 
@@ -3046,7 +3012,7 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
      below.  */
   gcc_assert ((int)VECTOR_NONE == 0);
   memset ((void *) &rs6000_vector_unit[0], '\0', sizeof (rs6000_vector_unit));
-  memset ((void *) &rs6000_vector_mem[0], '\0', sizeof (rs6000_vector_unit));
+  memset ((void *) &rs6000_vector_mem[0], '\0', sizeof (rs6000_vector_mem));
 
   gcc_assert ((int)CODE_FOR_nothing == 0);
   memset ((void *) &reg_addr[0], '\0', sizeof (reg_addr));
@@ -3182,27 +3148,14 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
        wc - Reserved to represent individual CR bits (used in LLVM).
        wd - Preferred register class for V2DFmode.
        wf - Preferred register class for V4SFmode.
-       wg - Float register for power6x move insns.
-       wh - FP register for direct move instructions.
        wi - FP or VSX register to hold 64-bit integers for VSX insns.
-       wj - FP or VSX register to hold 64-bit integers for direct moves.
-       wk - FP or VSX register to hold 64-bit doubles for direct moves.
-       wl - Float register if we can do 32-bit signed int loads.
-       wm - VSX register for ISA 2.07 direct move operations.
        wn - always NO_REGS.
        wr - GPR if 64-bit mode is permitted.
        ws - Register class to do ISA 2.06 DF operations.
        wt - VSX register for TImode in VSX registers.
-       wu - Altivec register for ISA 2.07 VSX SF/SI load/stores.
        wv - Altivec register for ISA 2.06 VSX DF/DI load/stores.
        ww - Register class to do SF conversions in with VSX operations.
-       wx - Float register if we can do 32-bit int stores.
-       wy - Register class to do ISA 2.07 SF operations.
-       wz - Float register if we can do 32-bit unsigned int loads.
-       wH - Altivec register if SImode is allowed in VSX registers.
-       wI - VSX register if SImode is allowed in VSX registers.
-       wJ - VSX register if QImode/HImode are allowed in VSX registers.
-       wK - Altivec register if QImode/HImode are allowed in VSX registers.  */
+       wx - Float register if we can do 32-bit int stores.  */
 
   if (TARGET_HARD_FLOAT)
     {
@@ -3226,22 +3179,6 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
   if (TARGET_ALTIVEC)
     rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
 
-  if (TARGET_MFPGPR)                                           /* DFmode  */
-    rs6000_constraints[RS6000_CONSTRAINT_wg] = FLOAT_REGS;
-
-  if (TARGET_LFIWAX)
-    rs6000_constraints[RS6000_CONSTRAINT_wl] = FLOAT_REGS;     /* DImode  */
-
-  if (TARGET_DIRECT_MOVE)
-    {
-      rs6000_constraints[RS6000_CONSTRAINT_wh] = FLOAT_REGS;
-      rs6000_constraints[RS6000_CONSTRAINT_wj]                 /* DImode  */
-       = rs6000_constraints[RS6000_CONSTRAINT_wi];
-      rs6000_constraints[RS6000_CONSTRAINT_wk]                 /* DFmode  */
-       = rs6000_constraints[RS6000_CONSTRAINT_ws];
-      rs6000_constraints[RS6000_CONSTRAINT_wm] = VSX_REGS;
-    }
-
   if (TARGET_POWERPC64)
     {
       rs6000_constraints[RS6000_CONSTRAINT_wr] = GENERAL_REGS;
@@ -3249,20 +3186,13 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
     }
 
   if (TARGET_P8_VECTOR)                                                /* SFmode  */
-    {
-      rs6000_constraints[RS6000_CONSTRAINT_wu] = ALTIVEC_REGS;
-      rs6000_constraints[RS6000_CONSTRAINT_wy] = VSX_REGS;
-      rs6000_constraints[RS6000_CONSTRAINT_ww] = VSX_REGS;
-    }
+    rs6000_constraints[RS6000_CONSTRAINT_ww] = VSX_REGS;
   else if (TARGET_VSX)
     rs6000_constraints[RS6000_CONSTRAINT_ww] = FLOAT_REGS;
 
   if (TARGET_STFIWX)
     rs6000_constraints[RS6000_CONSTRAINT_wx] = FLOAT_REGS;     /* DImode  */
 
-  if (TARGET_LFIWZX)
-    rs6000_constraints[RS6000_CONSTRAINT_wz] = FLOAT_REGS;     /* DImode  */
-
   if (TARGET_FLOAT128_TYPE)
     {
       rs6000_constraints[RS6000_CONSTRAINT_wq] = VSX_REGS;     /* KFmode  */
@@ -3270,31 +3200,10 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
        rs6000_constraints[RS6000_CONSTRAINT_wp] = VSX_REGS;    /* TFmode  */
     }
 
-  if (TARGET_P9_VECTOR)
-    {
-      /* Support for new D-form instructions.  */
-      rs6000_constraints[RS6000_CONSTRAINT_wb] = ALTIVEC_REGS;
-
-      /* Support for ISA 3.0 (power9) vectors.  */
-      rs6000_constraints[RS6000_CONSTRAINT_wo] = VSX_REGS;
-    }
-
   /* Support for new direct moves (ISA 3.0 + 64bit).  */
   if (TARGET_DIRECT_MOVE_128)
     rs6000_constraints[RS6000_CONSTRAINT_we] = VSX_REGS;
 
-  /* Support small integers in VSX registers.  */
-  if (TARGET_P8_VECTOR)
-    {
-      rs6000_constraints[RS6000_CONSTRAINT_wH] = ALTIVEC_REGS;
-      rs6000_constraints[RS6000_CONSTRAINT_wI] = FLOAT_REGS;
-      if (TARGET_P9_VECTOR)
-       {
-         rs6000_constraints[RS6000_CONSTRAINT_wJ] = FLOAT_REGS;
-         rs6000_constraints[RS6000_CONSTRAINT_wK] = ALTIVEC_REGS;
-       }
-    }
-
   /* Set up the reload helper and direct move functions.  */
   if (TARGET_VSX || TARGET_ALTIVEC)
     {
@@ -3456,16 +3365,16 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
     }
 
   /* Precalculate HARD_REGNO_NREGS.  */
-  for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
+  for (r = 0; HARD_REGISTER_NUM_P (r); ++r)
     for (m = 0; m < NUM_MACHINE_MODES; ++m)
       rs6000_hard_regno_nregs[m][r]
-       = rs6000_hard_regno_nregs_internal (r, (machine_mode)m);
+       = rs6000_hard_regno_nregs_internal (r, (machine_mode) m);
 
   /* Precalculate TARGET_HARD_REGNO_MODE_OK.  */
-  for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
+  for (r = 0; HARD_REGISTER_NUM_P (r); ++r)
     for (m = 0; m < NUM_MACHINE_MODES; ++m)
-      if (rs6000_hard_regno_mode_ok_uncached (r, (machine_mode)m))
-       rs6000_hard_regno_mode_ok_p[m][r] = true;
+      rs6000_hard_regno_mode_ok_p[m][r]
+       = rs6000_hard_regno_mode_ok_uncached (r, (machine_mode) m);
 
   /* Precalculate CLASS_MAX_NREGS sizes.  */
   for (c = 0; c < LIM_REG_CLASSES; ++c)
@@ -3865,6 +3774,9 @@ rs6000_option_override_internal (bool global_init_p)
   /* Don't override by the processor default if given explicitly.  */
   set_masks &= ~rs6000_isa_flags_explicit;
 
+  if (global_init_p && rs6000_dejagnu_cpu_index >= 0)
+    rs6000_cpu_index = rs6000_dejagnu_cpu_index;
+
   /* Process the -mcpu=<xxx> and -mtune=<xxx> argument.  If the user changed
      the cpu in a target attribute or pragma, but did not specify a tuning
      option, use the cpu for the tuning option rather than the option specified
@@ -3985,7 +3897,7 @@ rs6000_option_override_internal (bool global_init_p)
       if (!TARGET_HARD_FLOAT)
        {
          if (rs6000_isa_flags_explicit & OPTION_MASK_VSX)
-           msg = N_("-mvsx requires hardware floating point");
+           msg = N_("%<-mvsx%> requires hardware floating point");
          else
            {
              rs6000_isa_flags &= ~ OPTION_MASK_VSX;
@@ -3993,14 +3905,14 @@ rs6000_option_override_internal (bool global_init_p)
            }
        }
       else if (TARGET_AVOID_XFORM > 0)
-       msg = N_("-mvsx needs indexed addressing");
+       msg = N_("%<-mvsx%> needs indexed addressing");
       else if (!TARGET_ALTIVEC && (rs6000_isa_flags_explicit
                                   & OPTION_MASK_ALTIVEC))
         {
          if (rs6000_isa_flags_explicit & OPTION_MASK_VSX)
-           msg = N_("-mvsx and -mno-altivec are incompatible");
+           msg = N_("%<-mvsx%> and %<-mno-altivec%> are incompatible");
          else
-           msg = N_("-mno-altivec disables vsx");
+           msg = N_("%<-mno-altivec%> disables vsx");
         }
 
       if (msg)
@@ -4126,10 +4038,10 @@ rs6000_option_override_internal (bool global_init_p)
   if ((TARGET_QUAD_MEMORY || TARGET_QUAD_MEMORY_ATOMIC) && !TARGET_POWERPC64)
     {
       if ((rs6000_isa_flags_explicit & OPTION_MASK_QUAD_MEMORY) != 0)
-       warning (0, N_("-mquad-memory requires 64-bit mode"));
+       warning (0, N_("%<-mquad-memory%> requires 64-bit mode"));
 
       if ((rs6000_isa_flags_explicit & OPTION_MASK_QUAD_MEMORY_ATOMIC) != 0)
-       warning (0, N_("-mquad-memory-atomic requires 64-bit mode"));
+       warning (0, N_("%<-mquad-memory-atomic%> requires 64-bit mode"));
 
       rs6000_isa_flags &= ~(OPTION_MASK_QUAD_MEMORY
                            | OPTION_MASK_QUAD_MEMORY_ATOMIC);
@@ -4141,7 +4053,7 @@ rs6000_option_override_internal (bool global_init_p)
   if (TARGET_QUAD_MEMORY && !WORDS_BIG_ENDIAN)
     {
       if ((rs6000_isa_flags_explicit & OPTION_MASK_QUAD_MEMORY) != 0)
-       warning (0, N_("-mquad-memory is not available in little endian "
+       warning (0, N_("%<-mquad-memory%> is not available in little endian "
                       "mode"));
 
       rs6000_isa_flags &= ~OPTION_MASK_QUAD_MEMORY;
@@ -4276,12 +4188,19 @@ rs6000_option_override_internal (bool global_init_p)
       if (main_target_opt != NULL
          && (main_target_opt->x_rs6000_long_double_type_size
              != default_long_double_size))
-       error ("target attribute or pragma changes long double size");
+       error ("target attribute or pragma changes %<long double%> size");
       else
        rs6000_long_double_type_size = default_long_double_size;
     }
   else if (rs6000_long_double_type_size == 128)
     rs6000_long_double_type_size = FLOAT_PRECISION_TFmode;
+  else if (global_options_set.x_rs6000_ieeequad)
+    {
+      if (global_options.x_rs6000_ieeequad)
+       error ("%qs requires %qs", "-mabi=ieeelongdouble", "-mlong-double-128");
+      else
+       error ("%qs requires %qs", "-mabi=ibmlongdouble", "-mlong-double-128");
+    }
 
   /* Set -mabi=ieeelongdouble on some old targets.  In the future, power server
      systems will also set long double to be IEEE 128-bit.  AIX and Darwin
@@ -4291,16 +4210,25 @@ rs6000_option_override_internal (bool global_init_p)
   if (!global_options_set.x_rs6000_ieeequad)
     rs6000_ieeequad = TARGET_IEEEQUAD_DEFAULT;
 
-  else if (rs6000_ieeequad != TARGET_IEEEQUAD_DEFAULT && TARGET_LONG_DOUBLE_128)
+  else
     {
-      static bool warned_change_long_double;
-      if (!warned_change_long_double)
+      if (global_options.x_rs6000_ieeequad
+         && (!TARGET_POPCNTD || !TARGET_VSX))
+       error ("%qs requires full ISA 2.06 support", "-mabi=ieeelongdouble");
+
+      if (rs6000_ieeequad != TARGET_IEEEQUAD_DEFAULT && TARGET_LONG_DOUBLE_128)
        {
-         warned_change_long_double = true;
-         if (TARGET_IEEEQUAD)
-           warning (OPT_Wpsabi, "Using IEEE extended precision long double");
-         else
-           warning (OPT_Wpsabi, "Using IBM extended precision long double");
+         static bool warned_change_long_double;
+         if (!warned_change_long_double)
+           {
+             warned_change_long_double = true;
+             if (TARGET_IEEEQUAD)
+               warning (OPT_Wpsabi, "Using IEEE extended precision "
+                        "%<long double%>");
+             else
+               warning (OPT_Wpsabi, "Using IBM extended precision "
+                        "%<long double%>");
+           }
        }
     }
 
@@ -4317,7 +4245,7 @@ rs6000_option_override_internal (bool global_init_p)
       if (!TARGET_VSX)
        {
          if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_KEYWORD) != 0)
-           error ("%qs requires VSX support", "-mfloat128");
+           error ("%qs requires VSX support", "%<-mfloat128%>");
 
          TARGET_FLOAT128_TYPE = 0;
          rs6000_isa_flags &= ~(OPTION_MASK_FLOAT128_KEYWORD
@@ -4326,7 +4254,7 @@ rs6000_option_override_internal (bool global_init_p)
       else if (!TARGET_FLOAT128_TYPE)
        {
          TARGET_FLOAT128_TYPE = 1;
-         warning (0, "The -mfloat128 option may not be fully supported");
+         warning (0, "The %<-mfloat128%> option may not be fully supported");
        }
     }
 
@@ -4349,7 +4277,7 @@ rs6000_option_override_internal (bool global_init_p)
       && (rs6000_isa_flags & ISA_3_0_MASKS_IEEE) != ISA_3_0_MASKS_IEEE)
     {
       if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW) != 0)
-       error ("%qs requires full ISA 3.0 support", "-mfloat128-hardware");
+       error ("%qs requires full ISA 3.0 support", "%<-mfloat128-hardware%>");
 
       rs6000_isa_flags &= ~OPTION_MASK_FLOAT128_HW;
     }
@@ -4357,11 +4285,29 @@ rs6000_option_override_internal (bool global_init_p)
   if (TARGET_FLOAT128_HW && !TARGET_64BIT)
     {
       if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128_HW) != 0)
-       error ("%qs requires %qs", "-mfloat128-hardware", "-m64");
+       error ("%qs requires %qs", "%<-mfloat128-hardware%>", "-m64");
 
       rs6000_isa_flags &= ~OPTION_MASK_FLOAT128_HW;
     }
 
+  /* -mpcrel requires prefixed load/store addressing.  */
+  if (TARGET_PCREL && !TARGET_PREFIXED_ADDR)
+    {
+      if ((rs6000_isa_flags_explicit & OPTION_MASK_PCREL) != 0)
+       error ("%qs requires %qs", "-mpcrel", "-mprefixed-addr");
+
+      rs6000_isa_flags &= ~OPTION_MASK_PCREL;
+    }
+
+  /* -mprefixed-addr (and hence -mpcrel) requires -mcpu=future.  */
+  if (TARGET_PREFIXED_ADDR && !TARGET_FUTURE)
+    {
+      if ((rs6000_isa_flags_explicit & OPTION_MASK_PCREL) != 0)
+       error ("%qs requires %qs", "-mprefixed-addr", "-mcpu=future");
+
+      rs6000_isa_flags &= ~(OPTION_MASK_PCREL | OPTION_MASK_PREFIXED_ADDR);
+    }
+
   /* Print the options after updating the defaults.  */
   if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
     rs6000_print_isa_options (stderr, 0, "after defaults", rs6000_isa_flags);
@@ -4404,8 +4350,6 @@ rs6000_option_override_internal (bool global_init_p)
            = rs6000_debug_can_change_mode_class;
          rs6000_preferred_reload_class_ptr
            = rs6000_debug_preferred_reload_class;
-         rs6000_legitimize_reload_address_ptr
-           = rs6000_debug_legitimize_reload_address;
          rs6000_mode_dependent_address_ptr
            = rs6000_debug_mode_dependent_address;
        }
@@ -4504,6 +4448,7 @@ rs6000_option_override_internal (bool global_init_p)
                        && rs6000_tune != PROCESSOR_POWER7
                        && rs6000_tune != PROCESSOR_POWER8
                        && rs6000_tune != PROCESSOR_POWER9
+                       && rs6000_tune != PROCESSOR_FUTURE
                        && rs6000_tune != PROCESSOR_PPCA2
                        && rs6000_tune != PROCESSOR_CELL
                        && rs6000_tune != PROCESSOR_PPC476);
@@ -4517,6 +4462,7 @@ rs6000_option_override_internal (bool global_init_p)
                                 || rs6000_tune == PROCESSOR_POWER7
                                 || rs6000_tune == PROCESSOR_POWER8
                                 || rs6000_tune == PROCESSOR_POWER9
+                                || rs6000_tune == PROCESSOR_FUTURE
                                 || rs6000_tune == PROCESSOR_PPCE500MC
                                 || rs6000_tune == PROCESSOR_PPCE500MC64
                                 || rs6000_tune == PROCESSOR_PPCE5500
@@ -4817,6 +4763,7 @@ rs6000_option_override_internal (bool global_init_p)
        break;
 
       case PROCESSOR_POWER9:
+      case PROCESSOR_FUTURE:
        rs6000_cost = &power9_cost;
        break;
 
@@ -5700,6 +5647,39 @@ rs6000_builtin_md_vectorized_function (tree fndecl, tree type_out,
 /* Default CPU string for rs6000*_file_start functions.  */
 static const char *rs6000_default_cpu;
 
+#ifdef USING_ELFOS_H
+static const char *rs6000_machine;
+
+static const char *
+rs6000_machine_from_flags (void)
+{
+  if ((rs6000_isa_flags & (ISA_FUTURE_MASKS_SERVER & ~ISA_3_0_MASKS_SERVER))
+      != 0)
+    return "future";
+  if ((rs6000_isa_flags & (ISA_3_0_MASKS_SERVER & ~ISA_2_7_MASKS_SERVER)) != 0)
+    return "power9";
+  if ((rs6000_isa_flags & (ISA_2_7_MASKS_SERVER & ~ISA_2_6_MASKS_SERVER)) != 0)
+    return "power8";
+  if ((rs6000_isa_flags & (ISA_2_6_MASKS_SERVER & ~ISA_2_5_MASKS_SERVER)) != 0)
+    return "power7";
+  if ((rs6000_isa_flags & (ISA_2_5_MASKS_SERVER & ~ISA_2_4_MASKS)) != 0)
+    return "power6";
+  if ((rs6000_isa_flags & (ISA_2_4_MASKS & ~ISA_2_1_MASKS)) != 0)
+    return "power5";
+  if ((rs6000_isa_flags & ISA_2_1_MASKS) != 0)
+    return "power4";
+  if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) != 0)
+    return "ppc64";
+  return "ppc";
+}
+
+static void
+emit_asm_machine (void)
+{
+  fprintf (asm_out_file, "\t.machine %s\n", rs6000_machine);
+}
+#endif
+
 /* Do anything needed at the start of the asm file.  */
 
 static void
@@ -5765,27 +5745,10 @@ rs6000_file_start (void)
     }
 
 #ifdef USING_ELFOS_H
+  rs6000_machine = rs6000_machine_from_flags ();
   if (!(rs6000_default_cpu && rs6000_default_cpu[0])
       && !global_options_set.x_rs6000_cpu_index)
-    {
-      fputs ("\t.machine ", asm_out_file);
-      if ((rs6000_isa_flags & OPTION_MASK_MODULO) != 0)
-       fputs ("power9\n", asm_out_file);
-      else if ((rs6000_isa_flags & OPTION_MASK_DIRECT_MOVE) != 0)
-       fputs ("power8\n", asm_out_file);
-      else if ((rs6000_isa_flags & OPTION_MASK_POPCNTD) != 0)
-       fputs ("power7\n", asm_out_file);
-      else if ((rs6000_isa_flags & OPTION_MASK_CMPB) != 0)
-       fputs ("power6\n", asm_out_file);
-      else if ((rs6000_isa_flags & OPTION_MASK_POPCNTB) != 0)
-       fputs ("power5\n", asm_out_file);
-      else if ((rs6000_isa_flags & OPTION_MASK_MFCRF) != 0)
-       fputs ("power4\n", asm_out_file);
-      else if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) != 0)
-       fputs ("ppc64\n", asm_out_file);
-      else
-       fputs ("ppc\n", asm_out_file);
-    }
+    emit_asm_machine ();
 #endif
 
   if (DEFAULT_ABI == ABI_ELFv2)
@@ -5815,11 +5778,12 @@ direct_return (void)
   return 0;
 }
 
-/* Return the number of instructions it takes to form a constant in an
-   integer register.  */
+/* Helper for num_insns_constant.  Calculate number of instructions to
+   load VALUE to a single gpr using combinations of addi, addis, ori,
+   oris and sldi instructions.  */
 
-int
-num_insns_constant_wide (HOST_WIDE_INT value)
+static int
+num_insns_constant_gpr (HOST_WIDE_INT value)
 {
   /* signed constant loadable with addi */
   if (((unsigned HOST_WIDE_INT) value + 0x8000) < 0x10000)
@@ -5841,85 +5805,127 @@ num_insns_constant_wide (HOST_WIDE_INT value)
       high >>= 1;
 
       if (low == 0)
-       return num_insns_constant_wide (high) + 1;
+       return num_insns_constant_gpr (high) + 1;
       else if (high == 0)
-       return num_insns_constant_wide (low) + 1;
+       return num_insns_constant_gpr (low) + 1;
       else
-       return (num_insns_constant_wide (high)
-               + num_insns_constant_wide (low) + 1);
+       return (num_insns_constant_gpr (high)
+               + num_insns_constant_gpr (low) + 1);
     }
 
   else
     return 2;
 }
 
+/* Helper for num_insns_constant.  Allow constants formed by the
+   num_insns_constant_gpr sequences, plus li -1, rldicl/rldicr/rlwinm,
+   and handle modes that require multiple gprs.  */
+
+static int
+num_insns_constant_multi (HOST_WIDE_INT value, machine_mode mode)
+{
+  int nregs = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+  int total = 0;
+  while (nregs-- > 0)
+    {
+      HOST_WIDE_INT low = sext_hwi (value, BITS_PER_WORD);
+      int insns = num_insns_constant_gpr (low);
+      if (insns > 2
+         /* We won't get more than 2 from num_insns_constant_gpr
+            except when TARGET_POWERPC64 and mode is DImode or
+            wider, so the register mode must be DImode.  */
+         && rs6000_is_valid_and_mask (GEN_INT (low), DImode))
+       insns = 2;
+      total += insns;
+      value >>= BITS_PER_WORD;
+    }
+  return total;
+}
+
+/* Return the number of instructions it takes to form a constant in as
+   many gprs are needed for MODE.  */
+
 int
 num_insns_constant (rtx op, machine_mode mode)
 {
-  HOST_WIDE_INT low, high;
+  HOST_WIDE_INT val;
 
   switch (GET_CODE (op))
     {
     case CONST_INT:
-      if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
-         && rs6000_is_valid_and_mask (op, mode))
-       return 2;
-      else
-       return num_insns_constant_wide (INTVAL (op));
+      val = INTVAL (op);
+      break;
 
     case CONST_WIDE_INT:
       {
-       int i;
-       int ins = CONST_WIDE_INT_NUNITS (op) - 1;
-       for (i = 0; i < CONST_WIDE_INT_NUNITS (op); i++)
-         ins += num_insns_constant_wide (CONST_WIDE_INT_ELT (op, i));
-       return ins;
+       int insns = 0;
+       for (int i = 0; i < CONST_WIDE_INT_NUNITS (op); i++)
+         insns += num_insns_constant_multi (CONST_WIDE_INT_ELT (op, i),
+                                            DImode);
+       return insns;
       }
 
-      case CONST_DOUBLE:
+    case CONST_DOUBLE:
+      {
+       const struct real_value *rv = CONST_DOUBLE_REAL_VALUE (op);
+
        if (mode == SFmode || mode == SDmode)
          {
            long l;
 
-           if (DECIMAL_FLOAT_MODE_P (mode))
-             REAL_VALUE_TO_TARGET_DECIMAL32
-               (*CONST_DOUBLE_REAL_VALUE (op), l);
+           if (mode == SDmode)
+             REAL_VALUE_TO_TARGET_DECIMAL32 (*rv, l);
            else
-             REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), l);
-           return num_insns_constant_wide ((HOST_WIDE_INT) l);
+             REAL_VALUE_TO_TARGET_SINGLE (*rv, l);
+           /* See the first define_split in rs6000.md handling a
+              const_double_operand.  */
+           val = l;
+           mode = SImode;
          }
-
-       long l[2];
-       if (DECIMAL_FLOAT_MODE_P (mode))
-         REAL_VALUE_TO_TARGET_DECIMAL64 (*CONST_DOUBLE_REAL_VALUE (op), l);
-       else
-         REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op), l);
-       high = l[WORDS_BIG_ENDIAN == 0];
-       low  = l[WORDS_BIG_ENDIAN != 0];
-
-       if (TARGET_32BIT)
-         return (num_insns_constant_wide (low)
-                 + num_insns_constant_wide (high));
-       else
+       else if (mode == DFmode || mode == DDmode)
          {
-           if ((high == 0 && low >= 0)
-               || (high == -1 && low < 0))
-             return num_insns_constant_wide (low);
+           long l[2];
 
-           else if (rs6000_is_valid_and_mask (op, mode))
-             return 2;
+           if (mode == DDmode)
+             REAL_VALUE_TO_TARGET_DECIMAL64 (*rv, l);
+           else
+             REAL_VALUE_TO_TARGET_DOUBLE (*rv, l);
 
-           else if (low == 0)
-             return num_insns_constant_wide (high) + 1;
+           /* See the second (32-bit) and third (64-bit) define_split
+              in rs6000.md handling a const_double_operand.  */
+           val = (unsigned HOST_WIDE_INT) l[WORDS_BIG_ENDIAN ? 0 : 1] << 32;
+           val |= l[WORDS_BIG_ENDIAN ? 1 : 0] & 0xffffffffUL;
+           mode = DImode;
+         }
+       else if (mode == TFmode || mode == TDmode
+                || mode == KFmode || mode == IFmode)
+         {
+           long l[4];
+           int insns;
 
+           if (mode == TDmode)
+             REAL_VALUE_TO_TARGET_DECIMAL128 (*rv, l);
            else
-             return (num_insns_constant_wide (high)
-                     + num_insns_constant_wide (low) + 1);
+             REAL_VALUE_TO_TARGET_LONG_DOUBLE (*rv, l);
+
+           val = (unsigned HOST_WIDE_INT) l[WORDS_BIG_ENDIAN ? 0 : 3] << 32;
+           val |= l[WORDS_BIG_ENDIAN ? 1 : 2] & 0xffffffffUL;
+           insns = num_insns_constant_multi (val, DImode);
+           val = (unsigned HOST_WIDE_INT) l[WORDS_BIG_ENDIAN ? 2 : 1] << 32;
+           val |= l[WORDS_BIG_ENDIAN ? 3 : 0] & 0xffffffffUL;
+           insns += num_insns_constant_multi (val, DImode);
+           return insns;
          }
+       else
+         gcc_unreachable ();
+      }
+      break;
 
     default:
       gcc_unreachable ();
     }
+
+  return num_insns_constant_multi (val, mode);
 }
 
 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
@@ -6137,8 +6143,8 @@ easy_altivec_constant (rtx op, machine_mode mode)
 
   else if (mode == V2DImode)
     {
-      if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
-         || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
+      if (!CONST_INT_P (CONST_VECTOR_ELT (op, 0))
+         || !CONST_INT_P (CONST_VECTOR_ELT (op, 1)))
        return false;
 
       if (zero_constant (op, mode))
@@ -6830,7 +6836,6 @@ rs6000_expand_vector_extract (rtx target, rtx vec, rtx elt)
        default:
          break;
        case E_V1TImode:
-         gcc_assert (INTVAL (elt) == 0 && inner_mode == TImode);
          emit_move_insn (target, gen_lowpart (TImode, vec));
          break;
        case E_V2DFmode:
@@ -6881,6 +6886,10 @@ rs6000_expand_vector_extract (rtx target, rtx vec, rtx elt)
 
       switch (mode)
        {
+       case E_V1TImode:
+         emit_move_insn (target, gen_lowpart (TImode, vec));
+         return;
+
        case E_V2DFmode:
          emit_insn (gen_vsx_extract_v2df_var (target, vec, elt));
          return;
@@ -6910,30 +6919,32 @@ rs6000_expand_vector_extract (rtx target, rtx vec, rtx elt)
        }
     }
 
-  gcc_assert (CONST_INT_P (elt));
-
   /* Allocate mode-sized buffer.  */
   mem = assign_stack_temp (mode, GET_MODE_SIZE (mode));
 
   emit_move_insn (mem, vec);
+  if (CONST_INT_P (elt))
+    {
+      int modulo_elt = INTVAL (elt) % GET_MODE_NUNITS (mode);
 
-  /* Add offset to field within buffer matching vector element.  */
-  mem = adjust_address_nv (mem, inner_mode,
-                          INTVAL (elt) * GET_MODE_SIZE (inner_mode));
-
-  emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
-}
-
-/* Helper function to return the register number of a RTX.  */
-static inline int
-regno_or_subregno (rtx op)
-{
-  if (REG_P (op))
-    return REGNO (op);
-  else if (SUBREG_P (op))
-    return subreg_regno (op);
+      /* Add offset to field within buffer matching vector element.  */
+      mem = adjust_address_nv (mem, inner_mode,
+                              modulo_elt * GET_MODE_SIZE (inner_mode));
+      emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
+    }
   else
-    gcc_unreachable ();
+    {
+      unsigned int ele_size = GET_MODE_SIZE (inner_mode);
+      rtx num_ele_m1 = GEN_INT (GET_MODE_NUNITS (mode) - 1);
+      rtx new_addr = gen_reg_rtx (Pmode);
+
+      elt = gen_rtx_AND (Pmode, elt, num_ele_m1);
+      if (ele_size > 1)
+       elt = gen_rtx_MULT (Pmode, elt, GEN_INT (ele_size));
+      new_addr = gen_rtx_PLUS (Pmode, XEXP (mem, 0), elt);
+      new_addr = change_address (mem, inner_mode, new_addr);
+      emit_move_insn (target, new_addr);
+    }
 }
 
 /* Adjust a memory address (MEM) of a vector type to point to a scalar field
@@ -7059,9 +7070,9 @@ rs6000_adjust_vec_address (rtx scalar_reg,
     {
       rtx op1 = XEXP (new_addr, 1);
       addr_mask_type addr_mask;
-      int scalar_regno = regno_or_subregno (scalar_reg);
+      unsigned int scalar_regno = reg_or_subregno (scalar_reg);
 
-      gcc_assert (scalar_regno < FIRST_PSEUDO_REGISTER);
+      gcc_assert (HARD_REGISTER_NUM_P (scalar_regno));
       if (INT_REGNO_P (scalar_regno))
        addr_mask = reg_addr[scalar_mode].addr_mask[RELOAD_REG_GPR];
 
@@ -7102,7 +7113,7 @@ rs6000_split_vec_extract_var (rtx dest, rtx src, rtx element, rtx tmp_gpr,
                              rtx tmp_altivec)
 {
   machine_mode mode = GET_MODE (src);
-  machine_mode scalar_mode = GET_MODE (dest);
+  machine_mode scalar_mode = GET_MODE_INNER (GET_MODE (src));
   unsigned scalar_size = GET_MODE_SIZE (scalar_mode);
   int byte_shift = exact_log2 (scalar_size);
 
@@ -7113,6 +7124,10 @@ rs6000_split_vec_extract_var (rtx dest, rtx src, rtx element, rtx tmp_gpr,
      systems.  */
   if (MEM_P (src))
     {
+      int num_elements = GET_MODE_NUNITS (mode);
+      rtx num_ele_m1 = GEN_INT (num_elements - 1);
+
+      emit_insn (gen_anddi3 (element, element, num_ele_m1));
       gcc_assert (REG_P (tmp_gpr));
       emit_move_insn (dest, rs6000_adjust_vec_address (dest, src, element,
                                                       tmp_gpr, scalar_mode));
@@ -7121,11 +7136,13 @@ rs6000_split_vec_extract_var (rtx dest, rtx src, rtx element, rtx tmp_gpr,
 
   else if (REG_P (src) || SUBREG_P (src))
     {
-      int bit_shift = byte_shift + 3;
+      int num_elements = GET_MODE_NUNITS (mode);
+      int bits_in_element = mode_to_bits (GET_MODE_INNER (mode));
+      int bit_shift = 7 - exact_log2 (num_elements);
       rtx element2;
-      int dest_regno = regno_or_subregno (dest);
-      int src_regno = regno_or_subregno (src);
-      int element_regno = regno_or_subregno (element);
+      unsigned int dest_regno = reg_or_subregno (dest);
+      unsigned int src_regno = reg_or_subregno (src);
+      unsigned int element_regno = reg_or_subregno (element);
 
       gcc_assert (REG_P (tmp_gpr));
 
@@ -7197,7 +7214,7 @@ rs6000_split_vec_extract_var (rtx dest, rtx src, rtx element, rtx tmp_gpr,
        {
          if (!BYTES_BIG_ENDIAN)
            {
-             rtx num_ele_m1 = GEN_INT (GET_MODE_NUNITS (mode) - 1);
+             rtx num_ele_m1 = GEN_INT (num_elements - 1);
 
              emit_insn (gen_anddi3 (tmp_gpr, element, num_ele_m1));
              emit_insn (gen_subdi3 (tmp_gpr, num_ele_m1, tmp_gpr));
@@ -7255,8 +7272,8 @@ rs6000_split_vec_extract_var (rtx dest, rtx src, rtx element, rtx tmp_gpr,
            emit_insn (gen_vsx_vslo_v2di (tmp_altivec_di, src_v2di,
                                          tmp_altivec));
            emit_move_insn (tmp_gpr_di, tmp_altivec_di);
-           emit_insn (gen_ashrdi3 (tmp_gpr_di, tmp_gpr_di,
-                                   GEN_INT (64 - (8 * scalar_size))));
+           emit_insn (gen_lshrdi3 (tmp_gpr_di, tmp_gpr_di,
+                                   GEN_INT (64 - bits_in_element)));
            return;
          }
 
@@ -7412,13 +7429,13 @@ small_data_operand (rtx op ATTRIBUTE_UNUSED,
   if (DEFAULT_ABI != ABI_V4)
     return 0;
 
-  if (GET_CODE (op) == SYMBOL_REF)
+  if (SYMBOL_REF_P (op))
     sym_ref = op;
 
   else if (GET_CODE (op) != CONST
           || GET_CODE (XEXP (op, 0)) != PLUS
-          || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
-          || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
+          || !SYMBOL_REF_P (XEXP (XEXP (op, 0), 0))
+          || !CONST_INT_P (XEXP (XEXP (op, 0), 1)))
     return 0;
 
   else
@@ -7456,30 +7473,22 @@ gpr_or_gpr_p (rtx op0, rtx op1)
 bool
 direct_move_p (rtx op0, rtx op1)
 {
-  int regno0, regno1;
-
   if (!REG_P (op0) || !REG_P (op1))
     return false;
 
-  if (!TARGET_DIRECT_MOVE && !TARGET_MFPGPR)
+  if (!TARGET_DIRECT_MOVE)
     return false;
 
-  regno0 = REGNO (op0);
-  regno1 = REGNO (op1);
-  if (regno0 >= FIRST_PSEUDO_REGISTER || regno1 >= FIRST_PSEUDO_REGISTER)
+  int regno0 = REGNO (op0);
+  int regno1 = REGNO (op1);
+  if (!HARD_REGISTER_NUM_P (regno0) || !HARD_REGISTER_NUM_P (regno1))
     return false;
 
-  if (INT_REGNO_P (regno0))
-    return (TARGET_DIRECT_MOVE) ? VSX_REGNO_P (regno1) : FP_REGNO_P (regno1);
-
-  else if (INT_REGNO_P (regno1))
-    {
-      if (TARGET_MFPGPR && FP_REGNO_P (regno0))
-       return true;
+  if (INT_REGNO_P (regno0) && VSX_REGNO_P (regno1))
+    return true;
 
-      else if (TARGET_DIRECT_MOVE && VSX_REGNO_P (regno0))
-       return true;
-    }
+  if (VSX_REGNO_P (regno0) && INT_REGNO_P (regno1))
+    return true;
 
   return false;
 }
@@ -7591,14 +7600,10 @@ address_offset (rtx op)
 
    Accept direct, indexed, offset, lo_sum and tocref.  Since this is
    a constraint function we know the operand has satisfied a suitable
-   memory predicate.  Also accept some odd rtl generated by reload
-   (see rs6000_legitimize_reload_address for various forms).  It is
-   important that reload rtl be accepted by appropriate constraints
-   but not by the operand predicate.
+   memory predicate.
 
    Offsetting a lo_sum should not be allowed, except where we know by
-   alignment that a 32k boundary is not crossed, but see the ???
-   comment in rs6000_legitimize_reload_address.  Note that by
+   alignment that a 32k boundary is not crossed.  Note that by
    "offsetting" here we mean a further offset to access parts of the
    MEM.  It's fine to have a lo_sum where the inner address is offset
    from a sym, since the same sym+offset will appear in the high part
@@ -7721,12 +7726,12 @@ virtual_stack_registers_memory_p (rtx op)
 {
   int regnum;
 
-  if (GET_CODE (op) == REG)
+  if (REG_P (op))
     regnum = REGNO (op);
 
   else if (GET_CODE (op) == PLUS
-          && GET_CODE (XEXP (op, 0)) == REG
-          && GET_CODE (XEXP (op, 1)) == CONST_INT)
+          && REG_P (XEXP (op, 0))
+          && CONST_INT_P (XEXP (op, 1)))
     regnum = REGNO (XEXP (op, 0));
 
   else
@@ -7754,7 +7759,7 @@ offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
   tree decl;
   unsigned HOST_WIDE_INT dsize, dalign, lsb, mask;
 
-  if (GET_CODE (op) != SYMBOL_REF)
+  if (!SYMBOL_REF_P (op))
     return false;
 
   /* ISA 3.0 vector d-form addressing is restricted, don't allow
@@ -7836,7 +7841,7 @@ constant_pool_expr_p (rtx op)
   rtx base, offset;
 
   split_const (op, &base, &offset);
-  return (GET_CODE (base) == SYMBOL_REF
+  return (SYMBOL_REF_P (base)
          && CONSTANT_POOL_ADDRESS_P (base)
          && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
 }
@@ -7915,7 +7920,7 @@ legitimate_small_data_p (machine_mode mode, rtx x)
 {
   return (DEFAULT_ABI == ABI_V4
          && !flag_pic && !TARGET_TOC
-         && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
+         && (SYMBOL_REF_P (x) || GET_CODE (x) == CONST)
          && small_data_operand (x, mode));
 }
 
@@ -7938,7 +7943,7 @@ rs6000_legitimate_offset_address_p (machine_mode mode, rtx x,
     return virtual_stack_registers_memory_p (x);
   if (legitimate_constant_pool_address_p (x, mode, strict || lra_in_progress))
     return true;
-  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+  if (!CONST_INT_P (XEXP (x, 1)))
     return false;
 
   offset = INTVAL (XEXP (x, 1));
@@ -8013,20 +8018,20 @@ avoiding_indexed_address_p (machine_mode mode)
 bool
 legitimate_indirect_address_p (rtx x, int strict)
 {
-  return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
+  return REG_P (x) && INT_REG_OK_FOR_BASE_P (x, strict);
 }
 
 bool
 macho_lo_sum_memory_operand (rtx x, machine_mode mode)
 {
   if (!TARGET_MACHO || !flag_pic
-      || mode != SImode || GET_CODE (x) != MEM)
+      || mode != SImode || !MEM_P (x))
     return false;
   x = XEXP (x, 0);
 
   if (GET_CODE (x) != LO_SUM)
     return false;
-  if (GET_CODE (XEXP (x, 0)) != REG)
+  if (!REG_P (XEXP (x, 0)))
     return false;
   if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
     return false;
@@ -8040,7 +8045,7 @@ legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict)
 {
   if (GET_CODE (x) != LO_SUM)
     return false;
-  if (GET_CODE (XEXP (x, 0)) != REG)
+  if (!REG_P (XEXP (x, 0)))
     return false;
   if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
     return false;
@@ -8060,9 +8065,8 @@ legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict)
         recognizes some LO_SUM addresses as valid although this
         function says opposite.  In most cases, LRA through different
         transformations can generate correct code for address reloads.
-        It can not manage only some LO_SUM cases.  So we need to add
-        code analogous to one in rs6000_legitimize_reload_address for
-        LOW_SUM here saying that some addresses are still valid.  */
+        It cannot manage only some LO_SUM cases.  So we need to add
+        code here saying that some addresses are still valid.  */
       large_toc_ok = (lra_in_progress && TARGET_CMODEL != CMODEL_SMALL
                      && small_toc_ref (x, VOIDmode));
       if (TARGET_TOC && ! large_toc_ok)
@@ -8130,7 +8134,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       else
        return force_reg (Pmode, x);
     }
-  if (GET_CODE (x) == SYMBOL_REF)
+  if (SYMBOL_REF_P (x))
     {
       enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
       if (model != 0)
@@ -8158,8 +8162,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
     }
 
   if (GET_CODE (x) == PLUS
-      && GET_CODE (XEXP (x, 0)) == REG
-      && GET_CODE (XEXP (x, 1)) == CONST_INT
+      && REG_P (XEXP (x, 0))
+      && CONST_INT_P (XEXP (x, 1))
       && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
          >= 0x10000 - extra))
     {
@@ -8174,8 +8178,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       return plus_constant (Pmode, sum, low_int);
     }
   else if (GET_CODE (x) == PLUS
-          && GET_CODE (XEXP (x, 0)) == REG
-          && GET_CODE (XEXP (x, 1)) != CONST_INT
+          && REG_P (XEXP (x, 0))
+          && !CONST_INT_P (XEXP (x, 1))
           && GET_MODE_NUNITS (mode) == 1
           && (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
               || (/* ??? Assume floating point reg based on mode?  */
@@ -8192,10 +8196,10 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
            )
           && TARGET_32BIT
           && TARGET_NO_TOC
-          && ! flag_pic
-          && GET_CODE (x) != CONST_INT
-          && GET_CODE (x) != CONST_WIDE_INT
-          && GET_CODE (x) != CONST_DOUBLE
+          && !flag_pic
+          && !CONST_INT_P (x)
+          && !CONST_WIDE_INT_P (x)
+          && !CONST_DOUBLE_P (x)
           && CONSTANT_P (x)
           && GET_MODE_NUNITS (mode) == 1
           && (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
@@ -8210,7 +8214,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       return gen_rtx_LO_SUM (Pmode, reg, x);
     }
   else if (TARGET_TOC
-          && GET_CODE (x) == SYMBOL_REF
+          && SYMBOL_REF_P (x)
           && constant_pool_expr_p (x)
           && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
     return create_TOC_reference (x, NULL_RTX);
@@ -8289,7 +8293,7 @@ rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
   output_addr_const (file, x);
   if (TARGET_ELF)
     fputs ("@dtprel+0x8000", file);
-  else if (TARGET_XCOFF && GET_CODE (x) == SYMBOL_REF)
+  else if (TARGET_XCOFF && SYMBOL_REF_P (x))
     {
       switch (SYMBOL_REF_TLS_MODEL (x))
        {
@@ -8317,7 +8321,7 @@ rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
 static bool
 rs6000_real_tls_symbol_ref_p (rtx x)
 {
-  return (GET_CODE (x) == SYMBOL_REF
+  return (SYMBOL_REF_P (x)
          && SYMBOL_REF_TLS_MODEL (x) >= TLS_MODEL_REAL);
 }
 
@@ -8330,14 +8334,17 @@ rs6000_delegitimize_address (rtx orig_x)
 {
   rtx x, y, offset;
 
+  if (GET_CODE (orig_x) == UNSPEC && XINT (orig_x, 1) == UNSPEC_FUSION_GPR)
+    orig_x = XVECEXP (orig_x, 0, 0);
+
   orig_x = delegitimize_mem_from_attrs (orig_x);
+
   x = orig_x;
   if (MEM_P (x))
     x = XEXP (x, 0);
 
   y = x;
-  if (TARGET_CMODEL != CMODEL_SMALL
-      && GET_CODE (y) == LO_SUM)
+  if (TARGET_CMODEL != CMODEL_SMALL && GET_CODE (y) == LO_SUM)
     y = XEXP (y, 1);
 
   offset = NULL_RTX;
@@ -8349,8 +8356,7 @@ rs6000_delegitimize_address (rtx orig_x)
       y = XEXP (y, 0);
     }
 
-  if (GET_CODE (y) == UNSPEC
-      && XINT (y, 1) == UNSPEC_TOCREL)
+  if (GET_CODE (y) == UNSPEC && XINT (y, 1) == UNSPEC_TOCREL)
     {
       y = XVECEXP (y, 0, 0);
 
@@ -8358,7 +8364,7 @@ rs6000_delegitimize_address (rtx orig_x)
       /* Do not associate thread-local symbols with the original
         constant pool symbol.  */
       if (TARGET_XCOFF
-         && GET_CODE (y) == SYMBOL_REF
+         && SYMBOL_REF_P (y)
          && CONSTANT_POOL_ADDRESS_P (y)
          && rs6000_real_tls_symbol_ref_p (get_pool_constant (y)))
        return orig_x;
@@ -8377,8 +8383,7 @@ rs6000_delegitimize_address (rtx orig_x)
       && GET_CODE (XEXP (orig_x, 1)) == CONST)
     {
       y = XEXP (XEXP (orig_x, 1), 0);
-      if (GET_CODE (y) == UNSPEC
-         && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
+      if (GET_CODE (y) == UNSPEC && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
        return XVECEXP (y, 0, 0);
     }
 
@@ -8394,7 +8399,7 @@ rs6000_const_not_ok_for_debug_p (rtx x)
 {
   if (GET_CODE (x) == UNSPEC)
     return true;
-  if (GET_CODE (x) == SYMBOL_REF
+  if (SYMBOL_REF_P (x)
       && CONSTANT_POOL_ADDRESS_P (x))
     {
       rtx c = get_pool_constant (x);
@@ -8566,6 +8571,47 @@ rs6000_legitimize_tls_address_aix (rtx addr, enum tls_model model)
   return dest;
 }
 
+/* Output arg setup instructions for a !TARGET_TLS_MARKERS
+   __tls_get_addr call.  */
+
+void
+rs6000_output_tlsargs (rtx *operands)
+{
+  /* Set up operands for output_asm_insn, without modifying OPERANDS.  */
+  rtx op[3];
+
+  /* The set dest of the call, ie. r3, which is also the first arg reg.  */
+  op[0] = operands[0];
+  /* The TLS symbol from global_tlsarg stashed as CALL operand 2.  */
+  op[1] = XVECEXP (operands[2], 0, 0);
+  if (XINT (operands[2], 1) == UNSPEC_TLSGD)
+    {
+      /* The GOT register.  */
+      op[2] = XVECEXP (operands[2], 0, 1);
+      if (TARGET_CMODEL != CMODEL_SMALL)
+       output_asm_insn ("addis %0,%2,%1@got@tlsgd@ha\n\t"
+                        "addi %0,%0,%1@got@tlsgd@l", op);
+      else
+       output_asm_insn ("addi %0,%2,%1@got@tlsgd", op);
+    }
+  else if (XINT (operands[2], 1) == UNSPEC_TLSLD)
+    {
+      if (TARGET_CMODEL != CMODEL_SMALL)
+       output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\n\t"
+                        "addi %0,%0,%&@got@tlsld@l", op);
+      else
+       output_asm_insn ("addi %0,%1,%&@got@tlsld", op);
+    }
+  else
+    gcc_unreachable ();
+}
+
+/* Passes the tls arg value for global dynamic and local dynamic
+   emit_library_call_value in rs6000_legitimize_tls_address to
+   rs6000_call_aix and rs6000_call_sysv.  This is used to emit the
+   marker relocs put on __tls_get_addr calls.  */
+static rtx global_tlsarg;
+
 /* ADDR contains a thread-local SYMBOL_REF.  Generate code to compute
    this (thread-local) address.  */
 
@@ -8618,7 +8664,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
     }
   else
     {
-      rtx r3, got, tga, tmp1, tmp2, call_insn;
+      rtx got, tga, tmp1, tmp2;
 
       /* We currently use relocations like @got@tlsgd for tls, which
         means the linker will handle allocation of tls entries, placing
@@ -8658,52 +8704,47 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
 
       if (model == TLS_MODEL_GLOBAL_DYNAMIC)
        {
+         rtx arg = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, addr, got),
+                                   UNSPEC_TLSGD);
          tga = rs6000_tls_get_addr ();
-         emit_library_call_value (tga, dest, LCT_CONST, Pmode,
-                                  const0_rtx, Pmode);
-
-         r3 = gen_rtx_REG (Pmode, 3);
-         if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+         global_tlsarg = arg;
+         if (TARGET_TLS_MARKERS)
            {
-             if (TARGET_64BIT)
-               insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
-             else
-               insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
+             rtx argreg = gen_rtx_REG (Pmode, 3);
+             emit_insn (gen_rtx_SET (argreg, arg));
+             emit_library_call_value (tga, dest, LCT_CONST, Pmode,
+                                      argreg, Pmode);
            }
-         else if (DEFAULT_ABI == ABI_V4)
-           insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
          else
-           gcc_unreachable ();
-         call_insn = last_call_insn ();
-         PATTERN (call_insn) = insn;
-         if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
-           use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
-                    pic_offset_table_rtx);
+           emit_library_call_value (tga, dest, LCT_CONST, Pmode);
+         global_tlsarg = NULL_RTX;
+
+         /* Make a note so that the result of this call can be CSEd.  */
+         rtvec vec = gen_rtvec (1, copy_rtx (arg));
+         rtx uns = gen_rtx_UNSPEC (Pmode, vec, UNSPEC_TLS_GET_ADDR);
+         set_unique_reg_note (get_last_insn (), REG_EQUAL, uns);
        }
       else if (model == TLS_MODEL_LOCAL_DYNAMIC)
        {
+         rtx arg = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got), UNSPEC_TLSLD);
          tga = rs6000_tls_get_addr ();
          tmp1 = gen_reg_rtx (Pmode);
-         emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
-                                  const0_rtx, Pmode);
-
-         r3 = gen_rtx_REG (Pmode, 3);
-         if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+         global_tlsarg = arg;
+         if (TARGET_TLS_MARKERS)
            {
-             if (TARGET_64BIT)
-               insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
-             else
-               insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
+             rtx argreg = gen_rtx_REG (Pmode, 3);
+             emit_insn (gen_rtx_SET (argreg, arg));
+             emit_library_call_value (tga, tmp1, LCT_CONST, Pmode,
+                                      argreg, Pmode);
            }
-         else if (DEFAULT_ABI == ABI_V4)
-           insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
          else
-           gcc_unreachable ();
-         call_insn = last_call_insn ();
-         PATTERN (call_insn) = insn;
-         if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
-           use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
-                    pic_offset_table_rtx);
+           emit_library_call_value (tga, tmp1, LCT_CONST, Pmode);
+         global_tlsarg = NULL_RTX;
+
+         /* Make a note so that the result of this call can be CSEd.  */
+         rtvec vec = gen_rtvec (1, copy_rtx (arg));
+         rtx uns = gen_rtx_UNSPEC (Pmode, vec, UNSPEC_TLS_GET_ADDR);
+         set_unique_reg_note (get_last_insn (), REG_EQUAL, uns);
 
          if (rs6000_tls_size == 16)
            {
@@ -8780,7 +8821,7 @@ rs6000_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
   /* A TLS symbol in the TOC cannot contain a sum.  */
   if (GET_CODE (x) == CONST
       && GET_CODE (XEXP (x, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
+      && SYMBOL_REF_P (XEXP (XEXP (x, 0), 0))
       && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) != 0)
     return true;
 
@@ -8803,290 +8844,6 @@ use_toc_relative_ref (rtx sym, machine_mode mode)
              && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT));
 }
 
-/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS.  Returns a value to
-   replace the input X, or the original X if no replacement is called for.
-   The output parameter *WIN is 1 if the calling macro should goto WIN,
-   0 if it should not.
-
-   For RS/6000, we wish to handle large displacements off a base
-   register by splitting the addend across an addiu/addis and the mem insn.
-   This cuts number of extra insns needed from 3 to 1.
-
-   On Darwin, we use this to generate code for floating point constants.
-   A movsf_low is generated so we wind up with 2 instructions rather than 3.
-   The Darwin code is inside #if TARGET_MACHO because only then are the
-   machopic_* functions defined.  */
-static rtx
-rs6000_legitimize_reload_address (rtx x, machine_mode mode,
-                                 int opnum, int type,
-                                 int ind_levels ATTRIBUTE_UNUSED, int *win)
-{
-  bool reg_offset_p = reg_offset_addressing_ok_p (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.  */
-  if (reg_offset_p
-      && opnum == 1
-      && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
-         || (mode == DImode && recog_data.operand_mode[0] == V2DImode)
-         || (mode == SFmode && recog_data.operand_mode[0] == V4SFmode
-             && TARGET_P9_VECTOR)
-         || (mode == SImode && recog_data.operand_mode[0] == V4SImode
-             && TARGET_P9_VECTOR)))
-    reg_offset_p = false;
-
-  /* We must recognize output that we have already generated ourselves.  */
-  if (GET_CODE (x) == PLUS
-      && GET_CODE (XEXP (x, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
-      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-      && GET_CODE (XEXP (x, 1)) == CONST_INT)
-    {
-      if (TARGET_DEBUG_ADDR)
-       {
-         fprintf (stderr, "\nlegitimize_reload_address push_reload #1:\n");
-         debug_rtx (x);
-       }
-      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
-                  BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
-                  opnum, (enum reload_type) type);
-      *win = 1;
-      return x;
-    }
-
-  /* Likewise for (lo_sum (high ...) ...) output we have generated.  */
-  if (GET_CODE (x) == LO_SUM
-      && GET_CODE (XEXP (x, 0)) == HIGH)
-    {
-      if (TARGET_DEBUG_ADDR)
-       {
-         fprintf (stderr, "\nlegitimize_reload_address push_reload #2:\n");
-         debug_rtx (x);
-       }
-      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
-                  BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-                  opnum, (enum reload_type) type);
-      *win = 1;
-      return x;
-    }
-
-#if TARGET_MACHO
-  if (DEFAULT_ABI == ABI_DARWIN && flag_pic
-      && GET_CODE (x) == LO_SUM
-      && GET_CODE (XEXP (x, 0)) == PLUS
-      && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
-      && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
-      && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
-      && machopic_operand_p (XEXP (x, 1)))
-    {
-      /* Result of previous invocation of this function on Darwin
-        floating point constant.  */
-      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
-                  BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-                  opnum, (enum reload_type) type);
-      *win = 1;
-      return x;
-    }
-#endif
-
-  if (TARGET_CMODEL != CMODEL_SMALL
-      && reg_offset_p
-      && !quad_offset_p
-      && small_toc_ref (x, VOIDmode))
-    {
-      rtx hi = gen_rtx_HIGH (Pmode, copy_rtx (x));
-      x = gen_rtx_LO_SUM (Pmode, hi, x);
-      if (TARGET_DEBUG_ADDR)
-       {
-         fprintf (stderr, "\nlegitimize_reload_address push_reload #3:\n");
-         debug_rtx (x);
-       }
-      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
-                  BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-                  opnum, (enum reload_type) type);
-      *win = 1;
-      return x;
-    }
-
-  if (GET_CODE (x) == PLUS
-      && REG_P (XEXP (x, 0))
-      && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
-      && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
-      && CONST_INT_P (XEXP (x, 1))
-      && reg_offset_p
-      && (quad_offset_p || !VECTOR_MODE_P (mode) || VECTOR_MEM_NONE_P (mode)))
-    {
-      HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
-      HOST_WIDE_INT high
-       = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
-
-      /* Check for 32-bit overflow or quad addresses with one of the
-        four least significant bits set.  */
-      if (high + low != val
-         || (quad_offset_p && (low & 0xf)))
-       {
-         *win = 0;
-         return x;
-       }
-
-      /* Reload the high part into a base reg; leave the low part
-        in the mem directly.  */
-
-      x = gen_rtx_PLUS (GET_MODE (x),
-                       gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
-                                     GEN_INT (high)),
-                       GEN_INT (low));
-
-      if (TARGET_DEBUG_ADDR)
-       {
-         fprintf (stderr, "\nlegitimize_reload_address push_reload #4:\n");
-         debug_rtx (x);
-       }
-      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
-                  BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
-                  opnum, (enum reload_type) type);
-      *win = 1;
-      return x;
-    }
-
-  if (GET_CODE (x) == SYMBOL_REF
-      && reg_offset_p
-      && !quad_offset_p
-      && (!VECTOR_MODE_P (mode) || VECTOR_MEM_NONE_P (mode))
-#if TARGET_MACHO
-      && DEFAULT_ABI == ABI_DARWIN
-      && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
-      && machopic_symbol_defined_p (x)
-#else
-      && DEFAULT_ABI == ABI_V4
-      && !flag_pic
-#endif
-      /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
-        The same goes for DImode without 64-bit gprs and DFmode and DDmode
-        without fprs.
-        ??? Assume floating point reg based on mode?  This assumption is
-        violated by eg. powerpc-linux -m32 compile of gcc.dg/pr28796-2.c
-        where reload ends up doing a DFmode load of a constant from
-        mem using two gprs.  Unfortunately, at this point reload
-        hasn't yet selected regs so poking around in reload data
-        won't help and even if we could figure out the regs reliably,
-        we'd still want to allow this transformation when the mem is
-        naturally aligned.  Since we say the address is good here, we
-        can't disable offsets from LO_SUMs in mem_operand_gpr.
-        FIXME: Allow offset from lo_sum for other modes too, when
-        mem is sufficiently aligned.
-
-        Also disallow this if the type can go in VMX/Altivec registers, since
-        those registers do not have d-form (reg+offset) address modes.  */
-      && !reg_addr[mode].scalar_in_vmx_p
-      && mode != TFmode
-      && mode != TDmode
-      && mode != IFmode
-      && mode != KFmode
-      && (mode != TImode || !TARGET_VSX)
-      && mode != PTImode
-      && (mode != DImode || TARGET_POWERPC64)
-      && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
-         || TARGET_HARD_FLOAT))
-    {
-#if TARGET_MACHO
-      if (flag_pic)
-       {
-         rtx offset = machopic_gen_offset (x);
-         x = gen_rtx_LO_SUM (GET_MODE (x),
-               gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
-                 gen_rtx_HIGH (Pmode, offset)), offset);
-       }
-      else
-#endif
-       x = gen_rtx_LO_SUM (GET_MODE (x),
-             gen_rtx_HIGH (Pmode, x), x);
-
-      if (TARGET_DEBUG_ADDR)
-       {
-         fprintf (stderr, "\nlegitimize_reload_address push_reload #5:\n");
-         debug_rtx (x);
-       }
-      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
-                  BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-                  opnum, (enum reload_type) type);
-      *win = 1;
-      return x;
-    }
-
-  /* Reload an offset address wrapped by an AND that represents the
-     masking of the lower bits.  Strip the outer AND and let reload
-     convert the offset address into an indirect address.  For VSX,
-     force reload to create the address with an AND in a separate
-     register, because we can't guarantee an altivec register will
-     be used.  */
-  if (VECTOR_MEM_ALTIVEC_P (mode)
-      && GET_CODE (x) == AND
-      && GET_CODE (XEXP (x, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
-      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-      && GET_CODE (XEXP (x, 1)) == CONST_INT
-      && INTVAL (XEXP (x, 1)) == -16)
-    {
-      x = XEXP (x, 0);
-      *win = 1;
-      return x;
-    }
-
-  if (TARGET_TOC
-      && reg_offset_p
-      && !quad_offset_p
-      && GET_CODE (x) == SYMBOL_REF
-      && use_toc_relative_ref (x, mode))
-    {
-      x = create_TOC_reference (x, NULL_RTX);
-      if (TARGET_CMODEL != CMODEL_SMALL)
-       {
-         if (TARGET_DEBUG_ADDR)
-           {
-             fprintf (stderr, "\nlegitimize_reload_address push_reload #6:\n");
-             debug_rtx (x);
-           }
-         push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
-                      BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
-                      opnum, (enum reload_type) type);
-       }
-      *win = 1;
-      return x;
-    }
-  *win = 0;
-  return x;
-}
-
-/* Debug version of rs6000_legitimize_reload_address.  */
-static rtx
-rs6000_debug_legitimize_reload_address (rtx x, machine_mode mode,
-                                       int opnum, int type,
-                                       int ind_levels, int *win)
-{
-  rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
-                                             ind_levels, win);
-  fprintf (stderr,
-          "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
-          "type = %d, ind_levels = %d, win = %d, original addr:\n",
-          GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
-  debug_rtx (x);
-
-  if (x == ret)
-    fprintf (stderr, "Same address returned\n");
-  else if (!ret)
-    fprintf (stderr, "NULL returned\n");
-  else
-    {
-      fprintf (stderr, "New address:\n");
-      debug_rtx (ret);
-    }
-
-  return ret;
-}
-
 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
    that is a valid memory address for an instruction.
    The MODE argument is the machine mode for the MEM expression
@@ -9113,7 +8870,7 @@ rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
   /* If this is an unaligned stvx/ldvx type address, discard the outer AND.  */
   if (VECTOR_MEM_ALTIVEC_P (mode)
       && GET_CODE (x) == AND
-      && GET_CODE (XEXP (x, 1)) == CONST_INT
+      && CONST_INT_P (XEXP (x, 1))
       && INTVAL (XEXP (x, 1)) == -16)
     x = XEXP (x, 0);
 
@@ -9159,10 +8916,10 @@ rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
   if (! reg_ok_strict
       && reg_offset_p
       && GET_CODE (x) == PLUS
-      && GET_CODE (XEXP (x, 0)) == REG
+      && REG_P (XEXP (x, 0))
       && (XEXP (x, 0) == virtual_stack_vars_rtx
          || XEXP (x, 0) == arg_pointer_rtx)
-      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+      && CONST_INT_P (XEXP (x, 1)))
     return 1;
   if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict, false))
     return 1;
@@ -9244,7 +9001,7 @@ rs6000_mode_dependent_address (const_rtx addr)
         been rejected as illegitimate.  */
       if (XEXP (addr, 0) != virtual_stack_vars_rtx
          && XEXP (addr, 0) != arg_pointer_rtx
-         && GET_CODE (XEXP (addr, 1)) == CONST_INT)
+         && CONST_INT_P (XEXP (addr, 1)))
        {
          unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
          return val + 0x8000 >= 0x10000 - (TARGET_POWERPC64 ? 8 : 12);
@@ -9362,6 +9119,7 @@ rs6000_reassociation_width (unsigned int opc ATTRIBUTE_UNUSED,
     {
     case PROCESSOR_POWER8:
     case PROCESSOR_POWER9:
+    case PROCESSOR_FUTURE:
       if (DECIMAL_FLOAT_MODE_P (mode))
        return 1;
       if (VECTOR_MODE_P (mode))
@@ -9386,10 +9144,6 @@ rs6000_conditional_register_usage (void)
   if (TARGET_DEBUG_TARGET)
     fprintf (stderr, "rs6000_conditional_register_usage called\n");
 
-  /* Set MQ register fixed (already call_used) so that it will not be
-     allocated.  */
-  fixed_regs[64] = 1;
-
   /* 64-bit AIX and Linux reserve GPR13 for thread-private data.  */
   if (TARGET_64BIT)
     fixed_regs[13] = call_used_regs[13]
@@ -9605,16 +9359,16 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
 static void
 rs6000_eliminate_indexed_memrefs (rtx operands[2])
 {
-  if (GET_CODE (operands[0]) == MEM
-      && GET_CODE (XEXP (operands[0], 0)) != REG
+  if (MEM_P (operands[0])
+      && !REG_P (XEXP (operands[0], 0))
       && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
                                               GET_MODE (operands[0]), false))
     operands[0]
       = replace_equiv_address (operands[0],
                               copy_addr_to_reg (XEXP (operands[0], 0)));
 
-  if (GET_CODE (operands[1]) == MEM
-      && GET_CODE (XEXP (operands[1], 0)) != REG
+  if (MEM_P (operands[1])
+      && !REG_P (XEXP (operands[1], 0))
       && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
                                               GET_MODE (operands[1]), false))
     operands[1]
@@ -9752,7 +9506,7 @@ rs6000_emit_le_vsx_move (rtx dest, rtx source, machine_mode mode)
 
   if (MEM_P (source))
     {
-      gcc_assert (REG_P (dest) || GET_CODE (dest) == SUBREG);
+      gcc_assert (REG_P (dest) || SUBREG_P (dest));
       rs6000_emit_le_vsx_load (dest, source, mode);
     }
   else
@@ -9811,7 +9565,7 @@ valid_sf_si_move (rtx dest, rtx src, machine_mode mode)
 static bool
 rs6000_emit_move_si_sf_subreg (rtx dest, rtx source, machine_mode mode)
 {
-  if (TARGET_DIRECT_MOVE_64BIT && !lra_in_progress && !reload_completed
+  if (TARGET_DIRECT_MOVE_64BIT && !reload_completed
       && (!SUBREG_P (dest) || !sf_subreg_operand (dest, mode))
       && SUBREG_P (source) && sf_subreg_operand (source, mode))
     {
@@ -9856,13 +9610,10 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
       debug_rtx (source);
     }
 
-  /* Sanity checks.  Check that we get CONST_DOUBLE only when we should.  */
+  /* Check that we get CONST_WIDE_INT only when we should.  */
   if (CONST_WIDE_INT_P (operands[1])
       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
-    {
-      /* This should be fixed with the introduction of CONST_WIDE_INT.  */
-      gcc_unreachable ();
-    }
+    gcc_unreachable ();
 
 #ifdef HAVE_AS_GNU_ATTRIBUTE
   /* If we use a long double type, set the flags in .gnu_attribute that say
@@ -9888,8 +9639,8 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
 
   /* Check if GCC is setting up a block move that will end up using FP
      registers as temporaries.  We must make sure this is acceptable.  */
-  if (GET_CODE (operands[0]) == MEM
-      && GET_CODE (operands[1]) == MEM
+  if (MEM_P (operands[0])
+      && MEM_P (operands[1])
       && mode == DImode
       && (rs6000_slow_unaligned_access (DImode, MEM_ALIGN (operands[0]))
          || rs6000_slow_unaligned_access (DImode, MEM_ALIGN (operands[1])))
@@ -9909,7 +9660,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
       return;
     }
 
-  if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
+  if (can_create_pseudo_p () && MEM_P (operands[0])
       && !gpc_reg_operand (operands[1], mode))
     operands[1] = force_reg (mode, operands[1]);
 
@@ -9927,7 +9678,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
          tmp = XEXP (XEXP (tmp, 0), 0);
        }
 
-      gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
+      gcc_assert (SYMBOL_REF_P (tmp));
       model = SYMBOL_REF_TLS_MODEL (tmp);
       gcc_assert (model != 0);
 
@@ -9943,8 +9694,8 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
   /* 128-bit constant floating-point values on Darwin should really be loaded
      as two parts.  However, this premature splitting is a problem when DFmode
      values can go into Altivec registers.  */
-  if (FLOAT128_IBM_P (mode) && !reg_addr[DFmode].scalar_in_vmx_p
-      && GET_CODE (operands[1]) == CONST_DOUBLE)
+  if (TARGET_MACHO && CONST_DOUBLE_P (operands[1]) && FLOAT128_IBM_P (mode)
+      && !reg_addr[DFmode].scalar_in_vmx_p)
     {
       rs6000_emit_move (simplify_gen_subreg (DFmode, operands[0], mode, 0),
                        simplify_gen_subreg (DFmode, operands[1], mode, 0),
@@ -9961,15 +9712,15 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
      p1:SD) if p1 is not of floating point class and p0 is spilled as
      we can have no analogous movsd_store for this.  */
   if (lra_in_progress && mode == DDmode
-      && REG_P (operands[0]) && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER
+      && REG_P (operands[0]) && !HARD_REGISTER_P (operands[0])
       && reg_preferred_class (REGNO (operands[0])) == NO_REGS
-      && GET_CODE (operands[1]) == SUBREG && REG_P (SUBREG_REG (operands[1]))
+      && SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))
       && GET_MODE (SUBREG_REG (operands[1])) == SDmode)
     {
       enum reg_class cl;
       int regno = REGNO (SUBREG_REG (operands[1]));
 
-      if (regno >= FIRST_PSEUDO_REGISTER)
+      if (!HARD_REGISTER_NUM_P (regno))
        {
          cl = reg_preferred_class (regno);
          regno = reg_renumber[regno];
@@ -9985,17 +9736,15 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
     }
   if (lra_in_progress
       && mode == SDmode
-      && REG_P (operands[0]) && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER
+      && REG_P (operands[0]) && !HARD_REGISTER_P (operands[0])
       && reg_preferred_class (REGNO (operands[0])) == NO_REGS
       && (REG_P (operands[1])
-         || (GET_CODE (operands[1]) == SUBREG
-             && REG_P (SUBREG_REG (operands[1])))))
+         || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))))
     {
-      int regno = REGNO (GET_CODE (operands[1]) == SUBREG
-                        ? SUBREG_REG (operands[1]) : operands[1]);
+      int regno = reg_or_subregno (operands[1]);
       enum reg_class cl;
 
-      if (regno >= FIRST_PSEUDO_REGISTER)
+      if (!HARD_REGISTER_NUM_P (regno))
        {
          cl = reg_preferred_class (regno);
          gcc_assert (cl != NO_REGS);
@@ -10019,15 +9768,15 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
      p:DD)) if p0 is not of floating point class and p1 is spilled as
      we can have no analogous movsd_load for this.  */
   if (lra_in_progress && mode == DDmode
-      && GET_CODE (operands[0]) == SUBREG && REG_P (SUBREG_REG (operands[0]))
+      && SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0]))
       && GET_MODE (SUBREG_REG (operands[0])) == SDmode
-      && REG_P (operands[1]) && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
+      && REG_P (operands[1]) && !HARD_REGISTER_P (operands[1])
       && reg_preferred_class (REGNO (operands[1])) == NO_REGS)
     {
       enum reg_class cl;
       int regno = REGNO (SUBREG_REG (operands[0]));
 
-      if (regno >= FIRST_PSEUDO_REGISTER)
+      if (!HARD_REGISTER_NUM_P (regno))
        {
          cl = reg_preferred_class (regno);
          regno = reg_renumber[regno];
@@ -10044,16 +9793,14 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
   if (lra_in_progress
       && mode == SDmode
       && (REG_P (operands[0])
-         || (GET_CODE (operands[0]) == SUBREG
-             && REG_P (SUBREG_REG (operands[0]))))
-      && REG_P (operands[1]) && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
+         || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0]))))
+      && REG_P (operands[1]) && !HARD_REGISTER_P (operands[1])
       && reg_preferred_class (REGNO (operands[1])) == NO_REGS)
     {
-      int regno = REGNO (GET_CODE (operands[0]) == SUBREG
-                        ? SUBREG_REG (operands[0]) : operands[0]);
+      int regno = reg_or_subregno (operands[0]);
       enum reg_class cl;
 
-      if (regno >= FIRST_PSEUDO_REGISTER)
+      if (!HARD_REGISTER_NUM_P (regno))
        {
          cl = reg_preferred_class (regno);
          gcc_assert (cl != NO_REGS);
@@ -10082,7 +9829,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
     case E_HImode:
     case E_QImode:
       if (CONSTANT_P (operands[1])
-         && GET_CODE (operands[1]) != CONST_INT)
+         && !CONST_INT_P (operands[1]))
        operands[1] = force_const_mem (mode, operands[1]);
       break;
 
@@ -10121,7 +9868,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
       if (TARGET_ELF
          && mode == Pmode
          && DEFAULT_ABI == ABI_V4
-         && (GET_CODE (operands[1]) == SYMBOL_REF
+         && (SYMBOL_REF_P (operands[1])
              || GET_CODE (operands[1]) == CONST)
          && small_data_operand (operands[1], mode))
        {
@@ -10143,7 +9890,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
          && mode == Pmode
          && CONSTANT_P (operands[1])
          && GET_CODE (operands[1]) != HIGH
-         && GET_CODE (operands[1]) != CONST_INT)
+         && !CONST_INT_P (operands[1]))
        {
          rtx target = (!can_create_pseudo_p ()
                        ? operands[0]
@@ -10152,7 +9899,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
          /* If this is a function address on -mcall-aixdesc,
             convert it to the address of the descriptor.  */
          if (DEFAULT_ABI == ABI_AIX
-             && GET_CODE (operands[1]) == SYMBOL_REF
+             && SYMBOL_REF_P (operands[1])
              && XSTR (operands[1], 0)[0] == '.')
            {
              const char *name = XSTR (operands[1], 0);
@@ -10195,19 +9942,17 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
         and we have put it in the TOC, we just need to make a TOC-relative
         reference to it.  */
       if (TARGET_TOC
-         && GET_CODE (operands[1]) == SYMBOL_REF
+         && SYMBOL_REF_P (operands[1])
          && use_toc_relative_ref (operands[1], mode))
        operands[1] = create_TOC_reference (operands[1], operands[0]);
       else if (mode == Pmode
               && CONSTANT_P (operands[1])
               && GET_CODE (operands[1]) != HIGH
-              && ((GET_CODE (operands[1]) != CONST_INT
-                   && ! easy_fp_constant (operands[1], mode))
-                  || (GET_CODE (operands[1]) == CONST_INT
-                      && (num_insns_constant (operands[1], mode)
-                          > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
-                  || (GET_CODE (operands[0]) == REG
-                      && FP_REGNO_P (REGNO (operands[0]))))
+              && ((REG_P (operands[0])
+                   && FP_REGNO_P (REGNO (operands[0])))
+                  || !CONST_INT_P (operands[1])
+                  || (num_insns_constant (operands[1], mode)
+                      > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
               && !toc_relative_expr_p (operands[1], false, NULL, NULL)
               && (TARGET_CMODEL == CMODEL_SMALL
                   || can_create_pseudo_p ()
@@ -10236,7 +9981,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
              && GET_CODE (XEXP (operands[1], 0)) == PLUS
              && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
              && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
-                 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
+                 || SYMBOL_REF_P (XEXP (XEXP (operands[1], 0), 0)))
              && ! side_effects_p (operands[0]))
            {
              rtx sym =
@@ -10251,7 +9996,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
          operands[1] = force_const_mem (mode, operands[1]);
 
          if (TARGET_TOC
-             && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
+             && SYMBOL_REF_P (XEXP (operands[1], 0))
              && use_toc_relative_ref (XEXP (operands[1], 0), mode))
            {
              rtx tocref = create_TOC_reference (XEXP (operands[1], 0),
@@ -10278,7 +10023,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
   /* Above, we may have called force_const_mem which may have returned
      an invalid address.  If we can, fix this up; otherwise, reload will
      have to deal with it.  */
-  if (GET_CODE (operands[1]) == MEM)
+  if (MEM_P (operands[1]))
     operands[1] = validize_mem (operands[1]);
 
   emit_insn (gen_rtx_SET (operands[0], operands[1]));
@@ -10662,7 +10407,7 @@ void
 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
                      rtx libname ATTRIBUTE_UNUSED, int incoming,
                      int libcall, int n_named_args,
-                     tree fndecl ATTRIBUTE_UNUSED,
+                     tree fndecl,
                      machine_mode return_mode ATTRIBUTE_UNUSED)
 {
   static CUMULATIVE_ARGS zero_cumulative;
@@ -10688,6 +10433,27 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
          && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
          && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
     cum->call_cookie |= CALL_LONG;
+  else if (DEFAULT_ABI != ABI_DARWIN)
+    {
+      bool is_local = (fndecl
+                      && !DECL_EXTERNAL (fndecl)
+                      && !DECL_WEAK (fndecl)
+                      && (*targetm.binds_local_p) (fndecl));
+      if (is_local)
+       ;
+      else if (flag_plt)
+       {
+         if (fntype
+             && lookup_attribute ("noplt", TYPE_ATTRIBUTES (fntype)))
+           cum->call_cookie |= CALL_LONG;
+       }
+      else
+       {
+         if (!(fntype
+               && lookup_attribute ("plt", TYPE_ATTRIBUTES (fntype))))
+           cum->call_cookie |= CALL_LONG;
+       }
+    }
 
   if (TARGET_DEBUG_ARG)
     {
@@ -11897,7 +11663,9 @@ rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
       if (elt_mode == TDmode && (cum->fregno % 2) == 1)
        cum->fregno++;
 
-      if (USE_FP_FOR_ARG_P (cum, elt_mode))
+      if (USE_FP_FOR_ARG_P (cum, elt_mode)
+         && !(TARGET_AIX && !TARGET_ELF
+              && type != NULL && AGGREGATE_TYPE_P (type)))
        {
          rtx rvec[GP_ARG_NUM_REG + AGGR_ARG_NUM_REG + 1];
          rtx r, off;
@@ -11968,7 +11736,7 @@ rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
                {
                  warned = true;
                  inform (input_location,
-                         "the ABI of passing homogeneous float aggregates"
+                         "the ABI of passing homogeneous %<float%> aggregates"
                          " has changed in GCC 5");
                }
            }
@@ -12033,7 +11801,9 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
 
   align_words = rs6000_parm_start (mode, type, cum->words);
 
-  if (USE_FP_FOR_ARG_P (cum, elt_mode))
+  if (USE_FP_FOR_ARG_P (cum, elt_mode)
+      && !(TARGET_AIX && !TARGET_ELF
+          && type != NULL && AGGREGATE_TYPE_P (type)))
     {
       unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
 
@@ -12425,13 +12195,13 @@ setup_incoming_varargs (cumulative_args_t cum, machine_mode mode,
            {
              rtx reg_save_area
                = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
-             gcc_assert (GET_CODE (reg_save_area) == MEM);
+             gcc_assert (MEM_P (reg_save_area));
              reg_save_area = XEXP (reg_save_area, 0);
              if (GET_CODE (reg_save_area) == PLUS)
                {
                  gcc_assert (XEXP (reg_save_area, 0)
                              == virtual_stack_vars_rtx);
-                 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
+                 gcc_assert (CONST_INT_P (XEXP (reg_save_area, 1)));
                  offset += INTVAL (XEXP (reg_save_area, 1));
                }
              else
@@ -13249,9 +13019,9 @@ rs6000_expand_zeroop_builtin (enum insn_code icode, rtx target)
     return 0;
 
   if (icode == CODE_FOR_rs6000_mffsl
-      && rs6000_isa_flags_explicit & OPTION_MASK_SOFT_FLOAT)
+      && rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
     {
-      error ("__builtin_mffsl() not supported with -msoft-float");
+      error ("%<__builtin_mffsl%> not supported with %<-msoft-float%>");
       return const0_rtx;
     }
 
@@ -13288,7 +13058,7 @@ rs6000_expand_mtfsf_builtin (enum insn_code icode, tree exp)
   if (arg0 == error_mark_node || arg1 == error_mark_node)
     return const0_rtx;
 
-  if (GET_CODE (op0) != CONST_INT
+  if (!CONST_INT_P (op0)
       || INTVAL (op0) > 255
       || INTVAL (op0) < 0)
     {
@@ -13321,9 +13091,10 @@ rs6000_expand_mtfsb_builtin (enum insn_code icode, tree exp)
     /* Builtin not supported on this processor.  */
     return 0;
 
-  if (rs6000_isa_flags_explicit & OPTION_MASK_SOFT_FLOAT)
+  if (rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
     {
-      error ("__builtin_mtfsb0 and __builtin_mtfsb1 not supported with -msoft-float");
+      error ("%<__builtin_mtfsb0%> and %<__builtin_mtfsb1%> not supported with "
+            "%<-msoft-float%>");
       return const0_rtx;
     }
 
@@ -13358,9 +13129,9 @@ rs6000_expand_set_fpscr_rn_builtin (enum insn_code icode, tree exp)
     /* Builtin not supported on this processor.  */
     return 0;
 
-  if (rs6000_isa_flags_explicit & OPTION_MASK_SOFT_FLOAT)
+  if (rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
     {
-      error ("__builtin_set_fpscr_rn not supported with -msoft-float");
+      error ("%<__builtin_set_fpscr_rn%> not supported with %<-msoft-float%>");
       return const0_rtx;
     }
 
@@ -13373,7 +13144,7 @@ rs6000_expand_set_fpscr_rn_builtin (enum insn_code icode, tree exp)
      compile time if the argument is a variable.  The least significant two
      bits of the argument, regardless of type, are used to set the rounding
      mode.  All other bits are ignored.  */
-  if (GET_CODE (op0) == CONST_INT && !const_0_to_3_operand(op0, VOIDmode))
+  if (CONST_INT_P (op0) && !const_0_to_3_operand(op0, VOIDmode))
     {
       error ("Argument must be a value between 0 and 3.");
       return const0_rtx;
@@ -13400,11 +13171,12 @@ rs6000_expand_set_fpscr_drn_builtin (enum insn_code icode, tree exp)
   if (TARGET_32BIT)
     /* Builtin not supported in 32-bit mode.  */
     fatal_error (input_location,
-                "__builtin_set_fpscr_drn is not supported in 32-bit mode.");
+                "%<__builtin_set_fpscr_drn%> is not supported "
+                "in 32-bit mode");
 
-  if (rs6000_isa_flags_explicit & OPTION_MASK_SOFT_FLOAT)
+  if (rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
     {
-      error ("__builtin_set_fpscr_drn not supported with -msoft-float");
+      error ("%<__builtin_set_fpscr_drn%> not supported with %<-msoft-float%>");
       return const0_rtx;
     }
 
@@ -13421,7 +13193,7 @@ rs6000_expand_set_fpscr_drn_builtin (enum insn_code icode, tree exp)
      compile time if the argument is a variable. The least significant two
      bits of the argument, regardless of type, are used to set the rounding
      mode.  All other bits are ignored.  */
-  if (GET_CODE (op0) == CONST_INT && !const_0_to_7_operand(op0, VOIDmode))
+  if (CONST_INT_P (op0) && !const_0_to_7_operand(op0, VOIDmode))
    {
       error ("Argument must be a value between 0 and 7.");
       return const0_rtx;
@@ -13460,7 +13232,7 @@ rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
       || icode == CODE_FOR_altivec_vspltisw)
     {
       /* Only allow 5-bit *signed* literals.  */
-      if (GET_CODE (op0) != CONST_INT
+      if (!CONST_INT_P (op0)
          || INTVAL (op0) > 15
          || INTVAL (op0) < -16)
        {
@@ -13968,23 +13740,6 @@ htm_spr_num (enum rs6000_builtins code)
   return TEXASRU_SPR;
 }
 
-/* Return the appropriate SPR regno associated with the given builtin.  */
-static inline HOST_WIDE_INT
-htm_spr_regno (enum rs6000_builtins code)
-{
-  if (code == HTM_BUILTIN_GET_TFHAR
-      || code == HTM_BUILTIN_SET_TFHAR)
-    return TFHAR_REGNO;
-  else if (code == HTM_BUILTIN_GET_TFIAR
-          || code == HTM_BUILTIN_SET_TFIAR)
-    return TFIAR_REGNO;
-  gcc_assert (code == HTM_BUILTIN_GET_TEXASR
-             || code == HTM_BUILTIN_SET_TEXASR
-             || code == HTM_BUILTIN_GET_TEXASRU
-             || code == HTM_BUILTIN_SET_TEXASRU);
-  return TEXASR_REGNO;
-}
-
 /* Return the correct ICODE value depending on whether we are
    setting or reading the HTM SPRs.  */
 static inline enum insn_code
@@ -14101,7 +13856,6 @@ htm_expand_builtin (tree exp, rtx target, bool * expandedp)
          {
            machine_mode mode = (TARGET_POWERPC64) ? DImode : SImode;
            op[nopnds++] = gen_rtx_CONST_INT (mode, htm_spr_num (fcode));
-           op[nopnds++] = gen_rtx_REG (mode, htm_spr_regno (fcode));
          }
        /* If this builtin accesses a CR, then pass in a scratch
           CR as the last operand.  */
@@ -14122,7 +13876,7 @@ htm_expand_builtin (tree exp, rtx target, bool * expandedp)
            if (!(attr & RS6000_BTC_VOID))
              expected_nopnds += 1;
            if (uses_spr)
-             expected_nopnds += 2;
+             expected_nopnds += 1;
 
            gcc_assert (nopnds == expected_nopnds
                        && nopnds <= MAX_HTM_OPERANDS);
@@ -14441,7 +14195,7 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
       if (TREE_CODE (arg2) != INTEGER_CST
          || wi::geu_p (wi::to_wide (arg2), 16))
        {
-         error ("argument 3 must be in the range 0..15");
+         error ("argument 3 must be in the range [0, 15]");
          return CONST0_RTX (tmode);
        }
     }
@@ -14574,7 +14328,7 @@ get_element_number (tree vec_type, tree arg)
   if (!tree_fits_uhwi_p (arg)
       || (elt = tree_to_uhwi (arg), elt > max))
     {
-      error ("selector must be an integer constant in the range 0..%wi", max);
+      error ("selector must be an integer constant in the range [0, %wi]", max);
       return 0;
     }
 
@@ -14628,9 +14382,17 @@ altivec_expand_vec_ext_builtin (tree exp, rtx target)
   op0 = expand_normal (arg0);
   op1 = expand_normal (arg1);
 
-  /* Call get_element_number to validate arg1 if it is a constant.  */
   if (TREE_CODE (arg1) == INTEGER_CST)
-    (void) get_element_number (TREE_TYPE (arg0), arg1);
+    {
+      unsigned HOST_WIDE_INT elt;
+      unsigned HOST_WIDE_INT size = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
+      unsigned int truncated_selector;
+      /* Even if !tree_fits_uhwi_p (arg1)), TREE_INT_CST_LOW (arg0)
+        returns low-order bits of INTEGER_CST for modulo indexing.  */
+      elt = TREE_INT_CST_LOW (arg1);
+      truncated_selector = elt % size;
+      op1 = GEN_INT (truncated_selector);
+    }
 
   tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
   mode0 = TYPE_MODE (TREE_TYPE (arg0));
@@ -14886,7 +14648,7 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
 
       if (TREE_CODE (arg1) != INTEGER_CST || TREE_INT_CST_LOW (arg1) > 12)
        {
-         error ("second argument to %qs must be 0..12", "vec_vextract4b");
+         error ("second argument to %qs must be [0, 12]", "vec_vextract4b");
          return expand_call (exp, target, false);
        }
       break;
@@ -14901,7 +14663,7 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
 
       if (TREE_CODE (arg2) != INTEGER_CST || TREE_INT_CST_LOW (arg2) > 12)
        {
-         error ("third argument to %qs must be 0..12", "vec_vinsert4b");
+         error ("third argument to %qs must be [0, 12]", "vec_vinsert4b");
          return expand_call (exp, target, false);
        }
       break;
@@ -15141,7 +14903,8 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
     error ("builtin function %qs requires ISA 3.0 IEEE 128-bit floating point",
           name);
   else if ((fnmask & RS6000_BTM_FLOAT128) != 0)
-    error ("builtin function %qs requires the %qs option", name, "-mfloat128");
+    error ("builtin function %qs requires the %qs option", name,
+          "%<-mfloat128%>");
   else if ((fnmask & (RS6000_BTM_POPCNTD | RS6000_BTM_POWERPC64))
           == (RS6000_BTM_POPCNTD | RS6000_BTM_POWERPC64))
     error ("builtin function %qs requires the %qs (or newer), and "
@@ -15328,6 +15091,7 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
   enum rs6000_builtins fn_code
     = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
   tree arg0, arg1, lhs, temp;
+  enum tree_code bcode;
   gimple *g;
 
   size_t uns_fncode = (size_t) fn_code;
@@ -15366,10 +15130,32 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case P8V_BUILTIN_VADDUDM:
     case ALTIVEC_BUILTIN_VADDFP:
     case VSX_BUILTIN_XVADDDP:
+      bcode = PLUS_EXPR;
+    do_binary:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, PLUS_EXPR, arg0, arg1);
+      if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (lhs)))
+         && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (lhs))))
+       {
+         /* Ensure the binary operation is performed in a type
+            that wraps if it is integral type.  */
+         gimple_seq stmts = NULL;
+         tree type = unsigned_type_for (TREE_TYPE (lhs));
+         tree uarg0 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+                                    type, arg0);
+         tree uarg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+                                    type, arg1);
+         tree res = gimple_build (&stmts, gimple_location (stmt), bcode,
+                                  type, uarg0, uarg1);
+         gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+         g = gimple_build_assign (lhs, VIEW_CONVERT_EXPR,
+                                  build1 (VIEW_CONVERT_EXPR,
+                                          TREE_TYPE (lhs), res));
+         gsi_replace (gsi, g, true);
+         return true;
+       }
+      g = gimple_build_assign (lhs, bcode, arg0, arg1);
       gimple_set_location (g, gimple_location (stmt));
       gsi_replace (gsi, g, true);
       return true;
@@ -15381,13 +15167,8 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case P8V_BUILTIN_VSUBUDM:
     case ALTIVEC_BUILTIN_VSUBFP:
     case VSX_BUILTIN_XVSUBDP:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, MINUS_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
+      bcode = MINUS_EXPR;
+      goto do_binary;
     case VSX_BUILTIN_XVMULSP:
     case VSX_BUILTIN_XVMULDP:
       arg0 = gimple_call_arg (stmt, 0);
@@ -15625,13 +15406,37 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VSRAH:
     case ALTIVEC_BUILTIN_VSRAW:
     case P8V_BUILTIN_VSRAD:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, RSHIFT_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
+      {
+       arg0 = gimple_call_arg (stmt, 0);
+       arg1 = gimple_call_arg (stmt, 1);
+       lhs = gimple_call_lhs (stmt);
+       tree arg1_type = TREE_TYPE (arg1);
+       tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
+       tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
+       location_t loc = gimple_location (stmt);
+       /* Force arg1 into the range valid matching the arg0 type.  */
+       /* Build a vector consisting of the max valid bit-size values.  */
+       int n_elts = VECTOR_CST_NELTS (arg1);
+       tree element_size = build_int_cst (unsigned_element_type,
+                                          128 / n_elts);
+       tree_vector_builder elts (unsigned_arg1_type, n_elts, 1);
+       for (int i = 0; i < n_elts; i++)
+         elts.safe_push (element_size);
+       tree modulo_tree = elts.build ();
+       /* Modulo the provided shift value against that vector.  */
+       gimple_seq stmts = NULL;
+       tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+                                          unsigned_arg1_type, arg1);
+       tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
+                                     unsigned_arg1_type, unsigned_arg1,
+                                     modulo_tree);
+       gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+       /* And finally, do the shift.  */
+       g = gimple_build_assign (lhs, RSHIFT_EXPR, arg0, new_arg1);
+       gimple_set_location (g, loc);
+       gsi_replace (gsi, g, true);
+       return true;
+      }
    /* Flavors of vector shift left.
       builtin_altivec_vsl{b,h,w} -> vsl{b,h,w}.  */
     case ALTIVEC_BUILTIN_VSLB:
@@ -15685,14 +15490,34 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
        arg0 = gimple_call_arg (stmt, 0);
        arg1 = gimple_call_arg (stmt, 1);
        lhs = gimple_call_lhs (stmt);
+       tree arg1_type = TREE_TYPE (arg1);
+       tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
+       tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
+       location_t loc = gimple_location (stmt);
        gimple_seq stmts = NULL;
        /* Convert arg0 to unsigned.  */
        tree arg0_unsigned
          = gimple_build (&stmts, VIEW_CONVERT_EXPR,
                          unsigned_type_for (TREE_TYPE (arg0)), arg0);
+       /* Force arg1 into the range valid matching the arg0 type.  */
+       /* Build a vector consisting of the max valid bit-size values.  */
+       int n_elts = VECTOR_CST_NELTS (arg1);
+       tree element_size = build_int_cst (unsigned_element_type,
+                                          128 / n_elts);
+       tree_vector_builder elts (unsigned_arg1_type, n_elts, 1);
+       for (int i = 0; i < n_elts; i++)
+         elts.safe_push (element_size);
+       tree modulo_tree = elts.build ();
+       /* Modulo the provided shift value against that vector.  */
+       tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+                                          unsigned_arg1_type, arg1);
+       tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
+                                     unsigned_arg1_type, unsigned_arg1,
+                                     modulo_tree);
+       /* Do the shift.  */
        tree res
          = gimple_build (&stmts, RSHIFT_EXPR,
-                         TREE_TYPE (arg0_unsigned), arg0_unsigned, arg1);
+                         TREE_TYPE (arg0_unsigned), arg0_unsigned, new_arg1);
        /* Convert result back to the lhs type.  */
        res = gimple_build (&stmts, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), res);
        gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
@@ -15728,6 +15553,13 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
                                          arg1_type, temp_addr,
                                          build_int_cst (arg1_type, -16));
        gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+       if (!is_gimple_mem_ref_addr (aligned_addr))
+         {
+           tree t = make_ssa_name (TREE_TYPE (aligned_addr));
+           gimple *g = gimple_build_assign (t, aligned_addr);
+           gsi_insert_before (gsi, g, GSI_SAME_STMT);
+           aligned_addr = t;
+         }
        /* Use the build2 helper to set up the mem_ref.  The MEM_REF could also
           take an offset, but since we've already incorporated the offset
           above, here we just pass in a zero.  */
@@ -15773,6 +15605,13 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
                                          arg2_type, temp_addr,
                                          build_int_cst (arg2_type, -16));
        gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+       if (!is_gimple_mem_ref_addr (aligned_addr))
+         {
+           tree t = make_ssa_name (TREE_TYPE (aligned_addr));
+           gimple *g = gimple_build_assign (t, aligned_addr);
+           gsi_insert_before (gsi, g, GSI_SAME_STMT);
+           aligned_addr = t;
+         }
        /* The desired gimple result should be similar to:
           MEM[(__vector floatD.1407 *)_1] = vf1D.2697;  */
        gimple *g
@@ -15810,6 +15649,13 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
        tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
                                       arg1_type, arg1, temp_offset);
        gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+       if (!is_gimple_mem_ref_addr (temp_addr))
+         {
+           tree t = make_ssa_name (TREE_TYPE (temp_addr));
+           gimple *g = gimple_build_assign (t, temp_addr);
+           gsi_insert_before (gsi, g, GSI_SAME_STMT);
+           temp_addr = t;
+         }
        /* Use the build2 helper to set up the mem_ref.  The MEM_REF could also
           take an offset, but since we've already incorporated the offset
           above, here we just pass in a zero.  */
@@ -15846,6 +15692,13 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
        tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
                                       arg2_type, arg2, temp_offset);
        gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+       if (!is_gimple_mem_ref_addr (temp_addr))
+         {
+           tree t = make_ssa_name (TREE_TYPE (temp_addr));
+           gimple *g = gimple_build_assign (t, temp_addr);
+           gsi_insert_before (gsi, g, GSI_SAME_STMT);
+           temp_addr = t;
+         }
        gimple *g;
        g = gimple_build_assign (build2 (MEM_REF, align_stype, temp_addr,
                                         build_int_cst (arg2_type, 0)), arg0);
@@ -15923,22 +15776,13 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VSPLTISH:
     case ALTIVEC_BUILTIN_VSPLTISW:
       {
-       int size;
-       if (fn_code == ALTIVEC_BUILTIN_VSPLTISB)
-         size = 8;
-       else if (fn_code == ALTIVEC_BUILTIN_VSPLTISH)
-         size = 16;
-       else
-         size = 32;
-
        arg0 = gimple_call_arg (stmt, 0);
        lhs = gimple_call_lhs (stmt);
 
        /* Only fold the vec_splat_*() if the lower bits of arg 0 is a
           5-bit signed constant in range -16 to +15.  */
        if (TREE_CODE (arg0) != INTEGER_CST
-           || !IN_RANGE (sext_hwi (TREE_INT_CST_LOW (arg0), size),
-                         -16, 15))
+           || !IN_RANGE (TREE_INT_CST_LOW (arg0), -16, 15))
          return false;
        gimple_seq stmts = NULL;
        location_t loc = gimple_location (stmt);
@@ -17505,6 +17349,7 @@ builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0,
     {
     /* unsigned 1 argument functions.  */
     case CRYPTO_BUILTIN_VSBOX:
+    case CRYPTO_BUILTIN_VSBOX_BE:
     case P8V_BUILTIN_VGBBD:
     case MISC_BUILTIN_CDTBCD:
     case MISC_BUILTIN_CBCDTD:
@@ -17520,9 +17365,13 @@ builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0,
     case ALTIVEC_BUILTIN_VMULOUH:
     case P8V_BUILTIN_VMULOUW:
     case CRYPTO_BUILTIN_VCIPHER:
+    case CRYPTO_BUILTIN_VCIPHER_BE:
     case CRYPTO_BUILTIN_VCIPHERLAST:
+    case CRYPTO_BUILTIN_VCIPHERLAST_BE:
     case CRYPTO_BUILTIN_VNCIPHER:
+    case CRYPTO_BUILTIN_VNCIPHER_BE:
     case CRYPTO_BUILTIN_VNCIPHERLAST:
+    case CRYPTO_BUILTIN_VNCIPHERLAST_BE:
     case CRYPTO_BUILTIN_VPMSUMB:
     case CRYPTO_BUILTIN_VPMSUMH:
     case CRYPTO_BUILTIN_VPMSUMW:
@@ -18715,7 +18564,7 @@ int
 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
 {
   /* We might have been passed a SUBREG.  */
-  if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
+  if (!REG_P (reg1) || !REG_P (reg2))
     return 0;
 
   /* We might have been passed non floating point registers.  */
@@ -18748,18 +18597,18 @@ mems_ok_for_quad_peep (rtx mem1, rtx mem2)
   if (GET_CODE (addr1) == PLUS)
     {
       /* If not a REG, return zero.  */
-      if (GET_CODE (XEXP (addr1, 0)) != REG)
+      if (!REG_P (XEXP (addr1, 0)))
        return 0;
       else
        {
          reg1 = REGNO (XEXP (addr1, 0));
          /* The offset must be constant!  */
-         if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
+         if (!CONST_INT_P (XEXP (addr1, 1)))
            return 0;
          offset1 = INTVAL (XEXP (addr1, 1));
        }
     }
-  else if (GET_CODE (addr1) != REG)
+  else if (!REG_P (addr1))
     return 0;
   else
     {
@@ -18772,18 +18621,18 @@ mems_ok_for_quad_peep (rtx mem1, rtx mem2)
   if (GET_CODE (addr2) == PLUS)
     {
       /* If not a REG, return zero.  */
-      if (GET_CODE (XEXP (addr2, 0)) != REG)
+      if (!REG_P (XEXP (addr2, 0)))
        return 0;
       else
        {
          reg2 = REGNO (XEXP (addr2, 0));
          /* The offset must be constant. */
-         if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
+         if (!CONST_INT_P (XEXP (addr2, 1)))
            return 0;
          offset2 = INTVAL (XEXP (addr2, 1));
        }
     }
-  else if (GET_CODE (addr2) != REG)
+  else if (!REG_P (addr2))
     return 0;
   else
     {
@@ -18826,20 +18675,20 @@ register_to_reg_type (rtx reg, bool *is_altivec)
   HOST_WIDE_INT regno;
   enum reg_class rclass;
 
-  if (GET_CODE (reg) == SUBREG)
+  if (SUBREG_P (reg))
     reg = SUBREG_REG (reg);
 
   if (!REG_P (reg))
     return NO_REG_TYPE;
 
   regno = REGNO (reg);
-  if (regno >= FIRST_PSEUDO_REGISTER)
+  if (!HARD_REGISTER_NUM_P (regno))
     {
       if (!lra_in_progress && !reload_completed)
        return PSEUDO_REG_TYPE;
 
       regno = true_regnum (reg);
-      if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
+      if (regno < 0 || !HARD_REGISTER_NUM_P (regno))
        return PSEUDO_REG_TYPE;
     }
 
@@ -18975,7 +18824,7 @@ rs6000_secondary_reload_memory (rtx addr,
     case AND:
       and_arg = XEXP (addr, 0);
       if (GET_MODE_SIZE (mode) != 16
-         || GET_CODE (XEXP (addr, 1)) != CONST_INT
+         || !CONST_INT_P (XEXP (addr, 1))
          || INTVAL (XEXP (addr, 1)) != -16)
        {
          fail_msg = "bad Altivec AND #1";
@@ -19222,12 +19071,6 @@ rs6000_secondary_reload_simple_move (enum rs6000_reg_type to_type,
        return true;
     }
 
-  /* Power6+: MFTGPR or MFFGPR.  */
-  else if (TARGET_MFPGPR && TARGET_POWERPC64 && size == 8
-      && ((to_type == GPR_REG_TYPE && from_type == FPR_REG_TYPE)
-         || (to_type == FPR_REG_TYPE && from_type == GPR_REG_TYPE)))
-    return true;
-
   /* Move to/from SPR.  */
   else if ((size == 4 || (TARGET_POWERPC64 && size == 8))
           && ((to_type == GPR_REG_TYPE && from_type == SPR_REG_TYPE)
@@ -19387,7 +19230,7 @@ rs6000_secondary_reload (bool in_p,
 
   /* Allow subreg of memory before/during reload.  */
   bool memory_p = (MEM_P (x)
-                  || (!reload_completed && GET_CODE (x) == SUBREG
+                  || (!reload_completed && SUBREG_P (x)
                       && MEM_P (SUBREG_REG (x))));
 
   sri->icode = CODE_FOR_nothing;
@@ -19432,7 +19275,7 @@ rs6000_secondary_reload (bool in_p,
   if (!done_p && reg_addr[mode].scalar_in_vmx_p
       && !mode_supports_vmx_dform (mode)
       && (rclass == VSX_REGS || rclass == ALTIVEC_REGS)
-      && (memory_p || (GET_CODE (x) == CONST_DOUBLE)))
+      && (memory_p || CONST_DOUBLE_P (x)))
     {
       ret = FLOAT_REGS;
       default_p = false;
@@ -19647,7 +19490,7 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
   rtx cc_clobber;
   rtvec rv;
 
-  if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER || !MEM_P (mem)
+  if (regno < 0 || !HARD_REGISTER_NUM_P (regno) || !MEM_P (mem)
       || !base_reg_operand (scratch, GET_MODE (scratch)))
     rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p);
 
@@ -19714,7 +19557,7 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
       op1 = XEXP (addr, 1);
       if ((addr_mask & RELOAD_REG_AND_M16) == 0)
        {
-         if (REG_P (op0) || GET_CODE (op0) == SUBREG)
+         if (REG_P (op0) || SUBREG_P (op0))
            op_reg = op0;
 
          else if (GET_CODE (op1) == PLUS)
@@ -19875,8 +19718,8 @@ rs6000_secondary_reload_gpr (rtx reg, rtx mem, rtx scratch, bool store_p)
       debug_rtx (scratch);
     }
 
-  gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
-  gcc_assert (GET_CODE (mem) == MEM);
+  gcc_assert (regno >= 0 && HARD_REGISTER_NUM_P (regno));
+  gcc_assert (MEM_P (mem));
   rclass = REGNO_REG_CLASS (regno);
   gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
   addr = XEXP (mem, 0);
@@ -20015,7 +19858,7 @@ rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
       return NO_REGS;
     }
 
-  if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
+  if (GET_MODE_CLASS (mode) == MODE_INT && rclass == GEN_OR_FLOAT_REGS)
     return GENERAL_REGS;
 
   return rclass;
@@ -20111,27 +19954,27 @@ rs6000_secondary_reload_class (enum reg_class rclass, machine_mode mode,
         On Darwin, pic addresses require a load from memory, which
         needs a base register.  */
       if (rclass != BASE_REGS
-         && (GET_CODE (in) == SYMBOL_REF
+         && (SYMBOL_REF_P (in)
              || GET_CODE (in) == HIGH
              || GET_CODE (in) == LABEL_REF
              || GET_CODE (in) == CONST))
        return BASE_REGS;
     }
 
-  if (GET_CODE (in) == REG)
+  if (REG_P (in))
     {
       regno = REGNO (in);
-      if (regno >= FIRST_PSEUDO_REGISTER)
+      if (!HARD_REGISTER_NUM_P (regno))
        {
          regno = true_regnum (in);
-         if (regno >= FIRST_PSEUDO_REGISTER)
+         if (!HARD_REGISTER_NUM_P (regno))
            regno = -1;
        }
     }
-  else if (GET_CODE (in) == SUBREG)
+  else if (SUBREG_P (in))
     {
       regno = true_regnum (in);
-      if (regno >= FIRST_PSEUDO_REGISTER)
+      if (!HARD_REGISTER_NUM_P (regno))
        regno = -1;
     }
   else
@@ -20163,7 +20006,7 @@ rs6000_secondary_reload_class (enum reg_class rclass, machine_mode mode,
 
   /* Constants, memory, and FP registers can go into FP registers.  */
   if ((regno == -1 || FP_REGNO_P (regno))
-      && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
+      && (rclass == FLOAT_REGS || rclass == GEN_OR_FLOAT_REGS))
     return (mode != SDmode || lra_in_progress) ? NO_REGS : GENERAL_REGS;
 
   /* Memory, and AltiVec registers can go into AltiVec registers.  */
@@ -20450,9 +20293,9 @@ rs6000_output_move_128bit (rtx operands[])
 
   /* Constants.  */
   else if (dest_regno >= 0
-          && (GET_CODE (src) == CONST_INT
-              || GET_CODE (src) == CONST_WIDE_INT
-              || GET_CODE (src) == CONST_DOUBLE
+          && (CONST_INT_P (src)
+              || CONST_WIDE_INT_P (src)
+              || CONST_DOUBLE_P (src)
               || GET_CODE (src) == CONST_VECTOR))
     {
       if (dest_gpr_p)
@@ -20514,7 +20357,8 @@ ccr_bit (rtx op, int scc_p)
 
   reg = XEXP (op, 0);
 
-  gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
+  if (!REG_P (reg) || !CR_REGNO_P (REGNO (reg)))
+    return -1;
 
   cc_mode = GET_MODE (reg);
   cc_regnum = REGNO (reg);
@@ -20524,9 +20368,19 @@ ccr_bit (rtx op, int scc_p)
 
   /* When generating a sCOND operation, only positive conditions are
      allowed.  */
-  gcc_assert (!scc_p
-             || code == EQ || code == GT || code == LT || code == UNORDERED
-             || code == GTU || code == LTU);
+  if (scc_p)
+    switch (code)
+      {
+      case EQ:
+      case GT:
+      case LT:
+      case UNORDERED:
+      case GTU:
+      case LTU:
+       break;
+      default:
+       return -1;
+      }
 
   switch (code)
     {
@@ -20551,7 +20405,7 @@ ccr_bit (rtx op, int scc_p)
       return scc_p ? base_bit + 3 : base_bit + 1;
 
     default:
-      gcc_unreachable ();
+      return -1;
     }
 }
 \f
@@ -20585,7 +20439,7 @@ rs6000_init_machine_status (void)
   return ggc_cleared_alloc<machine_function> ();
 }
 \f
-#define INT_P(X) (GET_CODE (X) == CONST_INT && GET_MODE (X) == VOIDmode)
+#define INT_P(X) (CONST_INT_P (X) && GET_MODE (X) == VOIDmode)
 
 /* Write out a function code label.  */
 
@@ -20644,7 +20498,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'D':
       /* Like 'J' but get to the GT bit only.  */
-      if (!REG_P (x))
+      if (!REG_P (x) || !CR_REGNO_P (REGNO (x)))
        {
          output_operand_lossage ("invalid %%D value");
          return;
@@ -20672,7 +20526,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'E':
       /* X is a CR register.  Print the number of the EQ bit of the CR */
-      if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
+      if (!REG_P (x) || !CR_REGNO_P (REGNO (x)))
        output_operand_lossage ("invalid %%E value");
       else
        fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
@@ -20681,7 +20535,7 @@ print_operand (FILE *file, rtx x, int code)
     case 'f':
       /* X is a CR register.  Print the shift count needed to move it
         to the high-order four bits.  */
-      if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
+      if (!REG_P (x) || !CR_REGNO_P (REGNO (x)))
        output_operand_lossage ("invalid %%f value");
       else
        fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
@@ -20690,7 +20544,7 @@ print_operand (FILE *file, rtx x, int code)
     case 'F':
       /* Similar, but print the count for the rotate in the opposite
         direction.  */
-      if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
+      if (!REG_P (x) || !CR_REGNO_P (REGNO (x)))
        output_operand_lossage ("invalid %%F value");
       else
        fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
@@ -20699,7 +20553,7 @@ print_operand (FILE *file, rtx x, int code)
     case 'G':
       /* X is a constant integer.  If it is negative, print "m",
         otherwise print "z".  This is to make an aze or ame insn.  */
-      if (GET_CODE (x) != CONST_INT)
+      if (!CONST_INT_P (x))
        output_operand_lossage ("invalid %%G value");
       else if (INTVAL (x) >= 0)
        putc ('z', file);
@@ -20767,9 +20621,9 @@ print_operand (FILE *file, rtx x, int code)
       if (GET_CODE (x) == CONST)
        {
          if (GET_CODE (XEXP (x, 0)) != PLUS
-             || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
+             || (!SYMBOL_REF_P (XEXP (XEXP (x, 0), 0))
                  && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
-             || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
+             || !CONST_INT_P (XEXP (XEXP (x, 0), 1)))
            output_operand_lossage ("invalid %%K value");
        }
       print_operand_address (file, x);
@@ -20835,7 +20689,7 @@ print_operand (FILE *file, rtx x, int code)
     case 'P':
       /* The operand must be an indirect memory reference.  The result
         is the register name.  */
-      if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
+      if (!MEM_P (x) || !REG_P (XEXP (x, 0))
          || REGNO (XEXP (x, 0)) >= 32)
        output_operand_lossage ("invalid %%P value");
       else
@@ -20888,7 +20742,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'R':
       /* X is a CR register.  Print the mask for `mtcrf'.  */
-      if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
+      if (!REG_P (x) || !CR_REGNO_P (REGNO (x)))
        output_operand_lossage ("invalid %%R value");
       else
        fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
@@ -20904,7 +20758,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 't':
       /* Like 'J' but get to the OVERFLOW/UNORDERED bit.  */
-      if (!REG_P (x) || GET_MODE (x) != CCmode)
+      if (!REG_P (x) || !CR_REGNO_P (REGNO (x)))
        {
          output_operand_lossage ("invalid %%t value");
          return;
@@ -20919,8 +20773,10 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'T':
       /* Print the symbolic name of a branch target register.  */
-      if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
-                                 && REGNO (x) != CTR_REGNO))
+      if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PLTSEQ)
+       x = XVECEXP (x, 0, 0);
+      if (!REG_P (x) || (REGNO (x) != LR_REGNO
+                        && REGNO (x) != CTR_REGNO))
        output_operand_lossage ("invalid %%T value");
       else if (REGNO (x) == LR_REGNO)
        fputs ("lr", file);
@@ -21013,7 +20869,7 @@ print_operand (FILE *file, rtx x, int code)
 
     case 'x':
       /* X is a FPR or Altivec register used in a VSX context.  */
-      if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
+      if (!REG_P (x) || !VSX_REGNO_P (REGNO (x)))
        output_operand_lossage ("invalid %%x value");
       else
        {
@@ -21062,6 +20918,8 @@ print_operand (FILE *file, rtx x, int code)
       return;
 
     case 'z':
+      if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PLTSEQ)
+       x = XVECEXP (x, 0, 1);
       /* X is a SYMBOL_REF.  Write out the name preceded by a
         period and without any trailing data in brackets.  Used for function
         names.  If we are configured for System V (or the embedded ABI) on
@@ -21124,7 +20982,7 @@ print_operand (FILE *file, rtx x, int code)
 
        if (VECTOR_MEM_ALTIVEC_OR_VSX_P (GET_MODE (x))
            && GET_CODE (tmp) == AND
-           && GET_CODE (XEXP (tmp, 1)) == CONST_INT
+           && CONST_INT_P (XEXP (tmp, 1))
            && INTVAL (XEXP (tmp, 1)) == -16)
          tmp = XEXP (tmp, 0);
        else if (VECTOR_MEM_VSX_P (GET_MODE (x))
@@ -21170,19 +21028,21 @@ print_operand (FILE *file, rtx x, int code)
          else
            output_address (GET_MODE (x), XEXP (x, 0));
        }
+      else if (toc_relative_expr_p (x, false,
+                                   &tocrel_base_oac, &tocrel_offset_oac))
+       /* This hack along with a corresponding hack in
+          rs6000_output_addr_const_extra arranges to output addends
+          where the assembler expects to find them.  eg.
+          (plus (unspec [(symbol_ref ("x")) (reg 2)] tocrel) 4)
+          without this hack would be output as "x@toc+4".  We
+          want "x+4@toc".  */
+       output_addr_const (file, CONST_CAST_RTX (tocrel_base_oac));
+      else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
+       output_addr_const (file, XVECEXP (x, 0, 0));
+      else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PLTSEQ)
+       output_addr_const (file, XVECEXP (x, 0, 1));
       else
-       {
-         if (toc_relative_expr_p (x, false, &tocrel_base_oac, &tocrel_offset_oac))
-           /* This hack along with a corresponding hack in
-              rs6000_output_addr_const_extra arranges to output addends
-              where the assembler expects to find them.  eg.
-              (plus (unspec [(symbol_ref ("x")) (reg 2)] tocrel) 4)
-              without this hack would be output as "x@toc+4".  We
-              want "x+4@toc".  */
-           output_addr_const (file, CONST_CAST_RTX (tocrel_base_oac));
-         else
-           output_addr_const (file, x);
-       }
+       output_addr_const (file, x);
       return;
 
     case '&':
@@ -21205,7 +21065,31 @@ print_operand_address (FILE *file, rtx x)
 {
   if (REG_P (x))
     fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
-  else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
+
+  /* Is it a pc-relative address?  */
+  else if (pcrel_address (x, Pmode))
+    {
+      HOST_WIDE_INT offset;
+
+      if (GET_CODE (x) == CONST)
+       x = XEXP (x, 0);
+
+      if (GET_CODE (x) == PLUS)
+       {
+         offset = INTVAL (XEXP (x, 1));
+         x = XEXP (x, 0);
+       }
+      else
+       offset = 0;
+
+      output_addr_const (file, x);
+
+      if (offset)
+       fprintf (file, "%+" PRId64, offset);
+
+      fputs ("@pcrel", file);
+    }
+  else if (SYMBOL_REF_P (x) || GET_CODE (x) == CONST
           || GET_CODE (x) == LABEL_REF)
     {
       output_addr_const (file, x);
@@ -21226,7 +21110,7 @@ print_operand_address (FILE *file, rtx x)
                 reg_names[ REGNO (XEXP (x, 1)) ]);
     }
   else if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0))
-          && GET_CODE (XEXP (x, 1)) == CONST_INT)
+          && CONST_INT_P (XEXP (x, 1)))
     fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
             INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
 #if TARGET_MACHO
@@ -21274,7 +21158,7 @@ rs6000_output_addr_const_extra (FILE *file, rtx x)
     switch (XINT (x, 1))
       {
       case UNSPEC_TOCREL:
-       gcc_checking_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF
+       gcc_checking_assert (SYMBOL_REF_P (XVECEXP (x, 0, 0))
                             && REG_P (XVECEXP (x, 0, 1))
                             && REGNO (XVECEXP (x, 0, 1)) == TOC_REGISTER);
        output_addr_const (file, XVECEXP (x, 0, 0));
@@ -21351,7 +21235,7 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
       /* Remove initial .'s to turn a -mcall-aixdesc function
         address into the address of the descriptor, not the function
         itself.  */
-      else if (GET_CODE (x) == SYMBOL_REF
+      else if (SYMBOL_REF_P (x)
               && XSTR (x, 0)[0] == '.'
               && DEFAULT_ABI == ABI_AIX)
        {
@@ -21368,18 +21252,27 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
 }
 
 /* Return a template string for assembly to emit when making an
-   external call.  FUNOP is the call mem argument operand number,
-   ARG is either NULL or a @TLSGD or @TLSLD __tls_get_addr argument
-   specifier.  */
+   external call.  FUNOP is the call mem argument operand number.  */
 
 static const char *
-rs6000_call_template_1 (rtx *operands ATTRIBUTE_UNUSED, unsigned int funop,
-                       bool sibcall, const char *arg)
+rs6000_call_template_1 (rtx *operands, unsigned int funop, bool sibcall)
 {
   /* -Wformat-overflow workaround, without which gcc thinks that %u
       might produce 10 digits.  */
   gcc_assert (funop <= MAX_RECOG_OPERANDS);
 
+  char arg[12];
+  arg[0] = 0;
+  if (TARGET_TLS_MARKERS && GET_CODE (operands[funop + 1]) == UNSPEC)
+    {
+      if (XINT (operands[funop + 1], 1) == UNSPEC_TLSGD)
+       sprintf (arg, "(%%%u@tlsgd)", funop + 1);
+      else if (XINT (operands[funop + 1], 1) == UNSPEC_TLSLD)
+       sprintf (arg, "(%%&@tlsld)");
+      else
+       gcc_unreachable ();
+    }
+
   /* The magic 32768 offset here corresponds to the offset of
      r30 in .got2, as given by LCTOC1.  See sysv4.h:toc_section.  */
   char z[11];
@@ -21387,28 +21280,57 @@ rs6000_call_template_1 (rtx *operands ATTRIBUTE_UNUSED, unsigned int funop,
           (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic == 2
            ? "+32768" : ""));
 
-  static char str[32];  /* 4 spare */
-  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+  static char str[32];  /* 1 spare */
+  if (rs6000_pcrel_p (cfun))
+    sprintf (str, "b%s %s@notoc%s", sibcall ? "" : "l", z, arg);
+  else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
     sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg,
             sibcall ? "" : "\n\tnop");
   else if (DEFAULT_ABI == ABI_V4)
     sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg,
             flag_pic ? "@plt" : "");
+#if TARGET_MACHO
+  /* If/when we remove the mlongcall opt, we can share the AIX/ELGv2 case. */
+   else if (DEFAULT_ABI == ABI_DARWIN)
+    {
+      /* The cookie is in operand func+2.  */
+      gcc_checking_assert (GET_CODE (operands[funop + 2]) == CONST_INT);
+      int cookie = INTVAL (operands[funop + 2]);
+      if (cookie & CALL_LONG)
+       {
+         tree funname = get_identifier (XSTR (operands[funop], 0));
+         tree labelname = get_prev_label (funname);
+         gcc_checking_assert (labelname && !sibcall);
+
+         /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
+            instruction will reach 'foo', otherwise link as 'bl L42'".
+            "L42" should be a 'branch island', that will do a far jump to
+            'foo'.  Branch islands are generated in
+            macho_branch_islands().  */
+         sprintf (str, "jbsr %%z%u,%.10s", funop,
+                  IDENTIFIER_POINTER (labelname));
+       }
+      else
+        /* Same as AIX or ELFv2, except to keep backwards compat, no nop
+          after the call.  */
+       sprintf (str, "b%s %s%s", sibcall ? "" : "l", z, arg);
+    }
+#endif
   else
     gcc_unreachable ();
   return str;
 }
 
 const char *
-rs6000_call_template (rtx *operands, unsigned int funop, const char *arg)
+rs6000_call_template (rtx *operands, unsigned int funop)
 {
-  return rs6000_call_template_1 (operands, funop, false, arg);
+  return rs6000_call_template_1 (operands, funop, false);
 }
 
 const char *
-rs6000_sibcall_template (rtx *operands, unsigned int funop, const char *arg)
+rs6000_sibcall_template (rtx *operands, unsigned int funop)
 {
-  return rs6000_call_template_1 (operands, funop, true, arg);
+  return rs6000_call_template_1 (operands, funop, true);
 }
 
 /* As above, for indirect calls.  */
@@ -21418,12 +21340,65 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop,
                                 bool sibcall)
 {
   /* -Wformat-overflow workaround, without which gcc thinks that %u
-      might produce 10 digits.  */
+     might produce 10 digits.  Note that -Wformat-overflow will not
+     currently warn here for str[], so do not rely on a warning to
+     ensure str[] is correctly sized.  */
   gcc_assert (funop <= MAX_RECOG_OPERANDS);
 
-  static char str[144];
+  /* Currently, funop is either 0 or 1.  The maximum string is always
+     a !speculate 64-bit __tls_get_addr call.
+
+     ABI_ELFv2, pcrel:
+     . 27      .reloc .,R_PPC64_TLSGD,%2\n\t
+     . 35      .reloc .,R_PPC64_PLTSEQ_NOTOC,%z1\n\t
+     .  9      crset 2\n\t
+     . 27      .reloc .,R_PPC64_TLSGD,%2\n\t
+     . 36      .reloc .,R_PPC64_PLTCALL_NOTOC,%z1\n\t
+     .  8      beq%T1l-
+     .---
+     .142
+
+     ABI_AIX:
+     .  9      ld 2,%3\n\t
+     . 27      .reloc .,R_PPC64_TLSGD,%2\n\t
+     . 29      .reloc .,R_PPC64_PLTSEQ,%z1\n\t
+     .  9      crset 2\n\t
+     . 27      .reloc .,R_PPC64_TLSGD,%2\n\t
+     . 30      .reloc .,R_PPC64_PLTCALL,%z1\n\t
+     . 10      beq%T1l-\n\t
+     . 10      ld 2,%4(1)
+     .---
+     .151
+
+     ABI_ELFv2:
+     . 27      .reloc .,R_PPC64_TLSGD,%2\n\t
+     . 29      .reloc .,R_PPC64_PLTSEQ,%z1\n\t
+     .  9      crset 2\n\t
+     . 27      .reloc .,R_PPC64_TLSGD,%2\n\t
+     . 30      .reloc .,R_PPC64_PLTCALL,%z1\n\t
+     . 10      beq%T1l-\n\t
+     . 10      ld 2,%3(1)
+     .---
+     .142
+
+     ABI_V4:
+     . 27      .reloc .,R_PPC64_TLSGD,%2\n\t
+     . 35      .reloc .,R_PPC64_PLTSEQ,%z1+32768\n\t
+     .  9      crset 2\n\t
+     . 27      .reloc .,R_PPC64_TLSGD,%2\n\t
+     . 36      .reloc .,R_PPC64_PLTCALL,%z1+32768\n\t
+     .  8      beq%T1l-
+     .---
+     .141  */
+  static char str[160];  /* 8 spare */
+  char *s = str;
   const char *ptrload = TARGET_64BIT ? "d" : "wz";
 
+  if (DEFAULT_ABI == ABI_AIX)
+    s += sprintf (s,
+                 "l%s 2,%%%u\n\t",
+                 ptrload, funop + 2);
+
   /* We don't need the extra code to stop indirect call speculation if
      calling via LR.  */
   bool speculate = (TARGET_MACHO
@@ -21431,32 +21406,69 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop,
                    || (REG_P (operands[funop])
                        && REGNO (operands[funop]) == LR_REGNO));
 
-  if (DEFAULT_ABI == ABI_AIX)
+  if (TARGET_PLTSEQ && GET_CODE (operands[funop]) == UNSPEC)
+    {
+      const char *rel64 = TARGET_64BIT ? "64" : "";
+      char tls[29];
+      tls[0] = 0;
+      if (TARGET_TLS_MARKERS && GET_CODE (operands[funop + 1]) == UNSPEC)
+       {
+         if (XINT (operands[funop + 1], 1) == UNSPEC_TLSGD)
+           sprintf (tls, ".reloc .,R_PPC%s_TLSGD,%%%u\n\t",
+                    rel64, funop + 1);
+         else if (XINT (operands[funop + 1], 1) == UNSPEC_TLSLD)
+           sprintf (tls, ".reloc .,R_PPC%s_TLSLD,%%&\n\t",
+                    rel64);
+         else
+           gcc_unreachable ();
+       }
+
+      const char *notoc = rs6000_pcrel_p (cfun) ? "_NOTOC" : "";
+      const char *addend = (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT
+                           && flag_pic == 2 ? "+32768" : "");
+      if (!speculate)
+       {
+         s += sprintf (s,
+                       "%s.reloc .,R_PPC%s_PLTSEQ%s,%%z%u%s\n\t",
+                       tls, rel64, notoc, funop, addend);
+         s += sprintf (s, "crset 2\n\t");
+       }
+      s += sprintf (s,
+                   "%s.reloc .,R_PPC%s_PLTCALL%s,%%z%u%s\n\t",
+                   tls, rel64, notoc, funop, addend);
+    }
+  else if (!speculate)
+    s += sprintf (s, "crset 2\n\t");
+
+  if (rs6000_pcrel_p (cfun))
     {
       if (speculate)
-       sprintf (str,
-                "l%s 2,%%%u\n\t"
+       sprintf (s, "b%%T%ul", funop);
+      else
+       sprintf (s, "beq%%T%ul-", funop);
+    }
+  else if (DEFAULT_ABI == ABI_AIX)
+    {
+      if (speculate)
+       sprintf (s,
                 "b%%T%ul\n\t"
                 "l%s 2,%%%u(1)",
-                ptrload, funop + 2, funop, ptrload, funop + 3);
+                funop, ptrload, funop + 3);
       else
-       sprintf (str,
-                "crset 2\n\t"
-                "l%s 2,%%%u\n\t"
+       sprintf (s,
                 "beq%%T%ul-\n\t"
                 "l%s 2,%%%u(1)",
-                ptrload, funop + 2, funop, ptrload, funop + 3);
+                funop, ptrload, funop + 3);
     }
   else if (DEFAULT_ABI == ABI_ELFv2)
     {
       if (speculate)
-       sprintf (str,
+       sprintf (s,
                 "b%%T%ul\n\t"
                 "l%s 2,%%%u(1)",
                 funop, ptrload, funop + 2);
       else
-       sprintf (str,
-                "crset 2\n\t"
+       sprintf (s,
                 "beq%%T%ul-\n\t"
                 "l%s 2,%%%u(1)",
                 funop, ptrload, funop + 2);
@@ -21464,12 +21476,11 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop,
   else
     {
       if (speculate)
-       sprintf (str,
+       sprintf (s,
                 "b%%T%u%s",
                 funop, sibcall ? "" : "l");
       else
-       sprintf (str,
-                "crset 2\n\t"
+       sprintf (s,
                 "beq%%T%u%s-%s",
                 funop, sibcall ? "" : "l", sibcall ? "\n\tb $" : "");
     }
@@ -21488,6 +21499,145 @@ rs6000_indirect_sibcall_template (rtx *operands, unsigned int funop)
   return rs6000_indirect_call_template_1 (operands, funop, true);
 }
 
+#if HAVE_AS_PLTSEQ
+/* Output indirect call insns.  WHICH identifies the type of sequence.  */
+const char *
+rs6000_pltseq_template (rtx *operands, int which)
+{
+  const char *rel64 = TARGET_64BIT ? "64" : "";
+  char tls[30];
+  tls[0] = 0;
+  if (TARGET_TLS_MARKERS && GET_CODE (operands[3]) == UNSPEC)
+    {
+      char off = which == RS6000_PLTSEQ_PLT_PCREL34 ? '8' : '4';
+      if (XINT (operands[3], 1) == UNSPEC_TLSGD)
+       sprintf (tls, ".reloc .-%c,R_PPC%s_TLSGD,%%3\n\t",
+                off, rel64);
+      else if (XINT (operands[3], 1) == UNSPEC_TLSLD)
+       sprintf (tls, ".reloc .-%c,R_PPC%s_TLSLD,%%&\n\t",
+                off, rel64);
+      else
+       gcc_unreachable ();
+    }
+
+  gcc_assert (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4);
+  static char str[96];  /* 10 spare */
+  char off = WORDS_BIG_ENDIAN ? '2' : '4';
+  const char *addend = (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT
+                       && flag_pic == 2 ? "+32768" : "");
+  switch (which)
+    {
+    case RS6000_PLTSEQ_TOCSAVE:
+      sprintf (str,
+              "st%s\n\t"
+              "%s.reloc .-4,R_PPC%s_PLTSEQ,%%z2",
+              TARGET_64BIT ? "d 2,24(1)" : "w 2,12(1)",
+              tls, rel64);
+      break;
+    case RS6000_PLTSEQ_PLT16_HA:
+      if (DEFAULT_ABI == ABI_V4 && !flag_pic)
+       sprintf (str,
+                "lis %%0,0\n\t"
+                "%s.reloc .-%c,R_PPC%s_PLT16_HA,%%z2",
+                tls, off, rel64);
+      else
+       sprintf (str,
+                "addis %%0,%%1,0\n\t"
+                "%s.reloc .-%c,R_PPC%s_PLT16_HA,%%z2%s",
+                tls, off, rel64, addend);
+      break;
+    case RS6000_PLTSEQ_PLT16_LO:
+      sprintf (str,
+              "l%s %%0,0(%%1)\n\t"
+              "%s.reloc .-%c,R_PPC%s_PLT16_LO%s,%%z2%s",
+              TARGET_64BIT ? "d" : "wz",
+              tls, off, rel64, TARGET_64BIT ? "_DS" : "", addend);
+      break;
+    case RS6000_PLTSEQ_MTCTR:
+      sprintf (str,
+              "mtctr %%1\n\t"
+              "%s.reloc .-4,R_PPC%s_PLTSEQ,%%z2%s",
+              tls, rel64, addend);
+      break;
+    case RS6000_PLTSEQ_PLT_PCREL34:
+      sprintf (str,
+              "pl%s %%0,0(0),1\n\t"
+              "%s.reloc .-8,R_PPC%s_PLT_PCREL34_NOTOC,%%z2",
+              TARGET_64BIT ? "d" : "wz",
+              tls, rel64);
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  return str;
+}
+#endif
+
+/* Helper function to return whether a MODE can do prefixed loads/stores.
+   VOIDmode is used when we are loading the pc-relative address into a base
+   register, but we are not using it as part of a memory operation.  As modes
+   add support for prefixed memory, they will be added here.  */
+
+static bool
+mode_supports_prefixed_address_p (machine_mode mode)
+{
+  return mode == VOIDmode;
+}
+
+/* Function to return true if ADDR is a valid prefixed memory address that uses
+   mode MODE.  */
+
+bool
+rs6000_prefixed_address (rtx addr, machine_mode mode)
+{
+  if (!TARGET_PREFIXED_ADDR || !mode_supports_prefixed_address_p (mode))
+    return false;
+
+  /* Check for PC-relative addresses.  */
+  if (pcrel_address (addr, Pmode))
+    return true;
+
+  /* Check for prefixed memory addresses that have a large numeric offset,
+     or an offset that can't be used for a DS/DQ-form memory operation.  */
+  if (GET_CODE (addr) == PLUS)
+    {
+      rtx op0 = XEXP (addr, 0);
+      rtx op1 = XEXP (addr, 1);
+
+      if (!base_reg_operand (op0, Pmode) || !CONST_INT_P (op1))
+       return false;
+
+      HOST_WIDE_INT value = INTVAL (op1);
+      if (!SIGNED_34BIT_OFFSET_P (value, 0))
+       return false;
+
+      /* Offset larger than 16-bits?  */
+      if (!SIGNED_16BIT_OFFSET_P (value, 0))
+       return true;
+
+      /* DQ instruction (bottom 4 bits must be 0) for vectors.  */
+      HOST_WIDE_INT mask;
+      if (GET_MODE_SIZE (mode) >= 16)
+       mask = 15;
+
+      /* DS instruction (bottom 2 bits must be 0).  For 32-bit integers, we
+        need to use DS instructions if we are sign-extending the value with
+        LWA.  For 32-bit floating point, we need DS instructions to load and
+        store values to the traditional Altivec registers.  */
+      else if (GET_MODE_SIZE (mode) >= 4)
+       mask = 3;
+
+      /* QImode/HImode has no restrictions.  */
+      else
+       return true;
+
+      /* Return true if we must use a prefixed instruction.  */
+      return (value & mask) != 0;
+    }
+
+  return false;
+}
+\f
 #if defined (HAVE_GAS_HIDDEN) && !TARGET_MACHO
 /* Emit an assembler directive to set symbol visibility for DECL to
    VISIBILITY_TYPE.  */
@@ -21567,7 +21717,7 @@ rs6000_generate_compare (rtx cmp, machine_mode mode)
 
   /* If we have an unsigned compare, make sure we don't have a signed value as
      an immediate.  */
-  if (comp_mode == CCUNSmode && GET_CODE (op1) == CONST_INT
+  if (comp_mode == CCUNSmode && CONST_INT_P (op1)
       && INTVAL (op1) < 0)
     {
       op0 = copy_rtx_if_shared (op0);
@@ -22714,7 +22864,7 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
      would treat EQ different to UNORDERED, we can't do it.  */
   if (HONOR_INFINITIES (compare_mode)
       && code != GT && code != UNGE
-      && (GET_CODE (op1) != CONST_DOUBLE
+      && (!CONST_DOUBLE_P (op1)
          || real_isinf (CONST_DOUBLE_REAL_VALUE (op1)))
       /* Constructs of the form (a OP b ? a : b) are safe.  */
       && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
@@ -23599,7 +23749,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
                  emit_insn (TARGET_32BIT
                             ? (TARGET_POWERPC64
                                ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
-                               : gen_movsi_update (breg, breg, delta_rtx, nsrc))
+                               : gen_movsi_si_update (breg, breg, delta_rtx, nsrc))
                             : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
                  used_update = true;
                }
@@ -23680,22 +23830,31 @@ rs6000_split_multireg_move (rtx dst, rtx src)
 static bool
 save_reg_p (int reg)
 {
-  /* We need to mark the PIC offset register live for the same conditions
-     as it is set up, or otherwise it won't be saved before we clobber it.  */
-
   if (reg == RS6000_PIC_OFFSET_TABLE_REGNUM && !TARGET_SINGLE_PIC_BASE)
     {
       /* When calling eh_return, we must return true for all the cases
         where conditional_register_usage marks the PIC offset reg
-        call used.  */
+        call used or fixed.  */
+      if (crtl->calls_eh_return
+         && ((DEFAULT_ABI == ABI_V4 && flag_pic)
+             || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
+             || (TARGET_TOC && TARGET_MINIMAL_TOC)))
+       return true;
+
+      /* We need to mark the PIC offset register live for the same
+        conditions as it is set up in rs6000_emit_prologue, or
+        otherwise it won't be saved before we clobber it.  */
       if (TARGET_TOC && TARGET_MINIMAL_TOC
-         && (crtl->calls_eh_return
-             || df_regs_ever_live_p (reg)
-             || !constant_pool_empty_p ()))
+         && !constant_pool_empty_p ())
        return true;
 
-      if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN)
-         && flag_pic)
+      if (DEFAULT_ABI == ABI_V4
+         && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
+         && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
+       return true;
+
+      if (DEFAULT_ABI == ABI_DARWIN
+         && flag_pic && crtl->uses_pic_offset_table)
        return true;
     }
 
@@ -23715,13 +23874,6 @@ first_reg_to_save (void)
     if (save_reg_p (first_reg))
       break;
 
-#if TARGET_MACHO
-  if (flag_pic
-      && crtl->uses_pic_offset_table
-      && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
-    return RS6000_PIC_OFFSET_TABLE_REGNUM;
-#endif
-
   return first_reg;
 }
 
@@ -24625,6 +24777,9 @@ debug_stack_info (rs6000_stack_t *info)
 
     fprintf (stderr, "\tsave-strategy       =  %04x\n", info->savres_strategy);
 
+  if (info->abi == ABI_DARWIN)
+    fprintf (stderr, "\tWORLD_SAVE_P        = %5d\n", WORLD_SAVE_P(info));
+
   fprintf (stderr, "\n");
 }
 
@@ -24654,6 +24809,52 @@ rs6000_return_addr (int count, rtx frame)
   return get_hard_reg_initial_val (Pmode, LR_REGNO);
 }
 
+/* Helper function for rs6000_function_ok_for_sibcall.  */
+
+static bool
+rs6000_decl_ok_for_sibcall (tree decl)
+{
+  /* Sibcalls are always fine for the Darwin ABI.  */
+  if (DEFAULT_ABI == ABI_DARWIN)
+    return true;
+
+  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+    {
+      /* Under the AIX or ELFv2 ABIs we can't allow calls to non-local
+        functions, because the callee may have a different TOC pointer to
+        the caller and there's no way to ensure we restore the TOC when
+        we return.  */
+      if (!decl || DECL_EXTERNAL (decl) || DECL_WEAK (decl)
+         || !(*targetm.binds_local_p) (decl))
+       return false;
+
+      /* Similarly, if the caller preserves the TOC pointer and the callee
+        doesn't (or vice versa), proper TOC setup or restoration will be
+        missed.  For example, suppose A, B, and C are in the same binary
+        and A -> B -> C.  A and B preserve the TOC pointer but C does not,
+        and B -> C is eligible as a sibcall.  A will call B through its
+        local entry point, so A will not restore its TOC itself.  B calls
+        C with a sibcall, so it will not restore the TOC.  C does not
+        preserve the TOC, so it may clobber r2 with impunity.  Returning
+        from C will result in a corrupted TOC for A.  */
+      else if (rs6000_fndecl_pcrel_p (decl) != rs6000_pcrel_p (cfun))
+       return false;
+
+      else
+       return true;
+    }
+
+  /*  With the secure-plt SYSV ABI we can't make non-local calls when
+      -fpic/PIC because the plt call stubs use r30.  */
+  if (DEFAULT_ABI != ABI_V4
+      || (TARGET_SECURE_PLT
+         && flag_pic
+         && (!decl || !((*targetm.binds_local_p) (decl)))))
+    return false;
+
+  return true;
+}
+
 /* Say whether a function is a candidate for sibcall handling or not.  */
 
 static bool
@@ -24699,22 +24900,7 @@ rs6000_function_ok_for_sibcall (tree decl, tree exp)
        return false;
     }
 
-  /* Under the AIX or ELFv2 ABIs we can't allow calls to non-local
-     functions, because the callee may have a different TOC pointer to
-     the caller and there's no way to ensure we restore the TOC when
-     we return.  With the secure-plt SYSV ABI we can't make non-local
-     calls when -fpic/PIC because the plt call stubs use r30.  */
-  if (DEFAULT_ABI == ABI_DARWIN
-      || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
-         && decl
-         && !DECL_EXTERNAL (decl)
-         && !DECL_WEAK (decl)
-         && (*targetm.binds_local_p) (decl))
-      || (DEFAULT_ABI == ABI_V4
-         && (!TARGET_SECURE_PLT
-             || !flag_pic
-             || (decl
-                 && (*targetm.binds_local_p) (decl)))))
+  if (rs6000_decl_ok_for_sibcall (decl))
     {
       tree attr_list = TYPE_ATTRIBUTES (fntype);
 
@@ -24978,7 +25164,7 @@ create_TOC_reference (rtx symbol, rtx largetoc_reg)
 
   if (TARGET_DEBUG_ADDR)
     {
-      if (GET_CODE (symbol) == SYMBOL_REF)
+      if (SYMBOL_REF_P (symbol))
        fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
                 XSTR (symbol, 0));
       else
@@ -25073,16 +25259,16 @@ rs6000_emit_allocate_stack_1 (HOST_WIDE_INT size_int, rtx orig_sp)
       size_rtx = tmp_reg;
     }
   
-  if (Pmode == SImode)
+  if (TARGET_32BIT)
     insn = emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
                                              stack_pointer_rtx,
                                              size_rtx,
                                              orig_sp));
   else
-    insn = emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
-                                                stack_pointer_rtx,
-                                                size_rtx,
-                                                orig_sp));
+    insn = emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
+                                             stack_pointer_rtx,
+                                             size_rtx,
+                                             orig_sp));
   rtx par = PATTERN (insn);
   gcc_assert (GET_CODE (par) == PARALLEL);
   rtx set = XVECEXP (par, 0, 0);
@@ -25290,7 +25476,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off)
          emit_insn (insn);
          emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg, const0_rtx));
        }
-      else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
+      else if (SYMBOL_REF_P (stack_limit_rtx)
               && TARGET_32BIT
               && DEFAULT_ABI == ABI_V4
               && !flag_pic)
@@ -25683,8 +25869,7 @@ generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
     if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
       {
        if (!epiloguep || call_used_regs [i])
-         clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
-                                            gen_rtx_REG (V4SImode, i));
+         clobs[nclobs++] = gen_hard_reg_clobber (V4SImode, i);
        else
          {
            rtx reg = gen_rtx_REG (V4SImode, i);
@@ -26008,8 +26193,7 @@ rs6000_emit_savres_rtx (rs6000_stack_t *info,
   if (!(sel & SAVRES_SAVE) && (sel & SAVRES_LR))
     RTVEC_ELT (p, offset++) = ret_rtx;
 
-  RTVEC_ELT (p, offset++)
-    = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO));
+  RTVEC_ELT (p, offset++) = gen_hard_reg_clobber (Pmode, LR_REGNO);
 
   sym = rs6000_savres_routine_sym (info, sel);
   RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
@@ -26018,8 +26202,7 @@ rs6000_emit_savres_rtx (rs6000_stack_t *info,
   if ((sel & SAVRES_REG) == SAVRES_VR)
     {
       /* Vector regs are saved/restored using [reg+reg] addressing.  */
-      RTVEC_ELT (p, offset++)
-       = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, use_reg));
+      RTVEC_ELT (p, offset++) = gen_hard_reg_clobber (Pmode, use_reg);
       RTVEC_ELT (p, offset++)
        = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 0));
     }
@@ -26099,8 +26282,7 @@ split_stack_arg_pointer_used_p (void)
      then the arg pointer is used.  */
   if (cfun->machine->split_stack_arg_pointer != NULL_RTX
       && (!REG_P (cfun->machine->split_stack_arg_pointer)
-         || (REGNO (cfun->machine->split_stack_arg_pointer)
-             < FIRST_PSEUDO_REGISTER)))
+         || HARD_REGISTER_P (cfun->machine->split_stack_arg_pointer)))
     return true;
 
   /* Unfortunately we also need to do some code scanning, since
@@ -26135,7 +26317,7 @@ split_stack_arg_pointer_used_p (void)
 /* Return whether we need to emit an ELFv2 global entry point prologue.  */
 
 static bool
-rs6000_global_entry_point_needed_p (void)
+rs6000_global_entry_point_prologue_needed_p (void)
 {
   /* Only needed for the ELFv2 ABI.  */
   if (DEFAULT_ABI != ABI_ELFv2)
@@ -26146,6 +26328,10 @@ rs6000_global_entry_point_needed_p (void)
   if (TARGET_SINGLE_PIC_BASE)
     return false;
 
+  /* PC-relative functions never generate a global entry point prologue.  */
+  if (rs6000_pcrel_p (cfun))
+    return false;
+
   /* Ensure we have a global entry point for thunks.   ??? We could
      avoid that if the target routine doesn't need a global entry point,
      but we do not know whether this is the case at this point.  */
@@ -26697,9 +26883,7 @@ rs6000_emit_prologue (void)
       sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
       p = rtvec_alloc (sz);
       j = 0;
-      RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
-                                           gen_rtx_REG (SImode,
-                                                        LR_REGNO));
+      RTVEC_ELT (p, j++) = gen_hard_reg_clobber (SImode, LR_REGNO);
       RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
                                        gen_rtx_SYMBOL_REF (Pmode,
                                                            "*save_world"));
@@ -27490,14 +27674,23 @@ static void
 rs6000_output_function_prologue (FILE *file)
 {
   if (!cfun->is_thunk)
-    rs6000_output_savres_externs (file);
+    {
+      rs6000_output_savres_externs (file);
+#ifdef USING_ELFOS_H
+      const char *curr_machine = rs6000_machine_from_flags ();
+      if (rs6000_machine != curr_machine)
+       {
+         rs6000_machine = curr_machine;
+         emit_asm_machine ();
+       }
+#endif
+    }
 
   /* ELFv2 ABI r2 setup code and local entry point.  This must follow
      immediately after the global entry point label.  */
-  if (rs6000_global_entry_point_needed_p ())
+  if (rs6000_global_entry_point_prologue_needed_p ())
     {
       const char *name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
-
       (*targetm.asm_out.internal_label) (file, "LCF", rs6000_pic_labelno);
 
       if (TARGET_CMODEL != CMODEL_LARGE)
@@ -27548,6 +27741,19 @@ rs6000_output_function_prologue (FILE *file)
       fputs ("\n", file);
     }
 
+  else if (rs6000_pcrel_p (cfun))
+    {
+      const char *name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
+      /* All functions compiled to use PC-relative addressing will
+        have a .localentry value of 0 or 1.  For now we set it to
+        1 all the time, indicating that the function may clobber
+        the TOC register r2.  Later we may optimize this by setting
+        it to 0 if the function is a leaf and does not clobber r2.  */
+      fputs ("\t.localentry\t", file);
+      assemble_name (file, name);
+      fputs (",1\n", file);
+    }
+
   /* Output -mprofile-kernel code.  This needs to be done here instead of
      in output_function_profile since it must go after the ELFv2 ABI
      local entry point.  */
@@ -27619,7 +27825,7 @@ load_cr_save (int regno, rtx frame_reg_rtx, int offset, bool exit_func)
 /* Reload CR from REG.  */
 
 static void
-restore_saved_cr (rtx reg, int using_mfcr_multiple, bool exit_func)
+restore_saved_cr (rtx reg, bool using_mfcr_multiple, bool exit_func)
 {
   int count = 0;
   int i;
@@ -27781,16 +27987,8 @@ emit_cfa_restores (rtx cfa_restores)
 /* Emit function epilogue as insns.  */
 
 void
-rs6000_emit_epilogue (int sibcall)
-{
-  rs6000_stack_t *info;
-  int restoring_GPRs_inline;
-  int restoring_FPRs_inline;
-  int using_load_multiple;
-  int using_mtcr_multiple;
-  int use_backchain_to_restore_sp;
-  int restore_lr;
-  int strategy;
+rs6000_emit_epilogue (enum epilogue_type epilogue_type)
+{
   HOST_WIDE_INT frame_off = 0;
   rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
   rtx frame_reg_rtx = sp_reg_rtx;
@@ -27802,30 +28000,38 @@ rs6000_emit_epilogue (int sibcall)
   machine_mode fp_reg_mode = TARGET_HARD_FLOAT ? DFmode : SFmode;
   int fp_reg_size = 8;
   int i;
-  bool exit_func;
   unsigned ptr_regno;
 
-  info = rs6000_stack_info ();
+  rs6000_stack_t *info = rs6000_stack_info ();
+
+  if (epilogue_type == EPILOGUE_TYPE_NORMAL && crtl->calls_eh_return)
+    epilogue_type = EPILOGUE_TYPE_EH_RETURN;
+
+  int strategy = info->savres_strategy;
+  bool using_load_multiple = !!(strategy & REST_MULTIPLE);
+  bool restoring_GPRs_inline = !!(strategy & REST_INLINE_GPRS);
+  bool restoring_FPRs_inline = !!(strategy & REST_INLINE_FPRS);
+  if (epilogue_type == EPILOGUE_TYPE_SIBCALL)
+    {
+      restoring_GPRs_inline = true;
+      restoring_FPRs_inline = true;
+    }
+
+  bool using_mtcr_multiple = (rs6000_tune == PROCESSOR_PPC601
+                             || rs6000_tune == PROCESSOR_PPC603
+                             || rs6000_tune == PROCESSOR_PPC750
+                             || optimize_size);
 
-  strategy = info->savres_strategy;
-  using_load_multiple = strategy & REST_MULTIPLE;
-  restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
-  restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
-  using_mtcr_multiple = (rs6000_tune == PROCESSOR_PPC601
-                        || rs6000_tune == PROCESSOR_PPC603
-                        || rs6000_tune == PROCESSOR_PPC750
-                        || optimize_size);
   /* Restore via the backchain when we have a large frame, since this
      is more efficient than an addis, addi pair.  The second condition
      here will not trigger at the moment;  We don't actually need a
      frame pointer for alloca, but the generic parts of the compiler
      give us one anyway.  */
-  use_backchain_to_restore_sp = (info->total_size + (info->lr_save_p
-                                                    ? info->lr_save_offset
-                                                    : 0) > 32767
-                                || (cfun->calls_alloca
-                                    && !frame_pointer_needed));
-  restore_lr = (info->lr_save_p
+  bool use_backchain_to_restore_sp
+    = (info->total_size + (info->lr_save_p ? info->lr_save_offset : 0) > 32767
+       || (cfun->calls_alloca && !frame_pointer_needed));
+
+  bool restore_lr = (info->lr_save_p
                && (restoring_FPRs_inline
                    || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
                && (restoring_GPRs_inline
@@ -27835,10 +28041,7 @@ rs6000_emit_epilogue (int sibcall)
 
   if (WORLD_SAVE_P (info))
     {
-      int i, j;
-      char rname[30];
-      const char *alloc_rname;
-      rtvec p;
+      gcc_assert (epilogue_type != EPILOGUE_TYPE_SIBCALL);
 
       /* eh_rest_world_r10 will return to the location saved in the LR
         stack slot (which is not likely to be our caller.)
@@ -27847,23 +28050,34 @@ rs6000_emit_epilogue (int sibcall)
         The exception-handling stuff that was here in 2.95 is no
         longer necessary.  */
 
+      rtvec p;
       p = rtvec_alloc (9
                       + 32 - info->first_gp_reg_save
                       + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
                       + 63 + 1 - info->first_fp_reg_save);
 
-      strcpy (rname, ((crtl->calls_eh_return) ?
-                     "*eh_rest_world_r10" : "*rest_world"));
-      alloc_rname = ggc_strdup (rname);
+      const char *rname;
+      switch (epilogue_type)
+       {
+       case EPILOGUE_TYPE_NORMAL:
+         rname = ggc_strdup ("*rest_world");
+         break;
 
-      j = 0;
+       case EPILOGUE_TYPE_EH_RETURN:
+         rname = ggc_strdup ("*eh_rest_world_r10");
+         break;
+
+       default:
+         gcc_unreachable ();
+       }
+
+      int j = 0;
       RTVEC_ELT (p, j++) = ret_rtx;
       RTVEC_ELT (p, j++)
-       = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
+       = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, rname));
       /* The instruction pattern requires a clobber here;
         it is shared with the restVEC helper. */
-      RTVEC_ELT (p, j++)
-       = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
+      RTVEC_ELT (p, j++) = gen_hard_reg_clobber (Pmode, 11);
 
       {
        /* CR register traditionally saved as CR2.  */
@@ -27879,6 +28093,7 @@ rs6000_emit_epilogue (int sibcall)
          }
       }
 
+      int i;
       for (i = 0; i < 32 - info->first_gp_reg_save; i++)
        {
          rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
@@ -27909,14 +28124,10 @@ rs6000_emit_epilogue (int sibcall)
              && save_reg_p (info->first_fp_reg_save + i))
            cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
        }
-      RTVEC_ELT (p, j++)
-       = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
-      RTVEC_ELT (p, j++)
-       = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
-      RTVEC_ELT (p, j++)
-       = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
-      RTVEC_ELT (p, j++)
-       = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
+      RTVEC_ELT (p, j++) = gen_hard_reg_clobber (Pmode, 0);
+      RTVEC_ELT (p, j++) = gen_hard_reg_clobber (SImode, 12);
+      RTVEC_ELT (p, j++) = gen_hard_reg_clobber (SImode, 7);
+      RTVEC_ELT (p, j++) = gen_hard_reg_clobber (SImode, 8);
       RTVEC_ELT (p, j++)
        = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
       insn = emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
@@ -28107,7 +28318,7 @@ rs6000_emit_epilogue (int sibcall)
     }
   else if (info->push_p
           && DEFAULT_ABI != ABI_V4
-          && !crtl->calls_eh_return)
+          && epilogue_type != EPILOGUE_TYPE_EH_RETURN)
     {
       /* Prevent reordering memory accesses against stack pointer restore.  */
       if (cfun->calls_alloca
@@ -28267,9 +28478,9 @@ rs6000_emit_epilogue (int sibcall)
      function will deallocate the stack, so we don't need to worry
      about the unwinder restoring cr from an invalid stack frame
      location.  */
-  exit_func = (!restoring_FPRs_inline
-              || (!restoring_GPRs_inline
-                  && info->first_fp_reg_save == 64));
+  bool exit_func = (!restoring_FPRs_inline
+                   || (!restoring_GPRs_inline
+                       && info->first_fp_reg_save == 64));
 
   /* In the ELFv2 ABI we need to restore all call-saved CR fields from
      *separate* slots if the routine calls __builtin_eh_return, so
@@ -28335,7 +28546,7 @@ rs6000_emit_epilogue (int sibcall)
     restore_saved_lr (0, exit_func);
 
   /* Load exception handler data registers, if needed.  */
-  if (crtl->calls_eh_return)
+  if (epilogue_type == EPILOGUE_TYPE_EH_RETURN)
     {
       unsigned int i, regno;
 
@@ -28526,13 +28737,13 @@ rs6000_emit_epilogue (int sibcall)
       RTX_FRAME_RELATED_P (insn) = 1;
     }
 
-  if (crtl->calls_eh_return)
+  if (epilogue_type == EPILOGUE_TYPE_EH_RETURN)
     {
       rtx sa = EH_RETURN_STACKADJ_RTX;
       emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
     }
 
-  if (!sibcall && restoring_FPRs_inline)
+  if (epilogue_type != EPILOGUE_TYPE_SIBCALL && restoring_FPRs_inline)
     {
       if (cfa_restores)
        {
@@ -28557,15 +28768,14 @@ rs6000_emit_epilogue (int sibcall)
       emit_jump_insn (targetm.gen_simple_return ());
     }
 
-  if (!sibcall && !restoring_FPRs_inline)
+  if (epilogue_type != EPILOGUE_TYPE_SIBCALL && !restoring_FPRs_inline)
     {
       bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
       rtvec p = rtvec_alloc (3 + !!lr + 64 - info->first_fp_reg_save);
       int elt = 0;
       RTVEC_ELT (p, elt++) = ret_rtx;
       if (lr)
-       RTVEC_ELT (p, elt++)
-         = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO));
+       RTVEC_ELT (p, elt++) = gen_hard_reg_clobber (Pmode, LR_REGNO);
 
       /* We have to restore more than two FP registers, so branch to the
         restore function.  It will return to our caller.  */
@@ -28597,7 +28807,7 @@ rs6000_emit_epilogue (int sibcall)
 
   if (cfa_restores)
     {
-      if (sibcall)
+      if (epilogue_type == EPILOGUE_TYPE_SIBCALL)
        /* Ensure the cfa_restores are hung off an insn that won't
           be reordered above other restores.  */
        emit_insn (gen_blockage ());
@@ -28724,7 +28934,7 @@ rs6000_output_function_epilogue (FILE *file)
         length fields that follow.  However, if you omit the optional
         fields, the assembler outputs zeros for all optional fields
         anyways, giving each variable length field is minimum length
-        (as defined in sys/debug.h).  Thus we can not use the .tbtab
+        (as defined in sys/debug.h).  Thus we cannot use the .tbtab
         pseudo-op at all.  */
 
       /* An all-zero word flags the start of the tbtab, for debuggers
@@ -28806,7 +29016,7 @@ rs6000_output_function_epilogue (FILE *file)
              rtx parameter = DECL_INCOMING_RTL (decl);
              machine_mode mode = GET_MODE (parameter);
 
-             if (GET_CODE (parameter) == REG)
+             if (REG_P (parameter))
                {
                  if (SCALAR_FLOAT_MODE_P (mode))
                    {
@@ -28959,7 +29169,7 @@ rs6000_expand_split_stack_prologue (void)
 
   if (global_regs[29])
     {
-      error ("%qs uses register r29", "-fsplit-stack");
+      error ("%qs uses register r29", "%<-fsplit-stack%>");
       inform (DECL_SOURCE_LOCATION (global_regs_decl[29]),
              "conflicts with %qD", global_regs_decl[29]);
     }
@@ -28967,7 +29177,8 @@ rs6000_expand_split_stack_prologue (void)
   allocate = info->total_size;
   if (allocate > (unsigned HOST_WIDE_INT) 1 << 31)
     {
-      sorry ("Stack frame larger than 2G is not supported for -fsplit-stack");
+      sorry ("Stack frame larger than 2G is not supported for "
+            "%<-fsplit-stack%>");
       return;
     }
   if (morestack_ref == NULL_RTX)
@@ -29152,6 +29363,7 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
                        HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
                        tree function)
 {
+  const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
   rtx this_rtx, funexp;
   rtx_insn *insn;
 
@@ -29221,13 +29433,14 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
 
   /* Run just enough of rest_of_compilation to get the insns emitted.
      There's not really enough bulk here to make other passes such as
-     instruction scheduling worth while.  Note that use_thunk calls
-     assemble_start_function and assemble_end_function.  */
+     instruction scheduling worth while.  */
   insn = get_insns ();
   shorten_branches (insn);
+  assemble_start_function (thunk_fndecl, fnname);
   final_start_function (insn, file, 1);
   final (insn, file, 1);
   final_end_function ();
+  assemble_end_function (thunk_fndecl, fnname);
 
   reload_completed = 0;
   epilogue_completed = 0;
@@ -29290,10 +29503,7 @@ rs6000_hash_constant (rtx k)
       }
 
     case CONST_DOUBLE:
-      if (mode != VOIDmode)
-       return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
-      flen = 2;
-      break;
+      return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
 
     case CODE_LABEL:
       fidx = 3;
@@ -29469,7 +29679,7 @@ output_toc (FILE *file, rtx x, int labelno, machine_mode mode)
          fprintf (file, "%d\n", ((*found)->labelno));
 
 #ifdef HAVE_AS_TLS
-         if (TARGET_XCOFF && GET_CODE (x) == SYMBOL_REF
+         if (TARGET_XCOFF && SYMBOL_REF_P (x)
              && (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_GLOBAL_DYNAMIC
                  || SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC))
            {
@@ -29498,9 +29708,9 @@ output_toc (FILE *file, rtx x, int labelno, machine_mode mode)
   /* Handle FP constants specially.  Note that if we have a minimal
      TOC, things we put here aren't actually in the TOC, so we can allow
      FP constants.  */
-  if (GET_CODE (x) == CONST_DOUBLE &&
-      (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode
-       || GET_MODE (x) == IFmode || GET_MODE (x) == KFmode))
+  if (CONST_DOUBLE_P (x)
+      && (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode
+         || GET_MODE (x) == IFmode || GET_MODE (x) == KFmode))
     {
       long k[4];
 
@@ -29538,8 +29748,8 @@ output_toc (FILE *file, rtx x, int labelno, machine_mode mode)
          return;
        }
     }
-  else if (GET_CODE (x) == CONST_DOUBLE &&
-          (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
+  else if (CONST_DOUBLE_P (x)
+          && (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
     {
       long k[2];
 
@@ -29572,8 +29782,8 @@ output_toc (FILE *file, rtx x, int labelno, machine_mode mode)
          return;
        }
     }
-  else if (GET_CODE (x) == CONST_DOUBLE &&
-          (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
+  else if (CONST_DOUBLE_P (x)
+          && (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
     {
       long l;
 
@@ -29604,7 +29814,7 @@ output_toc (FILE *file, rtx x, int labelno, machine_mode mode)
          return;
        }
     }
-  else if (GET_MODE (x) == VOIDmode && GET_CODE (x) == CONST_INT)
+  else if (GET_MODE (x) == VOIDmode && CONST_INT_P (x))
     {
       unsigned HOST_WIDE_INT low;
       HOST_WIDE_INT high;
@@ -29670,7 +29880,7 @@ output_toc (FILE *file, rtx x, int labelno, machine_mode mode)
   if (GET_CODE (x) == CONST)
     {
       gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
-                 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
+                 && CONST_INT_P (XEXP (XEXP (x, 0), 1)));
 
       base = XEXP (XEXP (x, 0), 0);
       offset = INTVAL (XEXP (XEXP (x, 0), 1));
@@ -29732,7 +29942,7 @@ output_toc (FILE *file, rtx x, int labelno, machine_mode mode)
     output_addr_const (file, x);
 
 #if HAVE_AS_TLS
-  if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF)
+  if (TARGET_XCOFF && SYMBOL_REF_P (base))
     {
       switch (SYMBOL_REF_TLS_MODEL (base))
        {
@@ -30141,11 +30351,12 @@ rs6000_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
           some cycles later.  */
 
        /* Separate a load from a narrower, dependent store.  */
-       if ((rs6000_sched_groups || rs6000_tune == PROCESSOR_POWER9)
+       if ((rs6000_sched_groups || rs6000_tune == PROCESSOR_POWER9
+            || rs6000_tune == PROCESSOR_FUTURE)
            && GET_CODE (PATTERN (insn)) == SET
            && GET_CODE (PATTERN (dep_insn)) == SET
-           && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
-           && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
+           && MEM_P (XEXP (PATTERN (insn), 1))
+           && MEM_P (XEXP (PATTERN (dep_insn), 0))
            && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
                > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
          return cost + 14;
@@ -30179,6 +30390,7 @@ rs6000_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
                 || rs6000_tune == PROCESSOR_POWER7
                 || rs6000_tune == PROCESSOR_POWER8
                 || rs6000_tune == PROCESSOR_POWER9
+                || rs6000_tune == PROCESSOR_FUTURE
                  || rs6000_tune == PROCESSOR_CELL)
                 && recog_memoized (dep_insn)
                 && (INSN_CODE (dep_insn) >= 0))
@@ -30758,6 +30970,7 @@ rs6000_issue_rate (void)
   case PROCESSOR_POWER8:
     return 7;
   case PROCESSOR_POWER9:
+  case PROCESSOR_FUTURE:
     return 6;
   default:
     return 1;
@@ -30818,7 +31031,7 @@ find_mem_ref (rtx pat, rtx *mem_ref)
   if (tie_operand (pat, VOIDmode))
     return false;
 
-  if (GET_CODE (pat) == MEM)
+  if (MEM_P (pat))
     {
       *mem_ref = pat;
       return true;
@@ -32498,26 +32711,54 @@ rs6000_set_default_type_attributes (tree type)
 /* Return a reference suitable for calling a function with the
    longcall attribute.  */
 
-rtx
-rs6000_longcall_ref (rtx call_ref)
+static rtx
+rs6000_longcall_ref (rtx call_ref, rtx arg)
 {
-  const char *call_name;
-  tree node;
-
-  if (GET_CODE (call_ref) != SYMBOL_REF)
-    return call_ref;
-
   /* System V adds '.' to the internal name, so skip them.  */
-  call_name = XSTR (call_ref, 0);
+  const char *call_name = XSTR (call_ref, 0);
   if (*call_name == '.')
     {
       while (*call_name == '.')
        call_name++;
 
-      node = get_identifier (call_name);
+      tree node = get_identifier (call_name);
       call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
     }
 
+  if (TARGET_PLTSEQ)
+    {
+      rtx base = const0_rtx;
+      int regno = 12;
+      if (rs6000_pcrel_p (cfun))
+       {
+         rtx reg = gen_rtx_REG (Pmode, regno);
+         rtx u = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, base, call_ref, arg),
+                                 UNSPEC_PLT_PCREL);
+         emit_insn (gen_rtx_SET (reg, u));
+         return reg;
+       }
+
+      if (DEFAULT_ABI == ABI_ELFv2)
+       base = gen_rtx_REG (Pmode, TOC_REGISTER);
+      else
+       {
+         if (flag_pic)
+           base = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
+         regno = 11;
+       }
+      /* Reg must match that used by linker PLT stubs.  For ELFv2, r12
+        may be used by a function global entry point.  For SysV4, r11
+        is used by __glink_PLTresolve lazy resolver entry.  */
+      rtx reg = gen_rtx_REG (Pmode, regno);
+      rtx hi = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, base, call_ref, arg),
+                              UNSPEC_PLT16_HA);
+      rtx lo = gen_rtx_UNSPEC (Pmode, gen_rtvec (3, reg, call_ref, arg),
+                              UNSPEC_PLT16_LO);
+      emit_insn (gen_rtx_SET (reg, hi));
+      emit_insn (gen_rtx_SET (reg, lo));
+      return reg;
+    }
+
   return force_reg (Pmode, call_ref);
 }
 \f
@@ -32760,10 +33001,10 @@ find_addr_reg (rtx addr)
 {
   while (GET_CODE (addr) == PLUS)
     {
-      if (GET_CODE (XEXP (addr, 0)) == REG
+      if (REG_P (XEXP (addr, 0))
          && REGNO (XEXP (addr, 0)) != 0)
        addr = XEXP (addr, 0);
-      else if (GET_CODE (XEXP (addr, 1)) == REG
+      else if (REG_P (XEXP (addr, 1))
               && REGNO (XEXP (addr, 1)) != 0)
        addr = XEXP (addr, 1);
       else if (CONSTANT_P (XEXP (addr, 0)))
@@ -32773,7 +33014,7 @@ find_addr_reg (rtx addr)
       else
        gcc_unreachable ();
     }
-  gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
+  gcc_assert (REG_P (addr) && REGNO (addr) != 0);
   return addr;
 }
 
@@ -32875,7 +33116,7 @@ macho_branch_islands (void)
        }
       else
        {
-         strcat (tmp_buf, ":\nlis r12,hi16(");
+         strcat (tmp_buf, ":\n\tlis r12,hi16(");
          strcat (tmp_buf, name_buf);
          strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
          strcat (tmp_buf, name_buf);
@@ -32920,49 +33161,6 @@ get_prev_label (tree function_name)
   return NULL_TREE;
 }
 
-/* INSN is either a function call or a millicode call.  It may have an
-   unconditional jump in its delay slot.
-
-   CALL_DEST is the routine we are calling.  */
-
-char *
-macho_call_template (rtx_insn *insn, rtx *operands, int dest_operand_number,
-                    int cookie_operand_number)
-{
-  static char buf[256];
-  if (darwin_emit_branch_islands
-      && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
-      && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
-    {
-      tree labelname;
-      tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
-
-      if (no_previous_def (funname))
-       {
-         rtx label_rtx = gen_label_rtx ();
-         char *label_buf, temp_buf[256];
-         ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
-                                      CODE_LABEL_NUMBER (label_rtx));
-         label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
-         labelname = get_identifier (label_buf);
-         add_compiler_branch_island (labelname, funname, insn_line (insn));
-       }
-      else
-       labelname = get_prev_label (funname);
-
-      /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
-        instruction will reach 'foo', otherwise link as 'bl L42'".
-        "L42" should be a 'branch island', that will do a far jump to
-        'foo'.  Branch islands are generated in
-        macho_branch_islands().  */
-      sprintf (buf, "jbsr %%z%d,%.246s",
-              dest_operand_number, IDENTIFIER_POINTER (labelname));
-    }
-  else
-    sprintf (buf, "bl %%z%d", dest_operand_number);
-  return buf;
-}
-
 /* Generate PIC and indirect symbol stubs.  */
 
 void
@@ -32971,7 +33169,7 @@ machopic_output_stub (FILE *file, const char *symb, const char *stub)
   unsigned int length;
   char *symbol_name, *lazy_ptr_name;
   char *local_label_0;
-  static int label = 0;
+  static unsigned label = 0;
 
   /* Lose our funky encoding stuff so it doesn't contaminate the stub.  */
   symb = (*targetm.strip_name_encoding) (symb);
@@ -32997,8 +33195,8 @@ machopic_output_stub (FILE *file, const char *symb, const char *stub)
       fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
 
       label++;
-      local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
-      sprintf (local_label_0, "\"L%011d$spb\"", label);
+      local_label_0 = XALLOCAVEC (char, 16);
+      sprintf (local_label_0, "L%u$spb", label);
 
       fprintf (file, "\tmflr r0\n");
       if (TARGET_LINK_STACK)
@@ -33079,7 +33277,7 @@ rs6000_machopic_legitimize_pic_address (rtx orig, machine_mode mode,
        rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
                                                Pmode, reg);
 
-      if (GET_CODE (offset) == CONST_INT)
+      if (CONST_INT_P (offset))
        {
          if (SMALL_INT (offset))
            return plus_constant (Pmode, base, INTVAL (offset));
@@ -33295,7 +33493,8 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
   ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
   ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
 
-  if (TARGET_CMODEL == CMODEL_LARGE && rs6000_global_entry_point_needed_p ())
+  if (TARGET_CMODEL == CMODEL_LARGE
+      && rs6000_global_entry_point_prologue_needed_p ())
     {
       char buf[256];
 
@@ -33488,6 +33687,10 @@ rs6000_xcoff_asm_init_sections (void)
                           rs6000_xcoff_output_readwrite_section_asm_op,
                           &xcoff_private_data_section_name);
 
+  read_only_private_data_section
+    = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
+                          &xcoff_private_rodata_section_name);
+
   tls_data_section
     = get_unnamed_section (SECTION_TLS,
                           rs6000_xcoff_output_tls_section_asm_op,
@@ -33498,10 +33701,6 @@ rs6000_xcoff_asm_init_sections (void)
                           rs6000_xcoff_output_tls_section_asm_op,
                           &xcoff_private_data_section_name);
 
-  read_only_private_data_section
-    = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
-                          &xcoff_private_data_section_name);
-
   toc_section
     = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
 
@@ -33682,6 +33881,8 @@ rs6000_xcoff_file_start (void)
                           main_input_filename, ".bss_");
   rs6000_gen_section_name (&xcoff_private_data_section_name,
                           main_input_filename, ".rw_");
+  rs6000_gen_section_name (&xcoff_private_rodata_section_name,
+                          main_input_filename, ".rop_");
   rs6000_gen_section_name (&xcoff_read_only_section_name,
                           main_input_filename, ".ro_");
   rs6000_gen_section_name (&xcoff_tls_data_section_name,
@@ -34004,7 +34205,7 @@ rs6000_xcoff_encode_section_info (tree decl, rtx rtl, int first)
   if (!MEM_P (rtl))
     return;
   symbol = XEXP (rtl, 0);
-  if (GET_CODE (symbol) != SYMBOL_REF)
+  if (!SYMBOL_REF_P (symbol))
     return;
 
   flags = SYMBOL_REF_FLAGS (symbol);
@@ -34184,7 +34385,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
       return false;
 
     case MULT:
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+      if (CONST_INT_P (XEXP (x, 1))
          && satisfies_constraint_I (XEXP (x, 1)))
        {
          if (INTVAL (XEXP (x, 1)) >= -256
@@ -34222,7 +34423,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 
     case UDIV:
     case UMOD:
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+      if (CONST_INT_P (XEXP (x, 1))
          && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
        {
          if (code == DIV || code == MOD)
@@ -34355,7 +34556,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 
     case SIGN_EXTEND:
     case ZERO_EXTEND:
-      if (GET_CODE (XEXP (x, 0)) == MEM)
+      if (MEM_P (XEXP (x, 0)))
        *total = 0;
       else
        *total = COSTS_N_INSNS (1);
@@ -34588,22 +34789,61 @@ rs6000_register_move_cost (machine_mode mode,
                           reg_class_t from, reg_class_t to)
 {
   int ret;
+  reg_class_t rclass;
 
   if (TARGET_DEBUG_COST)
     dbg_cost_ctrl++;
 
+  /* If we have VSX, we can easily move between FPR or Altivec registers,
+     otherwise we can only easily move within classes.
+     Do this first so we give best-case answers for union classes
+     containing both gprs and vsx regs.  */
+  HARD_REG_SET to_vsx, from_vsx;
+  COPY_HARD_REG_SET (to_vsx, reg_class_contents[to]);
+  AND_HARD_REG_SET (to_vsx, reg_class_contents[VSX_REGS]);
+  COPY_HARD_REG_SET (from_vsx, reg_class_contents[from]);
+  AND_HARD_REG_SET (from_vsx, reg_class_contents[VSX_REGS]);
+  if (!hard_reg_set_empty_p (to_vsx)
+      && !hard_reg_set_empty_p (from_vsx)
+      && (TARGET_VSX
+         || hard_reg_set_intersect_p (to_vsx, from_vsx)))
+    {
+      int reg = FIRST_FPR_REGNO;
+      if (TARGET_VSX
+         || (TEST_HARD_REG_BIT (to_vsx, FIRST_ALTIVEC_REGNO)
+             && TEST_HARD_REG_BIT (from_vsx, FIRST_ALTIVEC_REGNO)))
+       reg = FIRST_ALTIVEC_REGNO;
+      ret = 2 * hard_regno_nregs (reg, mode);
+    }
+
   /*  Moves from/to GENERAL_REGS.  */
-  if (reg_classes_intersect_p (to, GENERAL_REGS)
-      || reg_classes_intersect_p (from, GENERAL_REGS))
+  else if ((rclass = from, reg_classes_intersect_p (to, GENERAL_REGS))
+          || (rclass = to, reg_classes_intersect_p (from, GENERAL_REGS)))
     {
-      reg_class_t rclass = from;
-
-      if (! reg_classes_intersect_p (to, GENERAL_REGS))
-       rclass = to;
-
       if (rclass == FLOAT_REGS || rclass == ALTIVEC_REGS || rclass == VSX_REGS)
-       ret = (rs6000_memory_move_cost (mode, rclass, false)
-              + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
+       {
+         if (TARGET_DIRECT_MOVE)
+           {
+             /* Keep the cost for direct moves above that for within
+                a register class even if the actual processor cost is
+                comparable.  We do this because a direct move insn
+                can't be a nop, whereas with ideal register
+                allocation a move within the same class might turn
+                out to be a nop.  */
+             if (rs6000_tune == PROCESSOR_POWER9
+                 || rs6000_tune == PROCESSOR_FUTURE)
+               ret = 3 * hard_regno_nregs (FIRST_GPR_REGNO, mode);
+             else
+               ret = 4 * hard_regno_nregs (FIRST_GPR_REGNO, mode);
+             /* SFmode requires a conversion when moving between gprs
+                and vsx.  */
+             if (mode == SFmode)
+               ret += 2;
+           }
+         else
+           ret = (rs6000_memory_move_cost (mode, rclass, false)
+                  + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
+       }
 
       /* It's more expensive to move CR_REGS than CR0_REGS because of the
         shift.  */
@@ -34616,24 +34856,14 @@ rs6000_register_move_cost (machine_mode mode,
                || rs6000_tune == PROCESSOR_POWER7
                || rs6000_tune == PROCESSOR_POWER8
                || rs6000_tune == PROCESSOR_POWER9)
-              && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS))
-        ret = 6 * hard_regno_nregs (0, mode);
+              && reg_class_subset_p (rclass, SPECIAL_REGS))
+        ret = 6 * hard_regno_nregs (FIRST_GPR_REGNO, mode);
 
       else
        /* A move will cost one instruction per GPR moved.  */
-       ret = 2 * hard_regno_nregs (0, mode);
+       ret = 2 * hard_regno_nregs (FIRST_GPR_REGNO, mode);
     }
 
-  /* If we have VSX, we can easily move between FPR or Altivec registers.  */
-  else if (VECTOR_MEM_VSX_P (mode)
-          && reg_classes_intersect_p (to, VSX_REGS)
-          && reg_classes_intersect_p (from, VSX_REGS))
-    ret = 2 * hard_regno_nregs (FIRST_FPR_REGNO, mode);
-
-  /* Moving between two similar registers is just one instruction.  */
-  else if (reg_classes_intersect_p (to, from))
-    ret = (FLOAT128_2REG_P (mode)) ? 4 : 2;
-
   /* Everything else has to go through GENERAL_REGS.  */
   else
     ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
@@ -34643,7 +34873,7 @@ rs6000_register_move_cost (machine_mode mode,
     {
       if (dbg_cost_ctrl == 1)
        fprintf (stderr,
-                "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
+                "rs6000_register_move_cost: ret=%d, mode=%s, from=%s, to=%s\n",
                 ret, GET_MODE_NAME (mode), reg_class_names[from],
                 reg_class_names[to]);
       dbg_cost_ctrl--;
@@ -34686,6 +34916,64 @@ rs6000_memory_move_cost (machine_mode mode, reg_class_t rclass,
   return ret;
 }
 
+/* Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS.
+
+   The register allocator chooses GEN_OR_VSX_REGS for the allocno
+   class if GENERAL_REGS and VSX_REGS cost is lower than the memory
+   cost.  This happens a lot when TARGET_DIRECT_MOVE makes the register
+   move cost between GENERAL_REGS and VSX_REGS low.
+
+   It might seem reasonable to use a union class.  After all, if usage
+   of vsr is low and gpr high, it might make sense to spill gpr to vsr
+   rather than memory.  However, in cases where register pressure of
+   both is high, like the cactus_adm spec test, allowing
+   GEN_OR_VSX_REGS as the allocno class results in bad decisions in
+   the first scheduling pass.  This is partly due to an allocno of
+   GEN_OR_VSX_REGS wrongly contributing to the GENERAL_REGS pressure
+   class, which gives too high a pressure for GENERAL_REGS and too low
+   for VSX_REGS.  So, force a choice of the subclass here.
+
+   The best class is also the union if GENERAL_REGS and VSX_REGS have
+   the same cost.  In that case we do use GEN_OR_VSX_REGS as the
+   allocno class, since trying to narrow down the class by regno mode
+   is prone to error.  For example, SImode is allowed in VSX regs and
+   in some cases (eg. gcc.target/powerpc/p9-xxbr-3.c do_bswap32_vect)
+   it would be wrong to choose an allocno of GENERAL_REGS based on
+   SImode.  */
+
+static reg_class_t
+rs6000_ira_change_pseudo_allocno_class (int regno ATTRIBUTE_UNUSED,
+                                       reg_class_t allocno_class,
+                                       reg_class_t best_class)
+{
+  switch (allocno_class)
+    {
+    case GEN_OR_VSX_REGS:
+      /* best_class must be a subset of allocno_class.  */
+      gcc_checking_assert (best_class == GEN_OR_VSX_REGS
+                          || best_class == GEN_OR_FLOAT_REGS
+                          || best_class == VSX_REGS
+                          || best_class == ALTIVEC_REGS
+                          || best_class == FLOAT_REGS
+                          || best_class == GENERAL_REGS
+                          || best_class == BASE_REGS);
+      /* Use best_class but choose wider classes when copying from the
+        wider class to best_class is cheap.  This mimics IRA choice
+        of allocno class.  */
+      if (best_class == BASE_REGS)
+       return GENERAL_REGS;
+      if (TARGET_VSX
+         && (best_class == FLOAT_REGS || best_class == ALTIVEC_REGS))
+       return VSX_REGS;
+      return best_class;
+
+    default:
+      break;
+    }
+
+  return allocno_class;
+}
+
 /* Returns a code for a target-specific builtin that implements
    reciprocal of the function, or NULL_TREE if not available.  */
 
@@ -35393,16 +35681,16 @@ altivec_expand_vec_perm_const (rtx target, rtx op0, rtx op1,
             numbering) are what we need.  */
          if (!BYTES_BIG_ENDIAN
              && icode == CODE_FOR_altivec_vpkuwum_direct
-             && ((GET_CODE (op0) == REG
+             && ((REG_P (op0)
                   && GET_MODE (op0) != V4SImode)
-                 || (GET_CODE (op0) == SUBREG
+                 || (SUBREG_P (op0)
                      && GET_MODE (XEXP (op0, 0)) != V4SImode)))
            continue;
          if (!BYTES_BIG_ENDIAN
              && icode == CODE_FOR_altivec_vpkuhum_direct
-             && ((GET_CODE (op0) == REG
+             && ((REG_P (op0)
                   && GET_MODE (op0) != V8HImode)
-                 || (GET_CODE (op0) == SUBREG
+                 || (SUBREG_P (op0)
                      && GET_MODE (XEXP (op0, 0)) != V8HImode)))
            continue;
 
@@ -35776,7 +36064,7 @@ rs6000_libcall_value (machine_mode mode)
 }
 
 /* Compute register pressure classes.  We implement the target hook to avoid
-   IRA picking something like NON_SPECIAL_REGS as a pressure class, which can
+   IRA picking something like GEN_OR_FLOAT_REGS as a pressure class, which can
    lead to incorrect estimates of number of available registers and therefor
    increased register pressure/spill.   */
 static int
@@ -35889,38 +36177,78 @@ rs6000_init_dwarf_reg_sizes_extra (tree address)
 unsigned int
 rs6000_dbx_register_number (unsigned int regno, unsigned int format)
 {
-  /* Except for the above, we use the internal number for non-DWARF
-     debug information, and also for .eh_frame.  */
-  if ((format == 0 && write_symbols != DWARF2_DEBUG) || format == 2)
-    return regno;
-
   /* On some platforms, we use the standard DWARF register
      numbering for .debug_info and .debug_frame.  */
+  if ((format == 0 && write_symbols == DWARF2_DEBUG) || format == 1)
+    {
 #ifdef RS6000_USE_DWARF_NUMBERING
-  if (regno <= 63)
+      if (regno <= 31)
+       return regno;
+      if (FP_REGNO_P (regno))
+       return regno - FIRST_FPR_REGNO + 32;
+      if (ALTIVEC_REGNO_P (regno))
+       return regno - FIRST_ALTIVEC_REGNO + 1124;
+      if (regno == LR_REGNO)
+       return 108;
+      if (regno == CTR_REGNO)
+       return 109;
+      if (regno == CA_REGNO)
+       return 101;  /* XER */
+      /* Special handling for CR for .debug_frame: rs6000_emit_prologue has
+        translated any combination of CR2, CR3, CR4 saves to a save of CR2.
+        The actual code emitted saves the whole of CR, so we map CR2_REGNO
+        to the DWARF reg for CR.  */
+      if (format == 1 && regno == CR2_REGNO)
+       return 64;
+      if (CR_REGNO_P (regno))
+       return regno - CR0_REGNO + 86;
+      if (regno == VRSAVE_REGNO)
+       return 356;
+      if (regno == VSCR_REGNO)
+       return 67;
+
+      /* These do not make much sense.  */
+      if (regno == FRAME_POINTER_REGNUM)
+       return 111;
+      if (regno == ARG_POINTER_REGNUM)
+       return 67;
+      if (regno == 64)
+       return 100;
+
+      gcc_unreachable ();
+#endif
+    }
+
+  /* We use the GCC 7 (and before) internal number for non-DWARF debug
+     information, and also for .eh_frame.  */
+  /* Translate the regnos to their numbers in GCC 7 (and before).  */
+  if (regno <= 31)
     return regno;
+  if (FP_REGNO_P (regno))
+    return regno - FIRST_FPR_REGNO + 32;
+  if (ALTIVEC_REGNO_P (regno))
+    return regno - FIRST_ALTIVEC_REGNO + 77;
   if (regno == LR_REGNO)
-    return 108;
+    return 65;
   if (regno == CTR_REGNO)
-    return 109;
-  /* Special handling for CR for .debug_frame: rs6000_emit_prologue has
-     translated any combination of CR2, CR3, CR4 saves to a save of CR2.
-     The actual code emitted saves the whole of CR, so we map CR2_REGNO
-     to the DWARF reg for CR.  */
-  if (format == 1 && regno == CR2_REGNO)
-    return 64;
-  if (CR_REGNO_P (regno))
-    return regno - CR0_REGNO + 86;
+    return 66;
   if (regno == CA_REGNO)
-    return 101;  /* XER */
-  if (ALTIVEC_REGNO_P (regno))
-    return regno - FIRST_ALTIVEC_REGNO + 1124;
+    return 76;  /* XER */
+  if (CR_REGNO_P (regno))
+    return regno - CR0_REGNO + 68;
   if (regno == VRSAVE_REGNO)
-    return 356;
+    return 109;
   if (regno == VSCR_REGNO)
+    return 110;
+
+  if (regno == FRAME_POINTER_REGNUM)
+    return 111;
+  if (regno == ARG_POINTER_REGNUM)
     return 67;
-#endif
-  return regno;
+  if (regno == 64)
+    return 64;
+
+  gcc_unreachable ();
 }
 
 /* target hook eh_return_filter_mode */
@@ -36105,14 +36433,16 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "float128",                        OPTION_MASK_FLOAT128_KEYWORD,   false, true  },
   { "float128-hardware",       OPTION_MASK_FLOAT128_HW,        false, true  },
   { "fprnd",                   OPTION_MASK_FPRND,              false, true  },
+  { "future",                  OPTION_MASK_FUTURE,             false, true  },
   { "hard-dfp",                        OPTION_MASK_DFP,                false, true  },
   { "htm",                     OPTION_MASK_HTM,                false, true  },
   { "isel",                    OPTION_MASK_ISEL,               false, true  },
   { "mfcrf",                   OPTION_MASK_MFCRF,              false, true  },
-  { "mfpgpr",                  OPTION_MASK_MFPGPR,             false, true  },
+  { "mfpgpr",                  0,                              false, true  },
   { "modulo",                  OPTION_MASK_MODULO,             false, true  },
   { "mulhw",                   OPTION_MASK_MULHW,              false, true  },
   { "multiple",                        OPTION_MASK_MULTIPLE,           false, true  },
+  { "pcrel",                   OPTION_MASK_PCREL,              false, true  },
   { "popcntb",                 OPTION_MASK_POPCNTB,            false, true  },
   { "popcntd",                 OPTION_MASK_POPCNTD,            false, true  },
   { "power8-fusion",           OPTION_MASK_P8_FUSION,          false, true  },
@@ -36123,6 +36453,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "power9-vector",           OPTION_MASK_P9_VECTOR,          false, true  },
   { "powerpc-gfxopt",          OPTION_MASK_PPC_GFXOPT,         false, true  },
   { "powerpc-gpopt",           OPTION_MASK_PPC_GPOPT,          false, true  },
+  { "prefixed-addr",           OPTION_MASK_PREFIXED_ADDR,      false, true  },
   { "quad-memory",             OPTION_MASK_QUAD_MEMORY,        false, true  },
   { "quad-memory-atomic",      OPTION_MASK_QUAD_MEMORY_ATOMIC, false, true  },
   { "recip-precision",         OPTION_MASK_RECIP_PRECISION,    false, true  },
@@ -37051,7 +37382,7 @@ rs6000_get_function_versions_dispatcher (void *decl)
 
 #ifndef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
   error_at (DECL_SOURCE_LOCATION (default_node->decl),
-           "target_clones attribute needs GLIBC (2.23 and newer) that "
+           "%<target_clones%> attribute needs GLIBC (2.23 and newer) that "
            "exports hardware capability bits");
 #else
 
@@ -37103,7 +37434,7 @@ make_resolver_func (const tree default_decl,
 {
   /* Make the resolver function static.  The resolver function returns
      void *.  */
-  tree decl_name = clone_function_name_numbered (default_decl, "resolver");
+  tree decl_name = clone_function_name (default_decl, "resolver");
   const char *resolver_name = IDENTIFIER_POINTER (decl_name);
   tree type = build_function_type_list (ptr_type_node, NULL_TREE);
   tree decl = build_fn_decl (resolver_name, type);
@@ -37126,6 +37457,7 @@ make_resolver_func (const tree default_decl,
 
   /* Build result decl and add to function_decl.  */
   tree t = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, ptr_type_node);
+  DECL_CONTEXT (t) = decl;
   DECL_ARTIFICIAL (t) = 1;
   DECL_IGNORED_P (t) = 1;
   DECL_RESULT (decl) = t;
@@ -37451,11 +37783,13 @@ rs6000_legitimate_constant_p (machine_mode mode, rtx x)
   if (TARGET_ELF && tls_referenced_p (x))
     return false;
 
-  return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
-         || GET_MODE (x) == VOIDmode
-         || (TARGET_POWERPC64 && mode == DImode)
-         || easy_fp_constant (x, mode)
-         || easy_vector_constant (x, mode));
+  if (CONST_DOUBLE_P (x))
+    return easy_fp_constant (x, mode);
+
+  if (GET_CODE (x) == CONST_VECTOR)
+    return easy_vector_constant (x, mode);
+
+  return true;
 }
 
 \f
@@ -37485,10 +37819,9 @@ chain_already_loaded (rtx_insn *last)
 /* Expand code to perform a call under the AIX or ELFv2 ABI.  */
 
 void
-rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
+rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
 {
-  const bool direct_call_p
-    = GET_CODE (func_desc) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (func_desc);
+  rtx func = func_desc;
   rtx toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM);
   rtx toc_load = NULL_RTX;
   rtx toc_restore = NULL_RTX;
@@ -37497,35 +37830,55 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
   rtx call[4];
   int n_call;
   rtx insn;
+  bool is_pltseq_longcall;
+
+  if (global_tlsarg)
+    tlsarg = global_tlsarg;
 
   /* Handle longcall attributes.  */
-  if (INTVAL (cookie) & CALL_LONG)
-    func_desc = rs6000_longcall_ref (func_desc);
+  is_pltseq_longcall = false;
+  if ((INTVAL (cookie) & CALL_LONG) != 0
+      && GET_CODE (func_desc) == SYMBOL_REF)
+    {
+      func = rs6000_longcall_ref (func_desc, tlsarg);
+      if (TARGET_PLTSEQ)
+       is_pltseq_longcall = true;
+    }
 
   /* Handle indirect calls.  */
-  if (GET_CODE (func_desc) != SYMBOL_REF
-      || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (func_desc)))
-    {
-      /* Save the TOC into its reserved slot before the call,
-        and prepare to restore it after the call.  */
-      rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
-      rtx stack_toc_offset = GEN_INT (RS6000_TOC_SAVE_SLOT);
-      rtx stack_toc_mem = gen_frame_mem (Pmode,
-                                        gen_rtx_PLUS (Pmode, stack_ptr,
-                                                      stack_toc_offset));
-      rtx stack_toc_unspec = gen_rtx_UNSPEC (Pmode,
-                                            gen_rtvec (1, stack_toc_offset),
-                                            UNSPEC_TOCSLOT);
-      toc_restore = gen_rtx_SET (toc_reg, stack_toc_unspec);
-
-      /* Can we optimize saving the TOC in the prologue or
-        do we need to do it at every call?  */
-      if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca)
-       cfun->machine->save_toc_in_prologue = true;
-      else
-       {
-         MEM_VOLATILE_P (stack_toc_mem) = 1;
-         emit_move_insn (stack_toc_mem, toc_reg);
+  if (!SYMBOL_REF_P (func)
+      || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (func)))
+    {
+      if (!rs6000_pcrel_p (cfun))
+       {
+         /* Save the TOC into its reserved slot before the call,
+            and prepare to restore it after the call.  */
+         rtx stack_toc_offset = GEN_INT (RS6000_TOC_SAVE_SLOT);
+         rtx stack_toc_unspec = gen_rtx_UNSPEC (Pmode,
+                                                gen_rtvec (1, stack_toc_offset),
+                                                UNSPEC_TOCSLOT);
+         toc_restore = gen_rtx_SET (toc_reg, stack_toc_unspec);
+
+         /* Can we optimize saving the TOC in the prologue or
+            do we need to do it at every call?  */
+         if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca)
+           cfun->machine->save_toc_in_prologue = true;
+         else
+           {
+             rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
+             rtx stack_toc_mem = gen_frame_mem (Pmode,
+                                                gen_rtx_PLUS (Pmode, stack_ptr,
+                                                              stack_toc_offset));
+             MEM_VOLATILE_P (stack_toc_mem) = 1;
+             if (is_pltseq_longcall)
+               {
+                 rtvec v = gen_rtvec (3, toc_reg, func_desc, tlsarg);
+                 rtx mark_toc_reg = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
+                 emit_insn (gen_rtx_SET (stack_toc_mem, mark_toc_reg));
+               }
+             else
+               emit_move_insn (stack_toc_mem, toc_reg);
+           }
        }
 
       if (DEFAULT_ABI == ABI_ELFv2)
@@ -37533,8 +37886,23 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
          /* A function pointer in the ELFv2 ABI is just a plain address, but
             the ABI requires it to be loaded into r12 before the call.  */
          func_addr = gen_rtx_REG (Pmode, 12);
-         emit_move_insn (func_addr, func_desc);
+         if (!rtx_equal_p (func_addr, func))
+           emit_move_insn (func_addr, func);
          abi_reg = func_addr;
+         /* Indirect calls via CTR are strongly preferred over indirect
+            calls via LR, so move the address there.  Needed to mark
+            this insn for linker plt sequence editing too.  */
+         func_addr = gen_rtx_REG (Pmode, CTR_REGNO);
+         if (is_pltseq_longcall)
+           {
+             rtvec v = gen_rtvec (3, abi_reg, func_desc, tlsarg);
+             rtx mark_func = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
+             emit_insn (gen_rtx_SET (func_addr, mark_func));
+             v = gen_rtvec (2, func_addr, func_desc);
+             func_addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
+           }
+         else
+           emit_move_insn (func_addr, abi_reg);
        }
       else
        {
@@ -37546,9 +37914,15 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
             not have any executable code.  */
 
          /* Load up address of the actual function.  */
-         func_desc = force_reg (Pmode, func_desc);
+         func = force_reg (Pmode, func);
          func_addr = gen_reg_rtx (Pmode);
-         emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func_desc));
+         emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func));
+
+         /* Indirect calls via CTR are strongly preferred over indirect
+            calls via LR, so move the address there.  */
+         rtx ctr_reg = gen_rtx_REG (Pmode, CTR_REGNO);
+         emit_move_insn (ctr_reg, func_addr);
+         func_addr = ctr_reg;
 
          /* Prepare to load the TOC of the called function.  Note that the
             TOC load must happen immediately before the actual call so
@@ -37556,7 +37930,7 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
             comment in frob_update_context.  */
          rtx func_toc_offset = GEN_INT (GET_MODE_SIZE (Pmode));
          rtx func_toc_mem = gen_rtx_MEM (Pmode,
-                                         gen_rtx_PLUS (Pmode, func_desc,
+                                         gen_rtx_PLUS (Pmode, func,
                                                        func_toc_offset));
          toc_load = gen_rtx_USE (VOIDmode, func_toc_mem);
 
@@ -37564,14 +37938,15 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
             originally direct, the 3rd word has not been written since no
             trampoline has been built, so we ought not to load it, lest we
             override a static chain value.  */
-         if (!direct_call_p
+         if (!(GET_CODE (func_desc) == SYMBOL_REF
+               && SYMBOL_REF_FUNCTION_P (func_desc))
              && TARGET_POINTERS_TO_NESTED_FUNCTIONS
              && !chain_already_loaded (get_current_sequence ()->next->last))
            {
              rtx sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
              rtx func_sc_offset = GEN_INT (2 * GET_MODE_SIZE (Pmode));
              rtx func_sc_mem = gen_rtx_MEM (Pmode,
-                                            gen_rtx_PLUS (Pmode, func_desc,
+                                            gen_rtx_PLUS (Pmode, func,
                                                           func_sc_offset));
              emit_move_insn (sc_reg, func_sc_mem);
              abi_reg = sc_reg;
@@ -37580,15 +37955,17 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
     }
   else
     {
-      /* Direct calls use the TOC: for local calls, the callee will
-        assume the TOC register is set; for non-local calls, the
-        PLT stub needs the TOC register.  */
-      abi_reg = toc_reg;
-      func_addr = func_desc;
+      /* No TOC register needed for calls from PC-relative callers.  */
+      if (!rs6000_pcrel_p (cfun))
+       /* Direct calls use the TOC: for local calls, the callee will
+          assume the TOC register is set; for non-local calls, the
+          PLT stub needs the TOC register.  */
+       abi_reg = toc_reg;
+      func_addr = func;
     }
 
   /* Create the call.  */
-  call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), flag);
+  call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), tlsarg);
   if (value != NULL_RTX)
     call[0] = gen_rtx_SET (value, call[0]);
   n_call = 1;
@@ -37598,7 +37975,7 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
   if (toc_restore)
     call[n_call++] = toc_restore;
 
-  call[n_call++] = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO));
+  call[n_call++] = gen_hard_reg_clobber (Pmode, LR_REGNO);
 
   insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (n_call, call));
   insn = emit_call_insn (insn);
@@ -37612,15 +37989,18 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
 /* Expand code to perform a sibling call under the AIX or ELFv2 ABI.  */
 
 void
-rs6000_sibcall_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
+rs6000_sibcall_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
 {
   rtx call[2];
   rtx insn;
 
   gcc_assert (INTVAL (cookie) == 0);
 
+  if (global_tlsarg)
+    tlsarg = global_tlsarg;
+
   /* Create the call.  */
-  call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_desc), flag);
+  call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_desc), tlsarg);
   if (value != NULL_RTX)
     call[0] = gen_rtx_SET (value, call[0]);
 
@@ -37630,9 +38010,273 @@ rs6000_sibcall_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
   insn = emit_call_insn (insn);
 
   /* Note use of the TOC register.  */
-  use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, TOC_REGNUM));
+  if (!rs6000_pcrel_p (cfun))
+    use_reg (&CALL_INSN_FUNCTION_USAGE (insn),
+            gen_rtx_REG (Pmode, TOC_REGNUM));
+}
+
+/* Expand code to perform a call under the SYSV4 ABI.  */
+
+void
+rs6000_call_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
+{
+  rtx func = func_desc;
+  rtx func_addr;
+  rtx call[4];
+  rtx insn;
+  rtx abi_reg = NULL_RTX;
+  int n;
+
+  if (global_tlsarg)
+    tlsarg = global_tlsarg;
+
+  /* Handle longcall attributes.  */
+  if ((INTVAL (cookie) & CALL_LONG) != 0
+      && GET_CODE (func_desc) == SYMBOL_REF)
+    {
+      func = rs6000_longcall_ref (func_desc, tlsarg);
+      /* If the longcall was implemented as an inline PLT call using
+        PLT unspecs then func will be REG:r11.  If not, func will be
+        a pseudo reg.  The inline PLT call sequence supports lazy
+        linking (and longcalls to functions in dlopen'd libraries).
+        The other style of longcalls don't.  The lazy linking entry
+        to the dynamic symbol resolver requires r11 be the function
+        address (as it is for linker generated PLT stubs).  Ensure
+        r11 stays valid to the bctrl by marking r11 used by the call.  */
+      if (TARGET_PLTSEQ)
+       abi_reg = func;
+    }
+
+  /* Handle indirect calls.  */
+  if (GET_CODE (func) != SYMBOL_REF)
+    {
+      func = force_reg (Pmode, func);
+
+      /* Indirect calls via CTR are strongly preferred over indirect
+        calls via LR, so move the address there.  That can't be left
+        to reload because we want to mark every instruction in an
+        inline PLT call sequence with a reloc, enabling the linker to
+        edit the sequence back to a direct call when that makes sense.  */
+      func_addr = gen_rtx_REG (Pmode, CTR_REGNO);
+      if (abi_reg)
+       {
+         rtvec v = gen_rtvec (3, func, func_desc, tlsarg);
+         rtx mark_func = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
+         emit_insn (gen_rtx_SET (func_addr, mark_func));
+         v = gen_rtvec (2, func_addr, func_desc);
+         func_addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
+       }
+      else
+       emit_move_insn (func_addr, func);
+    }
+  else
+    func_addr = func;
+
+  /* Create the call.  */
+  call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), tlsarg);
+  if (value != NULL_RTX)
+    call[0] = gen_rtx_SET (value, call[0]);
+
+  call[1] = gen_rtx_USE (VOIDmode, cookie);
+  n = 2;
+  if (TARGET_SECURE_PLT
+      && flag_pic
+      && GET_CODE (func_addr) == SYMBOL_REF
+      && !SYMBOL_REF_LOCAL_P (func_addr))
+    call[n++] = gen_rtx_USE (VOIDmode, pic_offset_table_rtx);
+
+  call[n++] = gen_hard_reg_clobber (Pmode, LR_REGNO);
+
+  insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (n, call));
+  insn = emit_call_insn (insn);
+  if (abi_reg)
+    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), abi_reg);
+}
+
+/* Expand code to perform a sibling call under the SysV4 ABI.  */
+
+void
+rs6000_sibcall_sysv (rtx value, rtx func_desc, rtx tlsarg, rtx cookie)
+{
+  rtx func = func_desc;
+  rtx func_addr;
+  rtx call[3];
+  rtx insn;
+  rtx abi_reg = NULL_RTX;
+
+  if (global_tlsarg)
+    tlsarg = global_tlsarg;
+
+  /* Handle longcall attributes.  */
+  if ((INTVAL (cookie) & CALL_LONG) != 0
+      && GET_CODE (func_desc) == SYMBOL_REF)
+    {
+      func = rs6000_longcall_ref (func_desc, tlsarg);
+      /* If the longcall was implemented as an inline PLT call using
+        PLT unspecs then func will be REG:r11.  If not, func will be
+        a pseudo reg.  The inline PLT call sequence supports lazy
+        linking (and longcalls to functions in dlopen'd libraries).
+        The other style of longcalls don't.  The lazy linking entry
+        to the dynamic symbol resolver requires r11 be the function
+        address (as it is for linker generated PLT stubs).  Ensure
+        r11 stays valid to the bctr by marking r11 used by the call.  */
+      if (TARGET_PLTSEQ)
+       abi_reg = func;
+    }
+
+  /* Handle indirect calls.  */
+  if (GET_CODE (func) != SYMBOL_REF)
+    {
+      func = force_reg (Pmode, func);
+
+      /* Indirect sibcalls must go via CTR.  That can't be left to
+        reload because we want to mark every instruction in an inline
+        PLT call sequence with a reloc, enabling the linker to edit
+        the sequence back to a direct call when that makes sense.  */
+      func_addr = gen_rtx_REG (Pmode, CTR_REGNO);
+      if (abi_reg)
+       {
+         rtvec v = gen_rtvec (3, func, func_desc, tlsarg);
+         rtx mark_func = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
+         emit_insn (gen_rtx_SET (func_addr, mark_func));
+         v = gen_rtvec (2, func_addr, func_desc);
+         func_addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_PLTSEQ);
+       }
+      else
+       emit_move_insn (func_addr, func);
+    }
+  else
+    func_addr = func;
+
+  /* Create the call.  */
+  call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), tlsarg);
+  if (value != NULL_RTX)
+    call[0] = gen_rtx_SET (value, call[0]);
+
+  call[1] = gen_rtx_USE (VOIDmode, cookie);
+  call[2] = simple_return_rtx;
+
+  insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call));
+  insn = emit_call_insn (insn);
+  if (abi_reg)
+    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), abi_reg);
+}
+
+#if TARGET_MACHO
+
+/* Expand code to perform a call under the Darwin ABI.
+   Modulo handling of mlongcall, this is much the same as sysv.
+   if/when the longcall optimisation is removed, we could drop this
+   code and use the sysv case (taking care to avoid the tls stuff).
+
+   We can use this for sibcalls too, if needed.  */
+
+void
+rs6000_call_darwin_1 (rtx value, rtx func_desc, rtx tlsarg,
+                     rtx cookie, bool sibcall)
+{
+  rtx func = func_desc;
+  rtx func_addr;
+  rtx call[3];
+  rtx insn;
+  int cookie_val = INTVAL (cookie);
+  bool make_island = false;
+
+  /* Handle longcall attributes, there are two cases for Darwin:
+     1) Newer linkers are capable of synthesising any branch islands needed.
+     2) We need a helper branch island synthesised by the compiler.
+     The second case has mostly been retired and we don't use it for m64.
+     In fact, it's is an optimisation, we could just indirect as sysv does..
+     ... however, backwards compatibility for now.
+     If we're going to use this, then we need to keep the CALL_LONG bit set,
+     so that we can pick up the special insn form later.  */
+  if ((cookie_val & CALL_LONG) != 0
+      && GET_CODE (func_desc) == SYMBOL_REF)
+    {
+      if (darwin_emit_branch_islands && TARGET_32BIT)
+       make_island = true; /* Do nothing yet, retain the CALL_LONG flag.  */
+      else
+       {
+         /* The linker is capable of doing this, but the user explicitly
+            asked for -mlongcall, so we'll do the 'normal' version.  */
+         func = rs6000_longcall_ref (func_desc, NULL_RTX);
+         cookie_val &= ~CALL_LONG; /* Handled, zap it.  */
+       }
+    }
+
+  /* Handle indirect calls.  */
+  if (GET_CODE (func) != SYMBOL_REF)
+    {
+      func = force_reg (Pmode, func);
+
+      /* Indirect calls via CTR are strongly preferred over indirect
+        calls via LR, and are required for indirect sibcalls, so move
+        the address there.   */
+      func_addr = gen_rtx_REG (Pmode, CTR_REGNO);
+      emit_move_insn (func_addr, func);
+    }
+  else
+    func_addr = func;
+
+  /* Create the call.  */
+  call[0] = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (SImode, func_addr), tlsarg);
+  if (value != NULL_RTX)
+    call[0] = gen_rtx_SET (value, call[0]);
+
+  call[1] = gen_rtx_USE (VOIDmode, GEN_INT (cookie_val));
+
+  if (sibcall)
+    call[2] = simple_return_rtx;
+  else
+    call[2] = gen_hard_reg_clobber (Pmode, LR_REGNO);
+
+  insn = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (3, call));
+  insn = emit_call_insn (insn);
+  /* Now we have the debug info in the insn, we can set up the branch island
+     if we're using one.  */
+  if (make_island)
+    {
+      tree funname = get_identifier (XSTR (func_desc, 0));
+
+      if (no_previous_def (funname))
+       {
+         rtx label_rtx = gen_label_rtx ();
+         char *label_buf, temp_buf[256];
+         ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
+                                      CODE_LABEL_NUMBER (label_rtx));
+         label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
+         tree labelname = get_identifier (label_buf);
+         add_compiler_branch_island (labelname, funname,
+                                    insn_line ((const rtx_insn*)insn));
+       }
+     }
+}
+#endif
+
+void
+rs6000_call_darwin (rtx value ATTRIBUTE_UNUSED, rtx func_desc ATTRIBUTE_UNUSED,
+                   rtx tlsarg ATTRIBUTE_UNUSED, rtx cookie ATTRIBUTE_UNUSED)
+{
+#if TARGET_MACHO
+  rs6000_call_darwin_1 (value, func_desc, tlsarg, cookie, false);
+#else
+  gcc_unreachable();
+#endif
+}
+
+
+void
+rs6000_sibcall_darwin (rtx value ATTRIBUTE_UNUSED, rtx func_desc ATTRIBUTE_UNUSED,
+                      rtx tlsarg ATTRIBUTE_UNUSED, rtx cookie ATTRIBUTE_UNUSED)
+{
+#if TARGET_MACHO
+  rs6000_call_darwin_1 (value, func_desc, tlsarg, cookie, true);
+#else
+  gcc_unreachable();
+#endif
 }
 
+
 /* Return whether we need to always update the saved TOC pointer when we update
    the stack pointer.  */
 
@@ -37642,6 +38286,34 @@ rs6000_save_toc_in_prologue_p (void)
   return (cfun && cfun->machine && cfun->machine->save_toc_in_prologue);
 }
 
+/* Return whether we should generate PC-relative code for FNDECL.  */
+bool
+rs6000_fndecl_pcrel_p (const_tree fndecl)
+{
+  if (DEFAULT_ABI != ABI_ELFv2)
+    return false;
+
+  struct cl_target_option *opts = target_opts_for_fn (fndecl);
+
+  return ((opts->x_rs6000_isa_flags & OPTION_MASK_PCREL) != 0
+         && TARGET_CMODEL == CMODEL_MEDIUM);
+}
+
+/* Return whether we should generate PC-relative code for *FN.  */
+bool
+rs6000_pcrel_p (struct function *fn)
+{
+  if (DEFAULT_ABI != ABI_ELFv2)
+    return false;
+
+  /* Optimize usual case.  */
+  if (fn == cfun)
+    return ((rs6000_isa_flags & OPTION_MASK_PCREL) != 0
+           && TARGET_CMODEL == CMODEL_MEDIUM);
+
+  return rs6000_fndecl_pcrel_p (fn->decl);
+}
+
 #ifdef HAVE_GAS_HIDDEN
 # define USE_HIDDEN_LINKONCE 1
 #else
@@ -37764,7 +38436,7 @@ rs6000_split_logical_inner (rtx dest,
   rtx bool_rtx;
 
   /* Optimize AND of 0/0xffffffff and IOR/XOR of 0.  */
-  if (op2 && GET_CODE (op2) == CONST_INT
+  if (op2 && CONST_INT_P (op2)
       && (mode == SImode || (mode == DImode && TARGET_POWERPC64))
       && !complement_final_p && !complement_op1_p && !complement_op2_p)
     {
@@ -37864,7 +38536,7 @@ rs6000_split_logical_di (rtx operands[3],
     op2_hi_lo[hi] = op2_hi_lo[lo] = NULL_RTX;
   else
     {
-      if (GET_CODE (operands[2]) != CONST_INT)
+      if (!CONST_INT_P (operands[2]))
        {
          op2_hi_lo[hi] = gen_highpart_mode (SImode, DImode, operands[2]);
          op2_hi_lo[lo] = gen_lowpart (SImode, operands[2]);
@@ -37903,7 +38575,7 @@ rs6000_split_logical_di (rtx operands[3],
     {
       /* Split large IOR/XOR operations.  */
       if ((code == IOR || code == XOR)
-         && GET_CODE (op2_hi_lo[i]) == CONST_INT
+         && CONST_INT_P (op2_hi_lo[i])
          && !complement_final_p
          && !complement_op1_p
          && !complement_op2_p