Hi Mike,
On 08/11/25 2:53 am, Michael Meissner wrote:
> I originally made a more complicated patch (V5) on September 22nd, 2025 that
> tried to do infrastructure cleanup as well as adding -mcpu=future. This patch
> is a more limited patch in that it just adds the -mcpu=future patch, and it
> does
> not do the other infrastructure work.
>
> I submitted the V6 patch on November 6th. However, in that patch, I
> forgot to add code to set the .machine directive to "future" if the
> user did -mcpu=future. This patch fixes this.
>
> This patch just adds support for -mcpu=future. Thanks to a question
> from Surya Kumari Jangal, I figured out a new method to do this patch.
>
> In the past, we would always add a new ISA flag for the cpu
> (i.e. -mpower11). But this means the user could potentially use
> -mfuture instead of -mcpu=future. To discourage this, we would then
> add a warning not to use the -m<xxx> direction.
>
> This patch now uses a separate variable (TARGET_FUTURE) that is set
> separately when the cpu type is set. This way we don't have to create
> a new dummy ISA option.
>
> The changes in this patch include:
>
> * The TARGET_FUTURE variable is set both in the inital cpu setup.
>
> * It is stored and restored as part of the target attribute and target
> pragma support.
>
> * The internal debug option -mdebug=reg now prints whether the TARGET_FUTURE
> field is set.
>
> * The macro _ARCH_FUTURE is defined if the user used -mcpu=future.
>
> * I added 2 tests to make sure -mcpu=future works.
>
> * If the user uses -mcpu=future, -mfuture is passed to the assembler.
>
> * I added support so the configuration option --with-cpu=future is
> used, it will set the default cpu type.
>
> Can I check this patch into the GCC trunk? I have built bootstrap
> builds on both a little endian Power10 system and a big endian Power9
> system and there were no regressions. On the little endian Power10
> system, I built the last run using the --with-cpu=future configuration
> option.
>
> 2025-11-07 Michael Meissner <[email protected]>
>
> gcc/
>
> * config.gcc (powerpc*-*-*): Add support for --with-cpu=future.
> * config/rs6000/aix71.h (ASM_CPU_SPEC): Pass -mfuture to the assembler
> if -mcpu=future is used.
> * config/rs6000/aix72.h (ASM_CPU_SPEC): Likewise.
> * config/rs6000/aix73.h (ASM_CPU_SPEC): Likewise.
> * config/rs6000/rs6000-c.cc (rs6000_target_modify_macros): Define
> _ARCH_FUTURE if -mcpu=future was used.
> (rs6000_cpu_cpp_builtins): Likewise.
> * config/rs6000/rs6000-cpus.def (FUTURE_MASKS_SERVER): New macro.
> (future cpu): Add support for -mcpu=future.
> * config/rs6000/rs6000-opts.h (PROCESSOR_FUTURE): Define to be power11.
> * config/rs6000/rs6000-protos.h (rs6000_target_modify_macros): Add
> -mcpu=future support.
> (rs6000_target_modify_macros_ptr): Likewise.
> * config/rs6000/rs6000-tables.opt: Regenerate.
> * config/rs6000/rs6000.cc (rs6000_target_modify_macros_ptr): Add
> -mcpu=future support.
> (rs6000_debug_reg_global): Likewise.
> (rs6000_option_override_internal): Likewise.
> (rs6000_machine_from_flags): Likewise.
> (rs6000_pragma_target_parse): Likewise.
> (rs6000_function_specific_save): Likewise.
> (rs6000_function_specific_restore): Likewise.
> (rs6000_function_specific_print): Likewise.
> (rs6000_print_options_internal): Likewise.
> (rs6000_print_isa_options): Likewise.
> * config/rs6000/rs6000.h (ASM_CPU_SPEC): Pass -mfuture to the assembler
> if -mcpu=future is used.
> (TARGET_FUTURE): New macro.
> * config/rs6000/rs6000.opt (TARGET_FUTURE): New target variable.
I believe the global variable rs6000_cpu can be used, at least in some
places in this patch wherever TARGET_FUTURE is being used. In other places
too, perhaps we can avoid this variable? The main issue is it is not
clear how will we handle any new processor that may be developed after the
potential FUTURE processor.
> (x_TARGET_FUTURE): Likewise.
> * doc/invoke.texi (RS/6000 and PowerPC Options): Document -mcpu=future.
>
> gcc/testsuite/
>
> * gcc.target/powerpc/future-1.c: New test.
> * gcc.target/powerpc/future-2.c: Likewise.
> ---
> gcc/config.gcc | 4 +-
> gcc/config/rs6000/aix71.h | 1 +
> gcc/config/rs6000/aix72.h | 1 +
> gcc/config/rs6000/aix73.h | 1 +
> gcc/config/rs6000/rs6000-c.cc | 16 +++-
> gcc/config/rs6000/rs6000-cpus.def | 4 +
> gcc/config/rs6000/rs6000-opts.h | 2 +
> gcc/config/rs6000/rs6000-protos.h | 5 +-
> gcc/config/rs6000/rs6000-tables.opt | 3 +
> gcc/config/rs6000/rs6000.cc | 81 ++++++++++++++++-----
> gcc/config/rs6000/rs6000.h | 11 +++
> gcc/config/rs6000/rs6000.opt | 7 ++
> gcc/doc/invoke.texi | 7 +-
> gcc/testsuite/gcc.target/powerpc/future-1.c | 13 ++++
> gcc/testsuite/gcc.target/powerpc/future-2.c | 24 ++++++
> 15 files changed, 151 insertions(+), 29 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/powerpc/future-1.c
> create mode 100644 gcc/testsuite/gcc.target/powerpc/future-2.c
>
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index b0fa43b5eba..205654a7998 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -542,7 +542,7 @@ powerpc*-*-*)
> extra_headers="${extra_headers} ppu_intrinsics.h spu2vmx.h vec_types.h
> si2vmx.h"
> extra_headers="${extra_headers} amo.h"
> case x$with_cpu in
> -
> xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[3456789]|xpower1[01]|xpower6x|xrs64a|xcell|xa2|xe500mc64|xe5500|xe6500)
> +
> xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[3456789]|xpower1[01]|xpower6x|xrs64a|xcell|xa2|xe500mc64|xe5500|xe6500|xfuture)
> cpu_is_64bit=yes
> ;;
> esac
> @@ -5749,7 +5749,7 @@ case "${target}" in
> tm_defines="${tm_defines} CONFIG_PPC405CR"
> eval "with_$which=405"
> ;;
> - "" | common | native \
> + "" | common | native | future \
> | power[3456789] | power1[01] | power5+ | power6x \
> | powerpc | powerpc64 | powerpc64le \
> | rs64 \
> diff --git a/gcc/config/rs6000/aix71.h b/gcc/config/rs6000/aix71.h
> index 2b21dd7cd1e..77651f5ea30 100644
> --- a/gcc/config/rs6000/aix71.h
> +++ b/gcc/config/rs6000/aix71.h
> @@ -79,6 +79,7 @@ do {
> \
> #undef ASM_CPU_SPEC
> #define ASM_CPU_SPEC \
> "%{mcpu=native: %(asm_cpu_native); \
> + mcpu=future: -mfuture; \
> mcpu=power11: -mpwr11; \
> mcpu=power10: -mpwr10; \
> mcpu=power9: -mpwr9; \
> diff --git a/gcc/config/rs6000/aix72.h b/gcc/config/rs6000/aix72.h
> index 53c0bde5ad4..652f60c7f49 100644
> --- a/gcc/config/rs6000/aix72.h
> +++ b/gcc/config/rs6000/aix72.h
> @@ -79,6 +79,7 @@ do {
> \
> #undef ASM_CPU_SPEC
> #define ASM_CPU_SPEC \
> "%{mcpu=native: %(asm_cpu_native); \
> + mcpu=future: -mfuture; \
> mcpu=power11: -mpwr11; \
> mcpu=power10: -mpwr10; \
> mcpu=power9: -mpwr9; \
> diff --git a/gcc/config/rs6000/aix73.h b/gcc/config/rs6000/aix73.h
> index c7639368a26..3c66ac1d917 100644
> --- a/gcc/config/rs6000/aix73.h
> +++ b/gcc/config/rs6000/aix73.h
> @@ -79,6 +79,7 @@ do {
> \
> #undef ASM_CPU_SPEC
> #define ASM_CPU_SPEC \
> "%{mcpu=native: %(asm_cpu_native); \
> + mcpu=future: -mfuture; \
> mcpu=power11: -mpwr11; \
> mcpu=power10: -mpwr10; \
> mcpu=power9: -mpwr9; \
> diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc
> index d3b0a566821..f9770ea0946 100644
> --- a/gcc/config/rs6000/rs6000-c.cc
> +++ b/gcc/config/rs6000/rs6000-c.cc
> @@ -338,13 +338,19 @@ rs6000_define_or_undefine_macro (bool define_p, const
> char *name)
> #pragma GCC target, we need to adjust the macros dynamically. */
>
> void
> -rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags)
> +rs6000_target_modify_macros (bool define_p,
> + HOST_WIDE_INT flags,
> + bool change_future_p,
> + bool future_p)
> {
> if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET)
> fprintf (stderr,
> - "rs6000_target_modify_macros (%s, " HOST_WIDE_INT_PRINT_HEX ")\n",
> + "rs6000_target_modify_macros (%s, " HOST_WIDE_INT_PRINT_HEX
> + ", change future: %s, future: %s)\n",
> (define_p) ? "define" : "undef",
> - flags);
> + flags,
> + change_future_p ? "true" : "false",
> + future_p ? "true" : "false");
>
> /* Each of the flags mentioned below controls whether certain
> preprocessor macros will be automatically defined when
> @@ -437,6 +443,8 @@ rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT
> flags)
> rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR10");
> if ((flags & OPTION_MASK_POWER11) != 0)
> rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR11");
> + if (change_future_p)
Can't we check for rs6000_cpu here instead of change_future_p, similar to
the following code that is already present:
/* Tell the user if we are targeting CELL. */
if (rs6000_cpu == PROCESSOR_CELL)
rs6000_define_or_undefine_macro (define_p, "__PPU__");
And thus we can avoid adding the two new parameters to
rs6000_target_modify_macros().
> + rs6000_define_or_undefine_macro (future_p, "_ARCH_FUTURE");
> if ((flags & OPTION_MASK_SOFT_FLOAT) != 0)
> rs6000_define_or_undefine_macro (define_p, "_SOFT_FLOAT");
> if ((flags & OPTION_MASK_RECIP_PRECISION) != 0)
> @@ -605,7 +613,7 @@ void
> rs6000_cpu_cpp_builtins (cpp_reader *pfile)
> {
> /* Define all of the common macros. */
> - rs6000_target_modify_macros (true, rs6000_isa_flags);
> + rs6000_target_modify_macros (true, rs6000_isa_flags, true, TARGET_FUTURE);
>
> if (TARGET_FRE)
> builtin_define ("__RECIP__");
> diff --git a/gcc/config/rs6000/rs6000-cpus.def
> b/gcc/config/rs6000/rs6000-cpus.def
> index 4a1037616d7..4cbbe94a010 100644
> --- a/gcc/config/rs6000/rs6000-cpus.def
> +++ b/gcc/config/rs6000/rs6000-cpus.def
> @@ -92,6 +92,9 @@
> | OPTION_MASK_FLOAT128_HW \
> | OPTION_MASK_P9_MINMAX)
>
> +/* Options for -mcpu=future. */
> +#define FUTURE_MASKS_SERVER POWER11_MASKS_SERVER
> +
> /* Flags that need to be turned off if -mno-altivec. */
> #define OTHER_ALTIVEC_MASKS (OTHER_VSX_VECTOR_MASKS \
> | OPTION_MASK_VSX)
> @@ -255,3 +258,4 @@ RS6000_CPU ("powerpc64", PROCESSOR_POWERPC64,
> OPTION_MASK_PPC_GFXOPT
> RS6000_CPU ("powerpc64le", PROCESSOR_POWER8, MASK_POWERPC64
> | ISA_2_7_MASKS_SERVER | OPTION_MASK_HTM)
> RS6000_CPU ("rs64", PROCESSOR_RS64A, OPTION_MASK_PPC_GFXOPT | MASK_POWERPC64)
> +RS6000_CPU ("future", PROCESSOR_FUTURE, MASK_POWERPC64 | FUTURE_MASKS_SERVER)
> diff --git a/gcc/config/rs6000/rs6000-opts.h b/gcc/config/rs6000/rs6000-opts.h
> index c31d2975f04..be2cacbd5e6 100644
> --- a/gcc/config/rs6000/rs6000-opts.h
> +++ b/gcc/config/rs6000/rs6000-opts.h
> @@ -71,6 +71,8 @@ enum processor_type
> PROCESSOR_TITAN
> };
Let us add PROCESSOR_FUTURE to 'enum processor_type'...
>
> +/* Treat -mcpu=future as -mcpu=power11. */
> +#define PROCESSOR_FUTURE PROCESSOR_POWER11
...and remove this macro definition.
>
> /* Types of costly dependences. */
> enum rs6000_dependence_cost
> diff --git a/gcc/config/rs6000/rs6000-protos.h
> b/gcc/config/rs6000/rs6000-protos.h
> index 234eb0ae2b3..5392eaf6309 100644
> --- a/gcc/config/rs6000/rs6000-protos.h
> +++ b/gcc/config/rs6000/rs6000-protos.h
> @@ -324,8 +324,9 @@ extern void rs6000_cpu_cpp_builtins (struct cpp_reader *);
> extern bool rs6000_pragma_target_parse (tree, tree);
> #endif
> extern void rs6000_activate_target_options (tree new_tree);
> -extern void rs6000_target_modify_macros (bool, HOST_WIDE_INT);
> -extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT);
> +extern void rs6000_target_modify_macros (bool, HOST_WIDE_INT, bool, bool);
> +extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, bool,
> + bool);
>
> #ifdef NO_DOLLAR_IN_LABEL
> const char * rs6000_xcoff_strip_dollar (const char *);
> diff --git a/gcc/config/rs6000/rs6000-tables.opt
> b/gcc/config/rs6000/rs6000-tables.opt
> index f5bbed5ea74..9e68c5a66e1 100644
> --- a/gcc/config/rs6000/rs6000-tables.opt
> +++ b/gcc/config/rs6000/rs6000-tables.opt
> @@ -200,3 +200,6 @@ Enum(rs6000_cpu_opt_value) String(powerpc64le) Value(56)
> EnumValue
> Enum(rs6000_cpu_opt_value) String(rs64) Value(57)
>
> +EnumValue
> +Enum(rs6000_cpu_opt_value) String(future) Value(58)
> +
Is it the norm to add this at the end of the file, or should it be added
after the entry for power11?
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index 1d5cd25c0f0..23d691d88e3 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -277,7 +277,7 @@ bool cpu_builtin_p = false;
> /* Pointer to function (in rs6000-c.cc) that can define or undefine target
> macros that have changed. Languages that don't support the preprocessor
> don't link in rs6000-c.cc, so we can't call it directly. */
> -void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT);
> +void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, bool, bool);
>
> /* Simplfy register classes into simpler classifications. We assume
> GPR_REG_TYPE - FPR_REG_TYPE are ordered so that we can use a simple range
> @@ -1170,7 +1170,7 @@ enum reg_class (*rs6000_preferred_reload_class_ptr)
> (rtx, enum reg_class)
> const int INSN_NOT_AVAILABLE = -1;
>
> static void rs6000_print_isa_options (FILE *, int, const char *,
> - HOST_WIDE_INT);
> + HOST_WIDE_INT, bool);
> static HOST_WIDE_INT rs6000_disable_incompatible_switches (void);
>
> static enum rs6000_reg_type register_to_reg_type (rtx, bool *);
> @@ -2398,9 +2398,11 @@ rs6000_debug_reg_global (void)
> const char *name = processor_target_table[rs6000_cpu_index].name;
> HOST_WIDE_INT flags
> = processor_target_table[rs6000_cpu_index].target_enable;
> + bool future = strcmp (processor_target_table[rs6000_cpu_index].name,
> + "future") == 0;
>
> sprintf (flags_buffer, "-mcpu=%s flags", name);
> - rs6000_print_isa_options (stderr, 0, flags_buffer, flags);
> + rs6000_print_isa_options (stderr, 0, flags_buffer, flags, future);
> }
> else
> fprintf (stderr, DEBUG_FMT_S, "cpu", "<none>");
> @@ -2410,21 +2412,24 @@ rs6000_debug_reg_global (void)
> const char *name = processor_target_table[rs6000_tune_index].name;
> HOST_WIDE_INT flags
> = processor_target_table[rs6000_tune_index].target_enable;
> + bool future = strcmp (processor_target_table[rs6000_tune_index].name,
> + "future") == 0;
>
> sprintf (flags_buffer, "-mtune=%s flags", name);
> - rs6000_print_isa_options (stderr, 0, flags_buffer, flags);
> + rs6000_print_isa_options (stderr, 0, flags_buffer, flags, future);
> }
> else
> fprintf (stderr, DEBUG_FMT_S, "tune", "<none>");
>
> cl_target_option_save (&cl_opts, &global_options, &global_options_set);
> rs6000_print_isa_options (stderr, 0, "rs6000_isa_flags",
> - rs6000_isa_flags);
> + rs6000_isa_flags, TARGET_FUTURE);
>
> rs6000_print_isa_options (stderr, 0, "rs6000_isa_flags_explicit",
> - rs6000_isa_flags_explicit);
> + rs6000_isa_flags_explicit, false);
>
> - rs6000_print_isa_options (stderr, 0, "TARGET_DEFAULT", TARGET_DEFAULT);
> + rs6000_print_isa_options (stderr, 0, "TARGET_DEFAULT", TARGET_DEFAULT,
> + false);
>
> fprintf (stderr, DEBUG_FMT_S, "--with-cpu default",
> OPTION_TARGET_CPU_DEFAULT ? OPTION_TARGET_CPU_DEFAULT : "<none>");
> @@ -3621,7 +3626,8 @@ rs6000_option_override_internal (bool global_init_p)
>
> /* Print defaults. */
> if ((TARGET_DEBUG_REG || TARGET_DEBUG_TARGET) && global_init_p)
> - rs6000_print_isa_options (stderr, 0, "TARGET_DEFAULT", TARGET_DEFAULT);
> + rs6000_print_isa_options (stderr, 0, "TARGET_DEFAULT", TARGET_DEFAULT,
> + false);
>
> /* Remember the explicit arguments. */
> if (global_init_p)
> @@ -3725,6 +3731,8 @@ rs6000_option_override_internal (bool global_init_p)
> rs6000_isa_flags &= ~set_masks;
> rs6000_isa_flags |= (processor_target_table[cpu_index].target_enable
> & set_masks);
> + TARGET_FUTURE = strcmp (processor_target_table[cpu_index].name,
> + "future") == 0;
How will we handle any potential new processor that may be developed
after the potential FUTURE processor?
> }
> else
> {
> @@ -3750,6 +3758,7 @@ rs6000_option_override_internal (bool global_init_p)
> flags = processor_target_table[default_cpu_index].target_enable;
> }
> rs6000_isa_flags |= (flags & ~rs6000_isa_flags_explicit);
> + TARGET_FUTURE = false;
> }
>
> /* Don't expect powerpc64 enabled on those OSes with OS_MISSING_POWERPC64,
> @@ -3871,7 +3880,8 @@ rs6000_option_override_internal (bool global_init_p)
> & ~rs6000_isa_flags_explicit);
>
> if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
> - rs6000_print_isa_options (stderr, 0, "before defaults",
> rs6000_isa_flags);
> + rs6000_print_isa_options (stderr, 0, "before defaults", rs6000_isa_flags,
> + TARGET_FUTURE);
How will we pass a flag for a potential new processor that may be developed
after the potential FUTURE processor?
Can rs6000_cpu be used inside rs6000_print_isa_options(), instead of having to
pass TARGET_FUTURE?
>
> #ifdef XCOFF_DEBUGGING_INFO
> /* For AIX default to 64-bit DWARF. */
> @@ -4232,7 +4242,8 @@ rs6000_option_override_internal (bool global_init_p)
>
> /* 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_print_isa_options (stderr, 0, "after defaults", rs6000_isa_flags,
> + TARGET_FUTURE);
>
> /* E500mc does "better" if we inline more aggressively. Respect the
> user's opinion, though. */
> @@ -4339,7 +4350,8 @@ rs6000_option_override_internal (bool global_init_p)
> TARGET_NO_FP_IN_TOC = 1;
>
> if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
> - rs6000_print_isa_options (stderr, 0, "before subtarget",
> rs6000_isa_flags);
> + rs6000_print_isa_options (stderr, 0, "before subtarget",
> rs6000_isa_flags,
> + TARGET_FUTURE);
>
> #ifdef SUBTARGET_OVERRIDE_OPTIONS
> SUBTARGET_OVERRIDE_OPTIONS;
> @@ -4406,7 +4418,8 @@ rs6000_option_override_internal (bool global_init_p)
> rs6000_isa_flags &= ~OPTION_MASK_PCREL_OPT;
>
> if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
> - rs6000_print_isa_options (stderr, 0, "after subtarget",
> rs6000_isa_flags);
> + rs6000_print_isa_options (stderr, 0, "after subtarget", rs6000_isa_flags,
> + TARGET_FUTURE);
>
> rs6000_always_hint = (rs6000_tune != PROCESSOR_POWER4
> && rs6000_tune != PROCESSOR_POWER5
> @@ -5913,6 +5926,8 @@ rs6000_machine_from_flags (void)
> flags &= ~(OPTION_MASK_PPC_GFXOPT | OPTION_MASK_PPC_GPOPT |
> OPTION_MASK_ISEL
> | OPTION_MASK_ALTIVEC);
>
> + if (TARGET_FUTURE)
> + return "future";
Can't we check for rs6000_cpu instead, similar to the following code:
/* Cell BE */
if (rs6000_cpu == PROCESSOR_CELL)
return "cell";
-Surya
> if ((flags & (POWER11_MASKS_SERVER & ~ISA_3_1_MASKS_SERVER)) != 0)
> return "power11";
> if ((flags & (ISA_3_1_MASKS_SERVER & ~ISA_3_0_MASKS_SERVER)) != 0)
> @@ -24879,6 +24894,7 @@ rs6000_pragma_target_parse (tree args, tree
> pop_target)
> tree cur_tree;
> struct cl_target_option *prev_opt, *cur_opt;
> HOST_WIDE_INT prev_flags, cur_flags, diff_flags;
> + bool prev_future, cur_future, diff_future;
>
> if (TARGET_DEBUG_TARGET)
> {
> @@ -24931,21 +24947,28 @@ rs6000_pragma_target_parse (tree args, tree
> pop_target)
> {
> prev_opt = TREE_TARGET_OPTION (prev_tree);
> prev_flags = prev_opt->x_rs6000_isa_flags;
> + prev_future = prev_opt->x_TARGET_FUTURE;
>
> cur_opt = TREE_TARGET_OPTION (cur_tree);
> cur_flags = cur_opt->x_rs6000_isa_flags;
> + cur_future = cur_opt->x_TARGET_FUTURE;
>
> diff_flags = (prev_flags ^ cur_flags);
> + diff_future = (prev_future ^ cur_future);
>
> - if (diff_flags != 0)
> + if (diff_flags != 0 || diff_future)
> {
> /* Delete old macros. */
> rs6000_target_modify_macros_ptr (false,
> - prev_flags & diff_flags);
> + prev_flags & diff_flags,
> + diff_future,
> + prev_future);
>
> /* Define new macros. */
> rs6000_target_modify_macros_ptr (true,
> - cur_flags & diff_flags);
> + cur_flags & diff_flags,
> + diff_future,
> + cur_future);
> }
> }
>
> @@ -25059,6 +25082,7 @@ rs6000_function_specific_save (struct
> cl_target_option *ptr,
> {
> ptr->x_rs6000_isa_flags = opts->x_rs6000_isa_flags;
> ptr->x_rs6000_isa_flags_explicit = opts->x_rs6000_isa_flags_explicit;
> + ptr->x_TARGET_FUTURE = opts->x_TARGET_FUTURE;
> }
>
> /* Restore the current options */
> @@ -25071,6 +25095,7 @@ rs6000_function_specific_restore (struct gcc_options
> *opts,
> {
> opts->x_rs6000_isa_flags = ptr->x_rs6000_isa_flags;
> opts->x_rs6000_isa_flags_explicit = ptr->x_rs6000_isa_flags_explicit;
> + opts->x_TARGET_FUTURE = ptr->x_TARGET_FUTURE;
> (void) rs6000_option_override_internal (false);
> }
>
> @@ -25081,10 +25106,12 @@ rs6000_function_specific_print (FILE *file, int
> indent,
> struct cl_target_option *ptr)
> {
> rs6000_print_isa_options (file, indent, "Isa options set",
> - ptr->x_rs6000_isa_flags);
> + ptr->x_rs6000_isa_flags,
> + ptr->x_TARGET_FUTURE);
>
> rs6000_print_isa_options (file, indent, "Isa options explicit",
> - ptr->x_rs6000_isa_flags_explicit);
> + ptr->x_rs6000_isa_flags_explicit,
> + ptr->x_TARGET_FUTURE);
> }
>
> /* Helper function to print the current isa or misc options on a line. */
> @@ -25096,7 +25123,8 @@ rs6000_print_options_internal (FILE *file,
> HOST_WIDE_INT flags,
> const char *prefix,
> const struct rs6000_opt_mask *opts,
> - size_t num_elements)
> + size_t num_elements,
> + bool future)
> {
> size_t i;
> size_t start_column = 0;
> @@ -25162,6 +25190,18 @@ rs6000_print_options_internal (FILE *file,
> comma_len = strlen (", ");
> }
>
> + if (future)
> + {
> + cur_column += sizeof ("-mcpu=future") - 1;
> + if (cur_column > max_column)
> + {
> + fprintf (stderr, ", \\\n%*s", (int)start_column, "");
> + comma = "";
> + }
> +
> + fprintf (file, "%s%s", comma, "-mcpu=future");
> + }
> +
> fputs ("\n", file);
> }
>
> @@ -25169,11 +25209,12 @@ rs6000_print_options_internal (FILE *file,
>
> static void
> rs6000_print_isa_options (FILE *file, int indent, const char *string,
> - HOST_WIDE_INT flags)
> + HOST_WIDE_INT flags, bool future)
> {
> rs6000_print_options_internal (file, indent, string, flags, "-m",
> &rs6000_opt_masks[0],
> - ARRAY_SIZE (rs6000_opt_masks));
> + ARRAY_SIZE (rs6000_opt_masks),
> + future);
> }
>
> /* If the user used -mno-vsx, we need turn off all of the implicit ISA 2.06,
> diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
> index db6112a09e1..3a5695570bc 100644
> --- a/gcc/config/rs6000/rs6000.h
> +++ b/gcc/config/rs6000/rs6000.h
> @@ -101,6 +101,7 @@
> you make changes here, make them also there. */
> #define ASM_CPU_SPEC \
> "%{mcpu=native: %(asm_cpu_native); \
> + mcpu=future: -mfuture; \
> mcpu=power11: -mpower11; \
> mcpu=power10: -mpower10; \
> mcpu=power9: -mpower9; \
> @@ -555,6 +556,16 @@ extern int rs6000_vector_align[];
> #define TARGET_DIRECT_MOVE_64BIT (TARGET_DIRECT_MOVE \
> && TARGET_POWERPC64)
>
> +/* Is this a future machine with potentially new feaatures? */
> +#ifndef TARGET_FUTURE
> +#ifdef GENERATOR_FILE
> +#define TARGET_FUTURE false
> +#else
> +#define TARGET_FUTURE global_options.x_TARGET_FUTURE
> +#endif
> +#endif
> +
> +
> /* Inlining allows targets to define the meanings of bits in target_info
> field of ipa_fn_summary by itself, the used bits for rs6000 are listed
> below. */
> diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
> index 88cf16ca581..489c85c9bb3 100644
> --- a/gcc/config/rs6000/rs6000.opt
> +++ b/gcc/config/rs6000/rs6000.opt
> @@ -44,6 +44,13 @@ enum processor_type rs6000_cpu = PROCESSOR_PPC603
> TargetVariable
> enum processor_type rs6000_tune = PROCESSOR_PPC603
>
> +;; Whether the current processor is a potential future processor
> +Variable
> +bool TARGET_FUTURE = false
> +
> +TargetSave
> +bool x_TARGET_FUTURE
> +
> ;; Always emit branch hint bits.
> TargetVariable
> unsigned char rs6000_always_hint
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 07a21fd7fc9..b7fcfb87c74 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -32047,7 +32047,7 @@ Supported values for @var{cpu_type} are @samp{401},
> @samp{403},
> @samp{titan}, @samp{power3}, @samp{power4}, @samp{power5}, @samp{power5+},
> @samp{power6}, @samp{power6x}, @samp{power7}, @samp{power8},
> @samp{power9}, @samp{power10}, @samp{power11}, @samp{powerpc},
> @samp{powerpc64},
> -@samp{powerpc64le}, @samp{rs64}, and @samp{native}.
> +@samp{powerpc64le}, @samp{rs64}, @samp{future}, and @samp{native}.
>
> @option{-mcpu=powerpc}, @option{-mcpu=powerpc64}, and
> @option{-mcpu=powerpc64le} specify pure 32-bit PowerPC (either
> @@ -32055,6 +32055,11 @@ endian), 64-bit big endian PowerPC and 64-bit little
> endian PowerPC
> architecture machine types, with an appropriate, generic processor
> model assumed for scheduling purposes.
>
> +Specifying @samp{future} as cpu type adds support for new instructions
> +that may be added to future PowerPC processors. This support is meant
> +to try out possible new PowerPC instructions, and these instruction
> +may or may not be used in new official PowerPC processors.
> +
> Specifying @samp{native} as cpu type detects and selects the
> architecture option that corresponds to the host processor of the
> system performing the compilation.
> diff --git a/gcc/testsuite/gcc.target/powerpc/future-1.c
> b/gcc/testsuite/gcc.target/powerpc/future-1.c
> new file mode 100644
> index 00000000000..7bd8e5ddbd0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/future-1.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mdejagnu-cpu=future -O2" } */
> +
> +/* Basic check to see if the compiler supports -mcpu=future and if it defines
> + _ARCH_FUTURE. */
> +
> +#ifndef _ARCH_FUTURE
> +#error "-mcpu=future is not supported"
> +#endif
> +
> +void foo (void)
> +{
> +}
> diff --git a/gcc/testsuite/gcc.target/powerpc/future-2.c
> b/gcc/testsuite/gcc.target/powerpc/future-2.c
> new file mode 100644
> index 00000000000..5552cefa3c2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/future-2.c
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +/* Check if we can set the future target via a target attribute. */
> +
> +__attribute__((__target__("cpu=power9")))
> +void foo_p9 (void)
> +{
> +}
> +
> +__attribute__((__target__("cpu=power10")))
> +void foo_p10 (void)
> +{
> +}
> +
> +__attribute__((__target__("cpu=power11")))
> +void foo_p11 (void)
> +{
> +}
> +
> +__attribute__((__target__("cpu=future")))
> +void foo_future (void)
> +{
> +}