diff options
Diffstat (limited to 'gcc/config/s390/s390-c.c')
-rw-r--r-- | gcc/config/s390/s390-c.c | 149 |
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 } |