rs6000-cpus.def (ISA_FUTURE_MASKS_SERVER): Add OPTION_MASK_PCREL.
[gcc.git] / gcc / config / rs6000 / rs6000.c
index ff51e48eae46bac1a4ef738d1ba0c7025936f13a..7a2e43fd72a33c0f5316b627ee88db10f3eaaa69 100644 (file)
@@ -1368,10 +1368,6 @@ static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree,
 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);
@@ -1392,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;
 
@@ -1464,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
 
@@ -1737,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
@@ -2513,67 +2508,39 @@ 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)
@@ -3011,9 +2978,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;
 
@@ -3050,7 +3014,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));
@@ -3187,26 +3151,14 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
        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)
     {
@@ -3233,19 +3185,6 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
   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;
@@ -3253,20 +3192,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  */
@@ -3274,31 +3206,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)
     {
@@ -3463,13 +3374,13 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
   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; 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)
@@ -3869,6 +3780,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
@@ -3989,7 +3903,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;
@@ -3997,14 +3911,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)
@@ -4130,10 +4044,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);
@@ -4145,7 +4059,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;
@@ -4280,7 +4194,7 @@ 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;
     }
@@ -4315,9 +4229,11 @@ rs6000_option_override_internal (bool global_init_p)
            {
              warned_change_long_double = true;
              if (TARGET_IEEEQUAD)
-               warning (OPT_Wpsabi, "Using IEEE extended precision long double");
+               warning (OPT_Wpsabi, "Using IEEE extended precision "
+                        "%<long double%>");
              else
-               warning (OPT_Wpsabi, "Using IBM extended precision long double");
+               warning (OPT_Wpsabi, "Using IBM extended precision "
+                        "%<long double%>");
            }
        }
     }
@@ -4335,7 +4251,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
@@ -4344,7 +4260,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");
        }
     }
 
@@ -4367,7 +4283,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;
     }
@@ -4375,11 +4291,20 @@ 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 the prefixed load/store support on FUTURE systems.  */
+  if (!TARGET_FUTURE && TARGET_PCREL)
+    {
+      if ((rs6000_isa_flags_explicit & OPTION_MASK_PCREL) != 0)
+       error ("%qs requires %qs", "-mpcrel", "-mcpu=future");
+
+      rs6000_isa_flags &= ~OPTION_MASK_PCREL;
+    }
+
   /* 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);
@@ -4422,8 +4347,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;
        }
@@ -4522,6 +4445,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);
@@ -4535,6 +4459,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
@@ -4835,6 +4760,7 @@ rs6000_option_override_internal (bool global_init_p)
        break;
 
       case PROCESSOR_POWER9:
+      case PROCESSOR_FUTURE:
        rs6000_cost = &power9_cost;
        break;
 
@@ -5718,6 +5644,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
@@ -5783,27 +5742,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)
@@ -6891,7 +6833,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:
@@ -6942,6 +6883,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;
@@ -6971,18 +6916,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));
+      /* 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
+    {
+      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);
 
-  emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
+      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
@@ -7151,7 +7110,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);
 
@@ -7162,6 +7121,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));
@@ -7170,7 +7133,9 @@ 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;
       unsigned int dest_regno = reg_or_subregno (dest);
       unsigned int src_regno = reg_or_subregno (src);
@@ -7246,7 +7211,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));
@@ -7304,8 +7269,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;
          }
 
@@ -7640,14 +7605,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
@@ -8110,8 +8071,7 @@ legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict)
         function says opposite.  In most cases, LRA through different
         transformations can generate correct code for address reloads.
         It cannot 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.  */
+        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)
@@ -8763,6 +8723,11 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
          else
            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)
        {
@@ -8781,6 +8746,11 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
            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)
            {
              if (TARGET_64BIT)
@@ -8879,290 +8849,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
-      && REG_P (XEXP (XEXP (x, 0), 0))
-      && CONST_INT_P (XEXP (XEXP (x, 0), 1))
-      && CONST_INT_P (XEXP (x, 1)))
-    {
-      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))
-      && HARD_REGISTER_P (XEXP (x, 0))
-      && 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 (SYMBOL_REF_P (x)
-      && 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
-      && REG_P (XEXP (XEXP (x, 0), 0))
-      && CONST_INT_P (XEXP (XEXP (x, 0), 1))
-      && CONST_INT_P (XEXP (x, 1))
-      && INTVAL (XEXP (x, 1)) == -16)
-    {
-      x = XEXP (x, 0);
-      *win = 1;
-      return x;
-    }
-
-  if (TARGET_TOC
-      && reg_offset_p
-      && !quad_offset_p
-      && SYMBOL_REF_P (x)
-      && 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
@@ -9438,6 +9124,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))
@@ -9462,10 +9149,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]
@@ -9887,7 +9570,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))
     {
@@ -12058,7 +11741,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");
                }
            }
@@ -13343,7 +13026,7 @@ rs6000_expand_zeroop_builtin (enum insn_code icode, rtx target)
   if (icode == CODE_FOR_rs6000_mffsl
       && 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;
     }
 
@@ -13415,7 +13098,8 @@ rs6000_expand_mtfsb_builtin (enum insn_code icode, tree exp)
 
   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;
     }
 
@@ -13452,7 +13136,7 @@ rs6000_expand_set_fpscr_rn_builtin (enum insn_code icode, tree exp)
 
   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;
     }
 
@@ -13492,11 +13176,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 & 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;
     }
 
@@ -14060,23 +13745,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
@@ -14193,7 +13861,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.  */
@@ -14214,7 +13881,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);
@@ -14533,7 +14200,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);
        }
     }
@@ -14666,7 +14333,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;
     }
 
@@ -14720,9 +14387,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));
@@ -14978,7 +14653,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;
@@ -14993,7 +14668,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;
@@ -15233,7 +14908,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 "
@@ -16105,22 +15781,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);
@@ -17687,6 +17354,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:
@@ -17702,9 +17370,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:
@@ -20197,7 +19869,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;
@@ -20345,7 +20017,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.  */
@@ -23971,7 +23643,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;
                }
@@ -24999,6 +24671,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");
 }
 
@@ -25447,16 +25122,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);
@@ -27858,7 +27533,17 @@ 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.  */
@@ -27987,7 +27672,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;
@@ -28149,16 +27834,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;
@@ -28170,30 +27847,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
@@ -28203,10 +27888,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.)
@@ -28215,19 +27897,31 @@ 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_hard_reg_clobber (Pmode, 11);
@@ -28246,6 +27940,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);
@@ -28470,7 +28165,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
@@ -28630,9 +28325,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
@@ -28698,7 +28393,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;
 
@@ -28889,13 +28584,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)
        {
@@ -28920,7 +28615,7 @@ 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);
@@ -28959,7 +28654,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 ());
@@ -29321,7 +29016,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]);
     }
@@ -29329,7 +29024,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)
@@ -29514,6 +29210,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;
 
@@ -29587,9 +29284,11 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
      assemble_start_function and assemble_end_function.  */
   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;
@@ -30500,7 +30199,8 @@ 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
            && MEM_P (XEXP (PATTERN (insn), 1))
@@ -30538,6 +30238,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))
@@ -31117,6 +30818,7 @@ rs6000_issue_rate (void)
   case PROCESSOR_POWER8:
     return 7;
   case PROCESSOR_POWER9:
+  case PROCESSOR_FUTURE:
     return 6;
   default:
     return 1;
@@ -33256,7 +32958,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);
@@ -33309,7 +33011,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);
@@ -33335,8 +33037,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)
@@ -33826,6 +33528,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,
@@ -33836,10 +33542,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);
 
@@ -34020,6 +33722,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,
@@ -34926,22 +34630,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.  */
@@ -34954,24 +34697,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)
@@ -34981,7 +34714,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--;
@@ -35024,6 +34757,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.  */
 
@@ -36114,7 +35905,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
@@ -36227,38 +36018,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 */
@@ -36443,6 +36274,7 @@ 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  },
@@ -36451,6 +36283,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "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  },
@@ -37389,7 +37222,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
 
@@ -37464,6 +37297,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;
@@ -38289,6 +38123,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