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);
&& 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);
|| 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
break;
case PROCESSOR_POWER9:
+ case PROCESSOR_FUTURE:
rs6000_cost = &power9_cost;
break;
/* 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
}
#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)
{
case PROCESSOR_POWER8:
case PROCESSOR_POWER9:
+ case PROCESSOR_FUTURE:
if (DECIMAL_FLOAT_MODE_P (mode))
return 1;
if (VECTOR_MODE_P (mode))
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. */
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))
|| 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))
case PROCESSOR_POWER8:
return 7;
case PROCESSOR_POWER9:
+ case PROCESSOR_FUTURE:
return 6;
default:
return 1;
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)
+ 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);
{ "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 },
{ "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 },
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