summaryrefslogtreecommitdiff
path: root/gcc/config/s390/s390-c.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/s390/s390-c.c')
-rw-r--r--gcc/config/s390/s390-c.c149
1 files changed, 125 insertions, 24 deletions
diff --git a/gcc/config/s390/s390-c.c b/gcc/config/s390/s390-c.c
index fa69ed31fe5..d87cc90b0da 100644
--- a/gcc/config/s390/s390-c.c
+++ b/gcc/config/s390/s390-c.c
@@ -287,33 +287,57 @@ s390_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
return expand_this;
}
-/* Define platform dependent macros. */
-void
-s390_cpu_cpp_builtins (cpp_reader *pfile)
+/* Helper function that defines or undefines macros. If SET is true, the macro
+ MACRO_DEF is defined. If SET is false, the macro MACRO_UNDEF is undefined.
+ Nothing is done if SET and WAS_SET have the same value. */
+static void
+s390_def_or_undef_macro (cpp_reader *pfile,
+ unsigned int mask,
+ const struct cl_target_option *old_opts,
+ const struct cl_target_option *new_opts,
+ const char *macro_def, const char *macro_undef)
{
- cpp_assert (pfile, "cpu=s390");
- cpp_assert (pfile, "machine=s390");
- cpp_define (pfile, "__s390__");
- if (TARGET_ZARCH)
- cpp_define (pfile, "__zarch__");
- if (TARGET_64BIT)
- cpp_define (pfile, "__s390x__");
- if (TARGET_LONG_DOUBLE_128)
- cpp_define (pfile, "__LONG_DOUBLE_128__");
- if (TARGET_HTM)
- cpp_define (pfile, "__HTM__");
- if (TARGET_ZVECTOR)
- {
- cpp_define (pfile, "__VEC__=10301");
- cpp_define (pfile, "__vector=__attribute__((vector_size(16)))");
- cpp_define (pfile, "__bool=__attribute__((s390_vector_bool)) unsigned");
+ bool was_set;
+ bool set;
+
+ was_set = (!old_opts) ? false : old_opts->x_target_flags & mask;
+ set = new_opts->x_target_flags & mask;
+ if (was_set == set)
+ return;
+ if (set)
+ cpp_define (pfile, macro_def);
+ else
+ cpp_undef (pfile, macro_undef);
+}
- if (!flag_iso)
+/* Internal function to either define or undef the appropriate system
+ macros. */
+static void
+s390_cpu_cpp_builtins_internal (cpp_reader *pfile,
+ struct cl_target_option *opts,
+ const struct cl_target_option *old_opts)
+{
+ s390_def_or_undef_macro (pfile, MASK_OPT_HTM, old_opts, opts,
+ "__HTM__", "__HTM__");
+ s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
+ "__VEC__=10301", "__VEC__");
+ s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
+ "__vector=__attribute__((vector_size(16)))",
+ "__vector__");
+ s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
+ "__bool=__attribute__((s390_vector_bool)) unsigned",
+ "__bool");
+ if (!flag_iso)
+ {
+ s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
+ "__VECTOR_KEYWORD_SUPPORTED__",
+ "__VECTOR_KEYWORD_SUPPORTED__");
+ s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
+ "vector=vector", "vector");
+ s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
+ "bool=bool", "bool");
+ if (TARGET_ZVECTOR_P (opts->x_target_flags) && __vector_keyword == NULL)
{
- cpp_define (pfile, "__VECTOR_KEYWORD_SUPPORTED__");
- cpp_define (pfile, "vector=vector");
- cpp_define (pfile, "bool=bool");
-
__vector_keyword = get_identifier ("__vector");
C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
@@ -335,6 +359,79 @@ s390_cpu_cpp_builtins (cpp_reader *pfile)
}
}
+/* Define platform dependent macros. */
+void
+s390_cpu_cpp_builtins (cpp_reader *pfile)
+{
+ struct cl_target_option opts;
+
+ cpp_assert (pfile, "cpu=s390");
+ cpp_assert (pfile, "machine=s390");
+ cpp_define (pfile, "__s390__");
+ if (TARGET_ZARCH)
+ cpp_define (pfile, "__zarch__");
+ if (TARGET_64BIT)
+ cpp_define (pfile, "__s390x__");
+ if (TARGET_LONG_DOUBLE_128)
+ cpp_define (pfile, "__LONG_DOUBLE_128__");
+ cl_target_option_save (&opts, &global_options);
+ s390_cpu_cpp_builtins_internal (pfile, &opts, NULL);
+}
+
+#if S390_USE_TARGET_ATTRIBUTE
+/* Hook to validate the current #pragma GCC target and set the state, and
+ update the macros based on what was changed. If ARGS is NULL, then
+ POP_TARGET is used to reset the options. */
+
+static bool
+s390_pragma_target_parse (tree args, tree pop_target)
+{
+ tree prev_tree = build_target_option_node (&global_options);
+ tree cur_tree;
+
+ if (! args)
+ cur_tree = pop_target;
+ else
+ {
+ cur_tree = s390_valid_target_attribute_tree (args, &global_options,
+ &global_options_set, true);
+ if (!cur_tree || cur_tree == error_mark_node)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (prev_tree));
+ return false;
+ }
+ }
+
+ target_option_current_node = cur_tree;
+ s390_activate_target_options (target_option_current_node);
+
+ {
+ struct cl_target_option *prev_opt;
+ struct cl_target_option *cur_opt;
+
+ /* Figure out the previous/current differences. */
+ prev_opt = TREE_TARGET_OPTION (prev_tree);
+ cur_opt = TREE_TARGET_OPTION (cur_tree);
+
+ /* For the definitions, ensure all newly defined macros are considered
+ as used for -Wunused-macros. There is no point warning about the
+ compiler predefined macros. */
+ cpp_options *cpp_opts = cpp_get_options (parse_in);
+ unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
+
+ cpp_opts->warn_unused_macros = 0;
+
+ /* Define all of the macros for new options that were just turned on. */
+ s390_cpu_cpp_builtins_internal (parse_in, cur_opt, prev_opt);
+
+ cpp_opts->warn_unused_macros = saved_warn_unused_macros;
+ }
+
+ return true;
+}
+#endif
+
/* Expand builtins which can directly be mapped to tree expressions.
LOC - location information
FCODE - function code of the builtin
@@ -884,4 +981,8 @@ void
s390_register_target_pragmas (void)
{
targetm.resolve_overloaded_builtin = s390_resolve_overloaded_builtin;
+#if S390_USE_TARGET_ATTRIBUTE
+ /* Update pragma hook to allow parsing #pragma GCC target. */
+ targetm.target_option.pragma_parse = s390_pragma_target_parse;
+#endif
}