summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-04 14:30:42 +0000
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-04 14:30:42 +0000
commit7a0cee35f9d427ed7e17ac99bbfac0c437278743 (patch)
tree94300fd777cd59b02e41f3e7bbfeeba143dc1b6c /gcc/config
parent9841c6ee5b694050bb3fbff91fd094888aa8e9c3 (diff)
downloadgcc-7a0cee35f9d427ed7e17ac99bbfac0c437278743.tar.gz
[PATCH 1/2] S/390: Implement "target" attribute.
gcc/ChangeLog * config/s390/s390.opt (s390_arch_string): Remove. (s390_tune_string): Likewise. (s390_cost_pointer): Add Variable. (s390_tune_flags): Add TargetVariable. (s390_arch_flags, march=, mbackchain, mdebug, mesa, mhard-dfp), (mhard-float, mlong-double-128, mlong-double-64, mhtm, mvx), (mpacked-stack, msmall-exec, msoft-float, mstack-guard=, mstack-size=), (mtune=, mmvcle, mzvector, mzarch, mbranch-cost=, mwarn-dynamicstack), (mwarn-framesize=): Save option. (mno-stack-guard, mno-stack-guard): New option. (mwarn-dynamicstack): Allow mno-warn-dynamicstack. (mwarn-framesize=): Convert to UInteger (negative values are rejected now). * config/s390/s390-c.c (s390_cpu_cpp_builtins_internal): Split setting macros changeable through the GCC target pragma into a separate function. (s390_cpu_cpp_builtins): Likewise. (s390_pragma_target_parse): New function, implement GCC target pragma if enabled. (s390_register_target_pragmas): Register s390_pragma_target_parse if available. * common/config/s390/s390-common.c (s390_handle_option): Export. Move setting s390_arch_flags to s390.c. Remove s390_tune_flags. Allow 0 as argument to -mstack-size (switch to default value). Allow 0 as argument to -mstack-guard (switch off). Remove now unnecessary explicit parsing code for -mwarn-framesize. * config/s390/s390-protos.h (s390_handle_option): Export. (s390_valid_target_attribute_tree): Export. (s390_reset_previous_fndecl): Export. * config/s390/s390-builtins.def: Use new macro B_GROUP to mark the start and end of HTM and VX builtins. (s390_asm_output_function_prefix): Declare hook. (s390_asm_declare_function_size): Likewise. * config/s390/s390-builtins.h (B_GROUP): Use macro. * config/s390/s390-opts.h: Add comment about processor_type usage. * config/s390/s390.h (TARGET_CPU_IEEE_FLOAT_P, TARGET_CPU_ZARCH_P), (TARGET_CPU_LONG_DISPLACEMENT_P, TARGET_CPU_EXTIMM_P, TARGET_CPU_DFP_P), (TARGET_CPU_Z10_P, TARGET_CPU_Z196_P, TARGET_CPU_ZEC12_P), (TARGET_CPU_HTM_P, TARGET_CPU_Z13_P, TARGET_CPU_VX_P), (TARGET_HARD_FLOAT_P, TARGET_LONG_DISPLACEMENT_P, TARGET_EXTIMM_P), (TARGET_DFP_P, TARGET_Z10_P, TARGET_Z196_P, TARGET_ZEC12_P), (TARGET_HTM_P, TARGET_Z13_P, TARGET_VX_P, TARGET_CPU_EXTIMM), (TARGET_CPU_DFP, TARGET_CPU_Z10, TARGET_CPU_Z196, TARGET_CPU_ZEC12), (TARGET_CPU_HTM, TARGET_CPU_Z13, TARGET_LONG_DISPLACEMENT), (TARGET_EXTIMM, TARGET_DFP, TARGET_Z10, TARGET_Z196, TARGET_ZEC12), (TARGET_Z13, TARGET_VX, S390_USE_TARGET_ATTRIBUTE), (S390_USE_ARCHITECTURE_MODIFIERS, SWITCHABLE_TARGET), (ASM_DECLARE_FUNCTION_SIZE, ASM_OUTPUT_FUNCTION_PREFIX): Likewise. * config/s390/vecintrin.h: Use vector definitions even if __VEC__ is undefined. (vec_all_nan): Rewrite as macro using statement expressions to avoid that the vector keyword needs to be defined when including the file. (vec_all_numeric): Likewise. (vec_any_nan): Likewise. (vec_any_numeric): Likewise. * config/s390/s390.c (s390_previous_fndecl): New static variable. (s390_set_current_function): New function. (s390_cost): Wrapper macro to allow defining the cost table pointer in the options file. (processor_table): Table for march= and mtune= parsing. (s390_init_builtins): Enable all builtins and types unconditionally. (s390_expand_builtin): Generate an error message if builtin is not supported by current options. Correct an error message. (s390_function_specific_restore): New function to set s390_cost. (s390_asm_output_machine_for_arch): New function for emitting .machine and .machinmode directives to the assembler file. (s390_asm_output_function_prefix): Likewise. (s390_asm_declare_function_size): Likewise. (s390_asm_output_function_label): Add mdebug output for feature testing. (s390_option_override): Move implementation into internal function. (s390_option_override_internal): Likewise. Implement option overriding based on current options. (s390_valid_target_attribute_inner_p): New function implementing target attribute logic. (s390_valid_target_attribute_tree): Likewise. (s390_valid_target_attribute_p): Likewise. (s390_reset_previous_fndecl): Likewise. (s390_set_current_function): Likewise. (TARGET_SET_CURRENT_FUNCTION): Provide target hook function. (TARGET_OPTION_VALID_ATTRIBUTE_P): Likewise. (TARGET_OPTION_RESTORE): Likewise. * doc/extend.texi: S390: Document target attribute and pragma. * config.in: Regenerated. * configure: Regenerated. * configure.ac: S390: Check for .machinemode and .machine in gas. S390: Check for architecture modifiers support in gas. gcc/testsuite/ChangeLog * gcc.target/s390/asm-machine-1.c: New test. * gcc.target/s390/asm-machine-2.c: New test. * gcc.target/s390/asm-machine-3.c: New test. * gcc.target/s390/asm-machine-4.c: New test. * gcc.target/s390/target-attribute/tattr-1.c: New test. * gcc.target/s390/target-attribute/tattr-2.c: New test. * gcc.target/s390/target-attribute/tattr-3.c: New test. * gcc.target/s390/target-attribute/tattr-4.c: New test. * gcc.target/s390/target-attribute/tattr-5.c: New test. * gcc.target/s390/target-attribute/tattr-6.c: New test. * gcc.target/s390/target-attribute/tattr-7.c: New test. * gcc.target/s390/target-attribute/tattr-8.c: New test. * gcc.target/s390/target-attribute/tattr-9.c: New test. * gcc.target/s390/target-attribute/tattr-10.c: New test. * gcc.target/s390/target-attribute/tattr-11.c: New test. * gcc.target/s390/target-attribute/tattr-12.c: New test. * gcc.target/s390/target-attribute/tattr-13.c: New test. * gcc.target/s390/target-attribute/tattr-14.c: New test. * gcc.target/s390/target-attribute/tattr-15.c: New test. * gcc.target/s390/target-attribute/tattr-16.c: New test. * gcc.target/s390/target-attribute/tattr-17.c: New test. * gcc.target/s390/target-attribute/tattr-18.c: New test. * gcc.target/s390/target-attribute/tattr-19.c: New test. * gcc.target/s390/target-attribute/tattr-arch-tune-1.c: New test. * gcc.target/s390/target-attribute/tattr-arch-tune-2.c: New test. * gcc.target/s390/target-attribute/tattr-m31-1.c: New test. * gcc.target/s390/target-attribute/tattr-m31-2.c: New test. * gcc.target/s390/target-attribute/tattr-m31-3.c: New test. * gcc.target/s390/target-attribute/tattr-m31-4.c: New test. * gcc.target/s390/target-attribute/tattr-m31-5.c: New test. * gcc.target/s390/target-attribute/tattr-m31-6.c: New test. * gcc.target/s390/target-attribute/tattr-m31-7.c: New test. * gcc.target/s390/target-attribute/tattr-m31-8.c: New test. * gcc.target/s390/target-attribute/tattr-m31-9.c: New test. * gcc.target/s390/target-attribute/tattr-m31-10.c: New test. * gcc.target/s390/target-attribute/tattr-m31-11.c: New test. * gcc.target/s390/target-attribute/tattr-m31-12.c: New test. * gcc.target/s390/target-attribute/tattr-m31-13.c: New test. * gcc.target/s390/target-attribute/tattr-m31-14.c: New test. * gcc.target/s390/target-attribute/tattr-m31-15.c: New test. * gcc.target/s390/target-attribute/tattr-m31-16.c: New test. * gcc.target/s390/target-attribute/tattr-m31-17.c: New test. * gcc.target/s390/target-attribute/tattr-m31-18.c: New test. * gcc.target/s390/target-attribute/tattr-m31-19.c: New test. * gcc.target/s390/target-attribute/tattr-m31-20.c: New test. * gcc.target/s390/target-attribute/tattr-m31-21.c: New test. * gcc.target/s390/target-attribute/tattr-m31-22.c: New test. * gcc.target/s390/target-attribute/tattr-m31-23.c: New test. * gcc.target/s390/target-attribute/tattr-m31-24.c: New test. * gcc.target/s390/target-attribute/tattr-m31-25.c: New test. * gcc.target/s390/target-attribute/tattr-m31-26.c: New test. * gcc.target/s390/target-attribute/tattr-m31-27.c: New test. * gcc.target/s390/target-attribute/tattr-m31-28.c: New test. * gcc.target/s390/target-attribute/tattr-m31-29.c: New test. * gcc.target/s390/target-attribute/tattr-m31-30.c: New test. * gcc.target/s390/target-attribute/tattr-m31-31.c: New test. * gcc.target/s390/target-attribute/tattr-m31-32.c: New test. * gcc.target/s390/target-attribute/tattr-m64-1.c: New test. * gcc.target/s390/target-attribute/tattr-m64-2.c: New test. * gcc.target/s390/target-attribute/tattr-m64-3.c: New test. * gcc.target/s390/target-attribute/tattr-m64-4.c: New test. * gcc.target/s390/target-attribute/tattr-m64-5.c: New test. * gcc.target/s390/target-attribute/tattr-m64-6.c: New test. * gcc.target/s390/target-attribute/tattr-m64-7.c: New test. * gcc.target/s390/target-attribute/tattr-m64-8.c: New test. * gcc.target/s390/target-attribute/tattr-m64-9.c: New test. * gcc.target/s390/target-attribute/tattr-m64-10.c: New test. * gcc.target/s390/target-attribute/tattr-m64-11.c: New test. * gcc.target/s390/target-attribute/tattr-m64-12.c: New test. * gcc.target/s390/target-attribute/tattr-m64-13.c: New test. * gcc.target/s390/target-attribute/tattr-m64-14.c: New test. * gcc.target/s390/target-attribute/tattr-m64-15.c: New test. * gcc.target/s390/target-attribute/tattr-m64-16.c: New test. * gcc.target/s390/target-attribute/tattr-m64-17.c: New test. * gcc.target/s390/target-attribute/tattr-m64-18.c: New test. * gcc.target/s390/target-attribute/tattr-m64-19.c: New test. * gcc.target/s390/target-attribute/tattr-m64-20.c: New test. * gcc.target/s390/target-attribute/tattr-m64-21.c: New test. * gcc.target/s390/target-attribute/tattr-m64-22.c: New test. * gcc.target/s390/target-attribute/tattr-m64-23.c: New test. * gcc.target/s390/target-attribute/tattr-m64-24.c: New test. * gcc.target/s390/target-attribute/tattr-m64-25.c: New test. * gcc.target/s390/target-attribute/tattr-m64-26.c: New test. * gcc.target/s390/target-attribute/tattr-m64-27.c: New test. * gcc.target/s390/target-attribute/tattr-m64-28.c: New test. * gcc.target/s390/target-attribute/tattr-m64-29.c: New test. * gcc.target/s390/target-attribute/tattr-m64-30.c: New test. * gcc.target/s390/target-attribute/tattr-m64-31.c: New test. * gcc.target/s390/target-attribute/tattr-m64-32.c: New test. * gcc.target/s390/target-attribute/tpragma-struct-vx-2.c: New test. * gcc.target/s390/s390.exp (check_effective_target_target_attribute): Add check whether target attribute is available. Run test in target-attribute subdir. * gcc.target/s390/s390-c++.exp (check_effective_target_target_attribute): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231271 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/s390/s390-c.c149
-rw-r--r--gcc/config/s390/s390-opts.h4
-rw-r--r--gcc/config/s390/s390-protos.h19
-rw-r--r--gcc/config/s390/s390.c891
-rw-r--r--gcc/config/s390/s390.h102
-rw-r--r--gcc/config/s390/s390.opt67
-rw-r--r--gcc/config/s390/vecintrin.h88
7 files changed, 1024 insertions, 296 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
}
diff --git a/gcc/config/s390/s390-opts.h b/gcc/config/s390/s390-opts.h
index f0ea532df2c..39b8824040d 100644
--- a/gcc/config/s390/s390-opts.h
+++ b/gcc/config/s390/s390-opts.h
@@ -22,7 +22,9 @@ along with GCC; see the file COPYING3. If not see
/* Which processor to generate code or schedule for. The cpu attribute
defines a list that mirrors this list, so changes to s390.md must be
- made at the same time. */
+ made at the same time. The enumeration must also be kept in snyc with
+ processor_table in s390.c (the enumeration values are used as indices into
+ the table). */
enum processor_type
{
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index a8b885476dd..962abb155c0 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -31,6 +31,12 @@ extern int s390_float_const_zero_p (rtx value);
extern bool s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment);
+/* In s390-common.c. */
+extern bool s390_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED,
+ struct gcc_options *opts_set ATTRIBUTE_UNUSED,
+ const struct cl_decoded_option *decoded,
+ location_t loc);
+
/* Declare functions in s390.c. */
extern HOST_WIDE_INT s390_initial_elimination_offset (int, int);
@@ -46,6 +52,19 @@ extern int s390_class_max_nregs (enum reg_class, machine_mode);
extern int s390_cannot_change_mode_class (machine_mode, machine_mode,
enum reg_class);
extern bool s390_function_arg_vector (machine_mode, const_tree);
+#if S390_USE_TARGET_ATTRIBUTE
+extern tree s390_valid_target_attribute_tree (tree args,
+ struct gcc_options *opts,
+ const struct gcc_options
+ *opts_set, bool is_pragma);
+extern void s390_activate_target_options (tree new_tree);
+extern void
+s390_asm_output_function_prefix (FILE *asm_out_file,
+ const char *fnname ATTRIBUTE_UNUSED);
+extern void
+s390_asm_declare_function_size (FILE *asm_out_file,
+ const char *fnname ATTRIBUTE_UNUSED, tree decl);
+#endif
#ifdef RTX_CODE
extern int s390_extra_constraint_str (rtx, int, const char *);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 7e7ed45230a..e0851e5cae8 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "backend.h"
#include "target.h"
+#include "target-globals.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
@@ -40,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "recog.h"
#include "cgraph.h"
#include "diagnostic-core.h"
+#include "diagnostic.h"
#include "alias.h"
#include "fold-const.h"
#include "print-tree.h"
@@ -79,6 +81,9 @@ along with GCC; see the file COPYING3. If not see
/* This file should be included last. */
#include "target-def.h"
+/* Remember the last target of s390_set_current_function. */
+static GTY(()) tree s390_previous_fndecl;
+
/* Define the specific costs for a given cpu. */
struct processor_costs
@@ -116,7 +121,7 @@ struct processor_costs
const int dsgr;
};
-const struct processor_costs *s390_cost;
+#define s390_cost ((const struct processor_costs *)(s390_cost_pointer))
static const
struct processor_costs z900_cost =
@@ -310,6 +315,27 @@ struct processor_costs zEC12_cost =
COSTS_N_INSNS (160), /* DSGR cracked */
};
+static struct
+{
+ const char *const name;
+ const enum processor_type processor;
+ const struct processor_costs *cost;
+}
+const processor_table[] =
+{
+ { "g5", PROCESSOR_9672_G5, &z900_cost },
+ { "g6", PROCESSOR_9672_G6, &z900_cost },
+ { "z900", PROCESSOR_2064_Z900, &z900_cost },
+ { "z990", PROCESSOR_2084_Z990, &z990_cost },
+ { "z9-109", PROCESSOR_2094_Z9_109, &z9_109_cost },
+ { "z9-ec", PROCESSOR_2094_Z9_EC, &z9_109_cost },
+ { "z10", PROCESSOR_2097_Z10, &z10_cost },
+ { "z196", PROCESSOR_2817_Z196, &z196_cost },
+ { "zEC12", PROCESSOR_2827_ZEC12, &zEC12_cost },
+ { "z13", PROCESSOR_2964_Z13, &zEC12_cost },
+ { "native", PROCESSOR_NATIVE, NULL }
+};
+
extern int reload_completed;
/* Kept up to date using the SCHED_VARIABLE_ISSUE hook. */
@@ -613,10 +639,6 @@ s390_init_builtins (void)
NULL, NULL);
tree noreturn_attr = tree_cons (get_identifier ("noreturn"), NULL, NULL);
tree c_uint64_type_node;
- unsigned int bflags_mask = (BFLAGS_MASK_INIT);
-
- bflags_mask |= (TARGET_VX) ? B_VX : 0;
- bflags_mask |= (TARGET_HTM) ? B_HTM : 0;
/* The uint64_type_node from tree.c is not compatible to the C99
uint64_t data type. What we want is c_uint64_type_node from
@@ -629,46 +651,46 @@ s390_init_builtins (void)
#undef DEF_TYPE
#define DEF_TYPE(INDEX, BFLAGS, NODE, CONST_P) \
- if ((BFLAGS) == 0 || ((BFLAGS) & bflags_mask)) \
+ if (s390_builtin_types[INDEX] == NULL) \
s390_builtin_types[INDEX] = (!CONST_P) ? \
(NODE) : build_type_variant ((NODE), 1, 0);
#undef DEF_POINTER_TYPE
#define DEF_POINTER_TYPE(INDEX, BFLAGS, INDEX_BASE) \
- if ((BFLAGS) == 0 || ((BFLAGS) & bflags_mask)) \
+ if (s390_builtin_types[INDEX] == NULL) \
s390_builtin_types[INDEX] = \
build_pointer_type (s390_builtin_types[INDEX_BASE]);
#undef DEF_DISTINCT_TYPE
#define DEF_DISTINCT_TYPE(INDEX, BFLAGS, INDEX_BASE) \
- if ((BFLAGS) == 0 || ((BFLAGS) & bflags_mask)) \
+ if (s390_builtin_types[INDEX] == NULL) \
s390_builtin_types[INDEX] = \
build_distinct_type_copy (s390_builtin_types[INDEX_BASE]);
#undef DEF_VECTOR_TYPE
#define DEF_VECTOR_TYPE(INDEX, BFLAGS, INDEX_BASE, ELEMENTS) \
- if ((BFLAGS) == 0 || ((BFLAGS) & bflags_mask)) \
+ if (s390_builtin_types[INDEX] == NULL) \
s390_builtin_types[INDEX] = \
build_vector_type (s390_builtin_types[INDEX_BASE], ELEMENTS);
#undef DEF_OPAQUE_VECTOR_TYPE
#define DEF_OPAQUE_VECTOR_TYPE(INDEX, BFLAGS, INDEX_BASE, ELEMENTS) \
- if ((BFLAGS) == 0 || ((BFLAGS) & bflags_mask)) \
+ if (s390_builtin_types[INDEX] == NULL) \
s390_builtin_types[INDEX] = \
build_opaque_vector_type (s390_builtin_types[INDEX_BASE], ELEMENTS);
#undef DEF_FN_TYPE
#define DEF_FN_TYPE(INDEX, BFLAGS, args...) \
- if ((BFLAGS) == 0 || ((BFLAGS) & bflags_mask)) \
+ if (s390_builtin_fn_types[INDEX] == NULL) \
s390_builtin_fn_types[INDEX] = \
- build_function_type_list (args, NULL_TREE);
+ build_function_type_list (args, NULL_TREE);
#undef DEF_OV_TYPE
#define DEF_OV_TYPE(...)
#include "s390-builtin-types.def"
#undef B_DEF
#define B_DEF(NAME, PATTERN, ATTRS, BFLAGS, OPFLAGS, FNTYPE) \
- if (((BFLAGS) & ~bflags_mask) == 0) \
+ if (s390_builtin_decls[S390_BUILTIN_##NAME] == NULL) \
s390_builtin_decls[S390_BUILTIN_##NAME] = \
add_builtin_function ("__builtin_" #NAME, \
s390_builtin_fn_types[FNTYPE], \
@@ -678,7 +700,8 @@ s390_init_builtins (void)
ATTRS);
#undef OB_DEF
#define OB_DEF(NAME, FIRST_VAR_NAME, LAST_VAR_NAME, BFLAGS, FNTYPE) \
- if (((BFLAGS) & ~bflags_mask) == 0) \
+ if (s390_builtin_decls[S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX] \
+ == NULL) \
s390_builtin_decls[S390_OVERLOADED_BUILTIN_##NAME + S390_BUILTIN_MAX] = \
add_builtin_function ("__builtin_" #NAME, \
s390_builtin_fn_types[FNTYPE], \
@@ -762,10 +785,29 @@ s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
if (TARGET_DEBUG_ARG)
{
fprintf (stderr,
- "s390_expand_builtin, code = %4d, %s\n",
- (int)fcode, IDENTIFIER_POINTER (DECL_NAME (fndecl)));
+ "s390_expand_builtin, code = %4d, %s, bflags = 0x%x\n",
+ (int)fcode, IDENTIFIER_POINTER (DECL_NAME (fndecl)),
+ bflags_for_builtin (fcode));
}
+ if (S390_USE_TARGET_ATTRIBUTE)
+ {
+ unsigned int bflags;
+
+ bflags = bflags_for_builtin (fcode);
+ if ((bflags & B_HTM) && !TARGET_HTM)
+ {
+ error ("Builtin %qF is not supported without -mhtm "
+ "(default with -march=zEC12 and higher).", fndecl);
+ return const0_rtx;
+ }
+ if ((bflags & B_VX) && !TARGET_VX)
+ {
+ error ("Builtin %qF is not supported without -mvx "
+ "(default with -march=z13 and higher).", fndecl);
+ return const0_rtx;
+ }
+ }
if (fcode >= S390_OVERLOADED_BUILTIN_VAR_OFFSET
&& fcode < S390_ALL_BUILTIN_MAX)
{
@@ -907,14 +949,6 @@ s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
arity++;
}
- if (last_vec_mode != VOIDmode && !TARGET_VX)
- {
- error ("Vector type builtin %qF is not supported without -mvx "
- "(default with -march=z13).",
- fndecl);
- return const0_rtx;
- }
-
switch (arity)
{
case 0:
@@ -6701,6 +6735,63 @@ s390_function_num_hotpatch_hw (tree decl,
}
}
+/* Write the current .machine and .machinemode specification to the assembler
+ file. */
+
+#if S390_USE_TARGET_ATTRIBUTE
+static void
+s390_asm_output_machine_for_arch (FILE *asm_out_file)
+{
+ fprintf (asm_out_file, "\t.machinemode %s\n",
+ (TARGET_ZARCH) ? "zarch" : "esa");
+ fprintf (asm_out_file, "\t.machine \"%s", processor_table[s390_arch].name);
+ if (S390_USE_ARCHITECTURE_MODIFIERS)
+ {
+ int cpu_flags;
+
+ cpu_flags = processor_flags_table[(int) s390_arch];
+ if (TARGET_HTM && !(cpu_flags & PF_TX))
+ fprintf (asm_out_file, "+htm");
+ else if (!TARGET_HTM && (cpu_flags & PF_TX))
+ fprintf (asm_out_file, "+nohtm");
+ if (TARGET_VX && !(cpu_flags & PF_VX))
+ fprintf (asm_out_file, "+vx");
+ else if (!TARGET_VX && (cpu_flags & PF_VX))
+ fprintf (asm_out_file, "+novx");
+ }
+ fprintf (asm_out_file, "\"\n");
+}
+
+/* Write an extra function header before the very start of the function. */
+
+void
+s390_asm_output_function_prefix (FILE *asm_out_file,
+ const char *fnname ATTRIBUTE_UNUSED)
+{
+ if (DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl) == NULL)
+ return;
+ /* Since only the function specific options are saved but not the indications
+ which options are set, it's too much work here to figure out which options
+ have actually changed. Thus, generate .machine and .machinemode whenever a
+ function has the target attribute or pragma. */
+ fprintf (asm_out_file, "\t.machinemode push\n");
+ fprintf (asm_out_file, "\t.machine push\n");
+ s390_asm_output_machine_for_arch (asm_out_file);
+}
+
+/* Write an extra function footer after the very end of the function. */
+
+void
+s390_asm_declare_function_size (FILE *asm_out_file,
+ const char *fnname ATTRIBUTE_UNUSED, tree decl)
+{
+ if (DECL_FUNCTION_SPECIFIC_TARGET (decl) == NULL)
+ return;
+ fprintf (asm_out_file, "\t.machine pop\n");
+ fprintf (asm_out_file, "\t.machinemode pop\n");
+}
+#endif
+
/* Write the extra assembler code needed to declare a function properly. */
void
@@ -6742,6 +6833,28 @@ s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (function_alignment));
}
+ if (S390_USE_TARGET_ATTRIBUTE && TARGET_DEBUG_ARG)
+ {
+ asm_fprintf (asm_out_file, "\t# fn:%s ar%d\n", fname, s390_arch);
+ asm_fprintf (asm_out_file, "\t# fn:%s tu%d\n", fname, s390_tune);
+ asm_fprintf (asm_out_file, "\t# fn:%s sg%d\n", fname, s390_stack_guard);
+ asm_fprintf (asm_out_file, "\t# fn:%s ss%d\n", fname, s390_stack_size);
+ asm_fprintf (asm_out_file, "\t# fn:%s bc%d\n", fname, s390_branch_cost);
+ asm_fprintf (asm_out_file, "\t# fn:%s wf%d\n", fname,
+ s390_warn_framesize);
+ asm_fprintf (asm_out_file, "\t# fn:%s ba%d\n", fname, TARGET_BACKCHAIN);
+ asm_fprintf (asm_out_file, "\t# fn:%s hd%d\n", fname, TARGET_HARD_DFP);
+ asm_fprintf (asm_out_file, "\t# fn:%s hf%d\n", fname, !TARGET_SOFT_FLOAT);
+ asm_fprintf (asm_out_file, "\t# fn:%s ht%d\n", fname, TARGET_OPT_HTM);
+ asm_fprintf (asm_out_file, "\t# fn:%s vx%d\n", fname, TARGET_OPT_VX);
+ asm_fprintf (asm_out_file, "\t# fn:%s ps%d\n", fname,
+ TARGET_PACKED_STACK);
+ asm_fprintf (asm_out_file, "\t# fn:%s se%d\n", fname, TARGET_SMALL_EXEC);
+ asm_fprintf (asm_out_file, "\t# fn:%s mv%d\n", fname, TARGET_MVCLE);
+ asm_fprintf (asm_out_file, "\t# fn:%s zv%d\n", fname, TARGET_ZVECTOR);
+ asm_fprintf (asm_out_file, "\t# fn:%s wd%d\n", fname,
+ s390_warn_dynamicstack_p);
+ }
ASM_OUTPUT_LABEL (asm_out_file, fname);
if (hw_after > 0)
asm_fprintf (asm_out_file,
@@ -13434,230 +13547,254 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
}
}
+/* Restore the current options. This is a hook function and also called
+ internally. */
+
static void
-s390_option_override (void)
+s390_function_specific_restore (struct gcc_options *opts,
+ struct cl_target_option *ptr ATTRIBUTE_UNUSED)
{
- unsigned int i;
- cl_deferred_option *opt;
- vec<cl_deferred_option> *v =
- (vec<cl_deferred_option> *) s390_deferred_options;
-
- if (v)
- FOR_EACH_VEC_ELT (*v, i, opt)
- {
- switch (opt->opt_index)
- {
- case OPT_mhotpatch_:
- {
- int val1;
- int val2;
- char s[256];
- char *t;
-
- strncpy (s, opt->arg, 256);
- s[255] = 0;
- t = strchr (s, ',');
- if (t != NULL)
- {
- *t = 0;
- t++;
- val1 = integral_argument (s);
- val2 = integral_argument (t);
- }
- else
- {
- val1 = -1;
- val2 = -1;
- }
- if (val1 == -1 || val2 == -1)
- {
- /* argument is not a plain number */
- error ("arguments to %qs should be non-negative integers",
- "-mhotpatch=n,m");
- break;
- }
- else if (val1 > s390_hotpatch_hw_max
- || val2 > s390_hotpatch_hw_max)
- {
- error ("argument to %qs is too large (max. %d)",
- "-mhotpatch=n,m", s390_hotpatch_hw_max);
- break;
- }
- s390_hotpatch_hw_before_label = val1;
- s390_hotpatch_hw_after_label = val2;
- break;
- }
- default:
- gcc_unreachable ();
- }
- }
-
- /* Set up function hooks. */
- init_machine_status = s390_init_machine_status;
+ opts->x_s390_cost_pointer = (long)processor_table[opts->x_s390_tune].cost;
+}
+static void
+s390_option_override_internal (struct gcc_options *opts,
+ const struct gcc_options *opts_set)
+{
/* Architecture mode defaults according to ABI. */
- if (!(target_flags_explicit & MASK_ZARCH))
+ if (!(opts_set->x_target_flags & MASK_ZARCH))
{
if (TARGET_64BIT)
- target_flags |= MASK_ZARCH;
+ opts->x_target_flags |= MASK_ZARCH;
else
- target_flags &= ~MASK_ZARCH;
+ opts->x_target_flags &= ~MASK_ZARCH;
}
- /* Set the march default in case it hasn't been specified on
- cmdline. */
- if (s390_arch == PROCESSOR_max)
- {
- s390_arch_string = TARGET_ZARCH? "z900" : "g5";
- s390_arch = TARGET_ZARCH ? PROCESSOR_2064_Z900 : PROCESSOR_9672_G5;
- s390_arch_flags = processor_flags_table[(int)s390_arch];
- }
+ /* Set the march default in case it hasn't been specified on cmdline. */
+ if (!opts_set->x_s390_arch)
+ opts->x_s390_arch = TARGET_ZARCH_P (opts->x_target_flags)
+ ? PROCESSOR_2064_Z900 : PROCESSOR_9672_G5;
+ opts->x_s390_arch_flags = processor_flags_table[(int) opts->x_s390_arch];
/* Determine processor to tune for. */
- if (s390_tune == PROCESSOR_max)
- {
- s390_tune = s390_arch;
- s390_tune_flags = s390_arch_flags;
- }
+ if (!opts_set->x_s390_tune)
+ opts->x_s390_tune = opts->x_s390_arch;
+ opts->x_s390_tune_flags = processor_flags_table[opts->x_s390_tune];
/* Sanity checks. */
- if (s390_arch == PROCESSOR_NATIVE || s390_tune == PROCESSOR_NATIVE)
+ if (opts->x_s390_arch == PROCESSOR_NATIVE
+ || opts->x_s390_tune == PROCESSOR_NATIVE)
gcc_unreachable ();
- if (TARGET_ZARCH && !TARGET_CPU_ZARCH)
- error ("z/Architecture mode not supported on %s", s390_arch_string);
- if (TARGET_64BIT && !TARGET_ZARCH)
+ if (TARGET_ZARCH_P (opts->x_target_flags) && !TARGET_CPU_ZARCH_P (opts))
+ error ("z/Architecture mode not supported on %s",
+ processor_table[(int)opts->x_s390_arch].name);
+ if (TARGET_64BIT && !TARGET_ZARCH_P (opts->x_target_flags))
error ("64-bit ABI not supported in ESA/390 mode");
- /* Use hardware DFP if available and not explicitly disabled by
- user. E.g. with -m31 -march=z10 -mzarch */
- if (!(target_flags_explicit & MASK_HARD_DFP) && TARGET_DFP)
- target_flags |= MASK_HARD_DFP;
-
/* Enable hardware transactions if available and not explicitly
disabled by user. E.g. with -m31 -march=zEC12 -mzarch */
- if (!(target_flags_explicit & MASK_OPT_HTM) && TARGET_CPU_HTM && TARGET_ZARCH)
- target_flags |= MASK_OPT_HTM;
+ if (!TARGET_OPT_HTM_P (opts_set->x_target_flags))
+ {
+ if (TARGET_CPU_HTM_P (opts) && TARGET_ZARCH_P (opts->x_target_flags))
+ opts->x_target_flags |= MASK_OPT_HTM;
+ else
+ opts->x_target_flags &= ~MASK_OPT_HTM;
+ }
- if (target_flags_explicit & MASK_OPT_VX)
+ if (TARGET_OPT_VX_P (opts_set->x_target_flags))
{
- if (TARGET_OPT_VX)
+ if (TARGET_OPT_VX_P (opts->x_target_flags))
{
- if (!TARGET_CPU_VX)
+ if (!TARGET_CPU_VX_P (opts))
error ("hardware vector support not available on %s",
- s390_arch_string);
- if (TARGET_SOFT_FLOAT)
+ processor_table[(int)opts->x_s390_arch].name);
+ if (TARGET_SOFT_FLOAT_P (opts->x_target_flags))
error ("hardware vector support not available with -msoft-float");
}
}
- else if (TARGET_CPU_VX)
- /* Enable vector support if available and not explicitly disabled
- by user. E.g. with -m31 -march=z13 -mzarch */
- target_flags |= MASK_OPT_VX;
+ else
+ {
+ if (TARGET_CPU_VX_P (opts))
+ /* Enable vector support if available and not explicitly disabled
+ by user. E.g. with -m31 -march=z13 -mzarch */
+ opts->x_target_flags |= MASK_OPT_VX;
+ else
+ opts->x_target_flags &= ~MASK_OPT_VX;
+ }
- if (TARGET_HARD_DFP && !TARGET_DFP)
+ /* Use hardware DFP if available and not explicitly disabled by
+ user. E.g. with -m31 -march=z10 -mzarch */
+ if (!TARGET_HARD_DFP_P (opts_set->x_target_flags))
+ {
+ if (TARGET_DFP_P (opts))
+ opts->x_target_flags |= MASK_HARD_DFP;
+ else
+ opts->x_target_flags &= ~MASK_HARD_DFP;
+ }
+
+ if (TARGET_HARD_DFP_P (opts->x_target_flags) && !TARGET_DFP_P (opts))
{
- if (target_flags_explicit & MASK_HARD_DFP)
+ if (TARGET_HARD_DFP_P (opts_set->x_target_flags))
{
- if (!TARGET_CPU_DFP)
+ if (!TARGET_CPU_DFP_P (opts))
error ("hardware decimal floating point instructions"
- " not available on %s", s390_arch_string);
- if (!TARGET_ZARCH)
+ " not available on %s",
+ processor_table[(int)opts->x_s390_arch].name);
+ if (!TARGET_ZARCH_P (opts->x_target_flags))
error ("hardware decimal floating point instructions"
" not available in ESA/390 mode");
}
else
- target_flags &= ~MASK_HARD_DFP;
+ opts->x_target_flags &= ~MASK_HARD_DFP;
}
- if ((target_flags_explicit & MASK_SOFT_FLOAT) && TARGET_SOFT_FLOAT)
+ if (TARGET_SOFT_FLOAT_P (opts_set->x_target_flags)
+ && TARGET_SOFT_FLOAT_P (opts->x_target_flags))
{
- if ((target_flags_explicit & MASK_HARD_DFP) && TARGET_HARD_DFP)
+ if (TARGET_HARD_DFP_P (opts_set->x_target_flags)
+ && TARGET_HARD_DFP_P (opts->x_target_flags))
error ("-mhard-dfp can%'t be used in conjunction with -msoft-float");
- target_flags &= ~MASK_HARD_DFP;
- }
-
- /* Set processor cost function. */
- switch (s390_tune)
- {
- case PROCESSOR_2084_Z990:
- s390_cost = &z990_cost;
- break;
- case PROCESSOR_2094_Z9_109:
- case PROCESSOR_2094_Z9_EC:
- s390_cost = &z9_109_cost;
- break;
- case PROCESSOR_2097_Z10:
- s390_cost = &z10_cost;
- break;
- case PROCESSOR_2817_Z196:
- s390_cost = &z196_cost;
- break;
- case PROCESSOR_2827_ZEC12:
- case PROCESSOR_2964_Z13:
- s390_cost = &zEC12_cost;
- break;
- default:
- s390_cost = &z900_cost;
+ opts->x_target_flags &= ~MASK_HARD_DFP;
}
- if (TARGET_BACKCHAIN && TARGET_PACKED_STACK && TARGET_HARD_FLOAT)
+ if (TARGET_BACKCHAIN_P (opts->x_target_flags)
+ && TARGET_PACKED_STACK_P (opts->x_target_flags)
+ && TARGET_HARD_FLOAT_P (opts->x_target_flags))
error ("-mbackchain -mpacked-stack -mhard-float are not supported "
"in combination");
- if (s390_stack_size)
+ if (opts->x_s390_stack_size)
{
- if (s390_stack_guard >= s390_stack_size)
+ if (opts->x_s390_stack_guard >= opts->x_s390_stack_size)
error ("stack size must be greater than the stack guard value");
- else if (s390_stack_size > 1 << 16)
+ else if (opts->x_s390_stack_size > 1 << 16)
error ("stack size must not be greater than 64k");
}
- else if (s390_stack_guard)
+ else if (opts->x_s390_stack_guard)
error ("-mstack-guard implies use of -mstack-size");
#ifdef TARGET_DEFAULT_LONG_DOUBLE_128
- if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
- target_flags |= MASK_LONG_DOUBLE_128;
+ if (!TARGET_LONG_DOUBLE_128_P (opts_set->x_target_flags))
+ opts->x_target_flags |= MASK_LONG_DOUBLE_128;
#endif
- if (s390_tune >= PROCESSOR_2097_Z10)
+ if (opts->x_s390_tune >= PROCESSOR_2097_Z10)
{
maybe_set_param_value (PARAM_MAX_UNROLLED_INSNS, 100,
- global_options.x_param_values,
- global_options_set.x_param_values);
+ opts->x_param_values,
+ opts_set->x_param_values);
maybe_set_param_value (PARAM_MAX_UNROLL_TIMES, 32,
- global_options.x_param_values,
- global_options_set.x_param_values);
+ opts->x_param_values,
+ opts_set->x_param_values);
maybe_set_param_value (PARAM_MAX_COMPLETELY_PEELED_INSNS, 2000,
- global_options.x_param_values,
- global_options_set.x_param_values);
+ opts->x_param_values,
+ opts_set->x_param_values);
maybe_set_param_value (PARAM_MAX_COMPLETELY_PEEL_TIMES, 64,
- global_options.x_param_values,
- global_options_set.x_param_values);
+ opts->x_param_values,
+ opts_set->x_param_values);
}
maybe_set_param_value (PARAM_MAX_PENDING_LIST_LENGTH, 256,
- global_options.x_param_values,
- global_options_set.x_param_values);
+ opts->x_param_values,
+ opts_set->x_param_values);
/* values for loop prefetching */
maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE, 256,
- global_options.x_param_values,
- global_options_set.x_param_values);
+ opts->x_param_values,
+ opts_set->x_param_values);
maybe_set_param_value (PARAM_L1_CACHE_SIZE, 128,
- global_options.x_param_values,
- global_options_set.x_param_values);
+ opts->x_param_values,
+ opts_set->x_param_values);
/* s390 has more than 2 levels and the size is much larger. Since
we are always running virtualized assume that we only get a small
part of the caches above l1. */
maybe_set_param_value (PARAM_L2_CACHE_SIZE, 1500,
- global_options.x_param_values,
- global_options_set.x_param_values);
+ opts->x_param_values,
+ opts_set->x_param_values);
maybe_set_param_value (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO, 2,
- global_options.x_param_values,
- global_options_set.x_param_values);
+ opts->x_param_values,
+ opts_set->x_param_values);
maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES, 6,
- global_options.x_param_values,
- global_options_set.x_param_values);
+ opts->x_param_values,
+ opts_set->x_param_values);
+
+ /* Use the alternative scheduling-pressure algorithm by default. */
+ maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, 2,
+ opts->x_param_values,
+ opts_set->x_param_values);
+
+ /* Call target specific restore function to do post-init work. At the moment,
+ this just sets opts->x_s390_cost_pointer. */
+ s390_function_specific_restore (opts, NULL);
+}
+
+static void
+s390_option_override (void)
+{
+ unsigned int i;
+ cl_deferred_option *opt;
+ vec<cl_deferred_option> *v =
+ (vec<cl_deferred_option> *) s390_deferred_options;
+
+ if (v)
+ FOR_EACH_VEC_ELT (*v, i, opt)
+ {
+ switch (opt->opt_index)
+ {
+ case OPT_mhotpatch_:
+ {
+ int val1;
+ int val2;
+ char s[256];
+ char *t;
+
+ strncpy (s, opt->arg, 256);
+ s[255] = 0;
+ t = strchr (s, ',');
+ if (t != NULL)
+ {
+ *t = 0;
+ t++;
+ val1 = integral_argument (s);
+ val2 = integral_argument (t);
+ }
+ else
+ {
+ val1 = -1;
+ val2 = -1;
+ }
+ if (val1 == -1 || val2 == -1)
+ {
+ /* argument is not a plain number */
+ error ("arguments to %qs should be non-negative integers",
+ "-mhotpatch=n,m");
+ break;
+ }
+ else if (val1 > s390_hotpatch_hw_max
+ || val2 > s390_hotpatch_hw_max)
+ {
+ error ("argument to %qs is too large (max. %d)",
+ "-mhotpatch=n,m", s390_hotpatch_hw_max);
+ break;
+ }
+ s390_hotpatch_hw_before_label = val1;
+ s390_hotpatch_hw_after_label = val2;
+ break;
+ }
+ default:
+ gcc_unreachable ();
+ }
+ }
+
+ /* Set up function hooks. */
+ init_machine_status = s390_init_machine_status;
+
+ s390_option_override_internal (&global_options, &global_options_set);
+
+ /* Save the initial options in case the user does function specific
+ options. */
+ target_option_default_node = build_target_option_node (&global_options);
+ target_option_current_node = target_option_default_node;
/* This cannot reside in s390_option_optimization_table since HAVE_prefetch
requires the arch flags to be evaluated already. Since prefetching
@@ -13665,11 +13802,6 @@ s390_option_override (void)
if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch && optimize >= 3)
flag_prefetch_loop_arrays = 1;
- /* Use the alternative scheduling-pressure algorithm by default. */
- maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, 2,
- global_options.x_param_values,
- global_options_set.x_param_values);
-
if (TARGET_TPF)
{
/* Don't emit DWARF3/4 unless specifically selected. The TPF
@@ -13696,6 +13828,386 @@ s390_option_override (void)
register_pass (&insert_pass_s390_early_mach);
}
+#if S390_USE_TARGET_ATTRIBUTE
+/* Inner function to process the attribute((target(...))), take an argument and
+ set the current options from the argument. If we have a list, recursively go
+ over the list. */
+
+static bool
+s390_valid_target_attribute_inner_p (tree args,
+ struct gcc_options *opts,
+ struct gcc_options *new_opts_set,
+ bool force_pragma)
+{
+ char *next_optstr;
+ bool ret = true;
+
+#define S390_ATTRIB(S,O,A) { S, sizeof (S)-1, O, A, 0 }
+#define S390_PRAGMA(S,O,A) { S, sizeof (S)-1, O, A, 1 }
+ static const struct
+ {
+ const char *string;
+ size_t len;
+ int opt;
+ int has_arg;
+ int only_as_pragma;
+ } attrs[] = {
+ /* enum options */
+ S390_ATTRIB ("arch=", OPT_march_, 1),
+ S390_ATTRIB ("tune=", OPT_mtune_, 1),
+ /* uinteger options */
+ S390_ATTRIB ("stack-guard=", OPT_mstack_guard_, 1),
+ S390_ATTRIB ("stack-size=", OPT_mstack_size_, 1),
+ S390_ATTRIB ("branch-cost=", OPT_mbranch_cost_, 1),
+ S390_ATTRIB ("warn-framesize=", OPT_mwarn_framesize_, 1),
+ /* flag options */
+ S390_ATTRIB ("backchain", OPT_mbackchain, 0),
+ S390_ATTRIB ("hard-dfp", OPT_mhard_dfp, 0),
+ S390_ATTRIB ("hard-float", OPT_mhard_float, 0),
+ S390_ATTRIB ("htm", OPT_mhtm, 0),
+ S390_ATTRIB ("vx", OPT_mvx, 0),
+ S390_ATTRIB ("packed-stack", OPT_mpacked_stack, 0),
+ S390_ATTRIB ("small-exec", OPT_msmall_exec, 0),
+ S390_ATTRIB ("soft-float", OPT_msoft_float, 0),
+ S390_ATTRIB ("mvcle", OPT_mmvcle, 0),
+ S390_PRAGMA ("zvector", OPT_mzvector, 0),
+ /* boolean options */
+ S390_ATTRIB ("warn-dynamicstack", OPT_mwarn_dynamicstack, 0),
+ };
+#undef S390_ATTRIB
+#undef S390_PRAGMA
+
+ /* If this is a list, recurse to get the options. */
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ bool ret = true;
+ int num_pragma_values;
+ int i;
+
+ /* Note: attribs.c:decl_attributes prepends the values from
+ current_target_pragma to the list of target attributes. To determine
+ whether we're looking at a value of the attribute or the pragma we
+ assume that the first [list_length (current_target_pragma)] values in
+ the list are the values from the pragma. */
+ num_pragma_values = (!force_pragma && current_target_pragma != NULL)
+ ? list_length (current_target_pragma) : 0;
+ for (i = 0; args; args = TREE_CHAIN (args), i++)
+ {
+ bool is_pragma;
+
+ is_pragma = (force_pragma || i < num_pragma_values);
+ if (TREE_VALUE (args)
+ && !s390_valid_target_attribute_inner_p (TREE_VALUE (args),
+ opts, new_opts_set,
+ is_pragma))
+ {
+ ret = false;
+ }
+ }
+ return ret;
+ }
+
+ else if (TREE_CODE (args) != STRING_CST)
+ {
+ error ("attribute %<target%> argument not a string");
+ return false;
+ }
+
+ /* Handle multiple arguments separated by commas. */
+ next_optstr = ASTRDUP (TREE_STRING_POINTER (args));
+
+ while (next_optstr && *next_optstr != '\0')
+ {
+ char *p = next_optstr;
+ char *orig_p = p;
+ char *comma = strchr (next_optstr, ',');
+ size_t len, opt_len;
+ int opt;
+ bool opt_set_p;
+ char ch;
+ unsigned i;
+ int mask = 0;
+ enum cl_var_type var_type;
+ bool found;
+
+ if (comma)
+ {
+ *comma = '\0';
+ len = comma - next_optstr;
+ next_optstr = comma + 1;
+ }
+ else
+ {
+ len = strlen (p);
+ next_optstr = NULL;
+ }
+
+ /* Recognize no-xxx. */
+ if (len > 3 && p[0] == 'n' && p[1] == 'o' && p[2] == '-')
+ {
+ opt_set_p = false;
+ p += 3;
+ len -= 3;
+ }
+ else
+ opt_set_p = true;
+
+ /* Find the option. */
+ ch = *p;
+ found = false;
+ for (i = 0; i < ARRAY_SIZE (attrs); i++)
+ {
+ opt_len = attrs[i].len;
+ if (ch == attrs[i].string[0]
+ && ((attrs[i].has_arg) ? len > opt_len : len == opt_len)
+ && memcmp (p, attrs[i].string, opt_len) == 0)
+ {
+ opt = attrs[i].opt;
+ if (!opt_set_p && cl_options[opt].cl_reject_negative)
+ continue;
+ mask = cl_options[opt].var_value;
+ var_type = cl_options[opt].var_type;
+ found = true;
+ break;
+ }
+ }
+
+ /* Process the option. */
+ if (!found)
+ {
+ error ("attribute(target(\"%s\")) is unknown", orig_p);
+ return false;
+ }
+ else if (attrs[i].only_as_pragma && !force_pragma)
+ {
+ /* Value is not allowed for the target attribute. */
+ error ("Value %qs is not supported by attribute %<target%>",
+ attrs[i].string);
+ return false;
+ }
+
+ else if (var_type == CLVC_BIT_SET || var_type == CLVC_BIT_CLEAR)
+ {
+ if (var_type == CLVC_BIT_CLEAR)
+ opt_set_p = !opt_set_p;
+
+ if (opt_set_p)
+ opts->x_target_flags |= mask;
+ else
+ opts->x_target_flags &= ~mask;
+ new_opts_set->x_target_flags |= mask;
+ }
+
+ else if (cl_options[opt].var_type == CLVC_BOOLEAN)
+ {
+ int value;
+
+ if (cl_options[opt].cl_uinteger)
+ {
+ /* Unsigned integer argument. Code based on the function
+ decode_cmdline_option () in opts-common.c. */
+ value = integral_argument (p + opt_len);
+ }
+ else
+ value = (opt_set_p) ? 1 : 0;
+
+ if (value != -1)
+ {
+ struct cl_decoded_option decoded;
+
+ /* Value range check; only implemented for numeric and boolean
+ options at the moment. */
+ generate_option (opt, NULL, value, CL_TARGET, &decoded);
+ s390_handle_option (opts, new_opts_set, &decoded, input_location);
+ set_option (opts, new_opts_set, opt, value,
+ p + opt_len, DK_UNSPECIFIED, input_location,
+ global_dc);
+ }
+ else
+ {
+ error ("attribute(target(\"%s\")) is unknown", orig_p);
+ ret = false;
+ }
+ }
+
+ else if (cl_options[opt].var_type == CLVC_ENUM)
+ {
+ bool arg_ok;
+ int value;
+
+ arg_ok = opt_enum_arg_to_value (opt, p + opt_len, &value, CL_TARGET);
+ if (arg_ok)
+ set_option (opts, new_opts_set, opt, value,
+ p + opt_len, DK_UNSPECIFIED, input_location,
+ global_dc);
+ else
+ {
+ error ("attribute(target(\"%s\")) is unknown", orig_p);
+ ret = false;
+ }
+ }
+
+ else
+ gcc_unreachable ();
+ }
+ return ret;
+}
+
+/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
+
+tree
+s390_valid_target_attribute_tree (tree args,
+ struct gcc_options *opts,
+ const struct gcc_options *opts_set,
+ bool force_pragma)
+{
+ tree t = NULL_TREE;
+ struct gcc_options new_opts_set;
+
+ memset (&new_opts_set, 0, sizeof (new_opts_set));
+
+ /* Process each of the options on the chain. */
+ if (! s390_valid_target_attribute_inner_p (args, opts, &new_opts_set,
+ force_pragma))
+ return error_mark_node;
+
+ /* If some option was set (even if it has not changed), rerun
+ s390_option_override_internal, and then save the options away. */
+ if (new_opts_set.x_target_flags
+ || new_opts_set.x_s390_arch
+ || new_opts_set.x_s390_tune
+ || new_opts_set.x_s390_stack_guard
+ || new_opts_set.x_s390_stack_size
+ || new_opts_set.x_s390_branch_cost
+ || new_opts_set.x_s390_warn_framesize
+ || new_opts_set.x_s390_warn_dynamicstack_p)
+ {
+ const unsigned char *src = (const unsigned char *)opts_set;
+ unsigned char *dest = (unsigned char *)&new_opts_set;
+ unsigned int i;
+
+ /* Merge the original option flags into the new ones. */
+ for (i = 0; i < sizeof(*opts_set); i++)
+ dest[i] |= src[i];
+
+ /* Do any overrides, such as arch=xxx, or tune=xxx support. */
+ s390_option_override_internal (opts, &new_opts_set);
+ /* Save the current options unless we are validating options for
+ #pragma. */
+ t = build_target_option_node (opts);
+ }
+ return t;
+}
+
+/* Hook to validate attribute((target("string"))). */
+
+static bool
+s390_valid_target_attribute_p (tree fndecl,
+ tree ARG_UNUSED (name),
+ tree args,
+ int ARG_UNUSED (flags))
+{
+ struct gcc_options func_options;
+ tree new_target, new_optimize;
+ bool ret = true;
+
+ /* attribute((target("default"))) does nothing, beyond
+ affecting multi-versioning. */
+ if (TREE_VALUE (args)
+ && TREE_CODE (TREE_VALUE (args)) == STRING_CST
+ && TREE_CHAIN (args) == NULL_TREE
+ && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0)
+ return true;
+
+ tree old_optimize = build_optimization_node (&global_options);
+
+ /* Get the optimization options of the current function. */
+ tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
+
+ if (!func_optimize)
+ func_optimize = old_optimize;
+
+ /* Init func_options. */
+ memset (&func_options, 0, sizeof (func_options));
+ init_options_struct (&func_options, NULL);
+ lang_hooks.init_options_struct (&func_options);
+
+ cl_optimization_restore (&func_options, TREE_OPTIMIZATION (func_optimize));
+
+ /* Initialize func_options to the default before its target options can
+ be set. */
+ cl_target_option_restore (&func_options,
+ TREE_TARGET_OPTION (target_option_default_node));
+
+ new_target = s390_valid_target_attribute_tree (args, &func_options,
+ &global_options_set,
+ (args ==
+ current_target_pragma));
+ new_optimize = build_optimization_node (&func_options);
+ if (new_target == error_mark_node)
+ ret = false;
+ else if (fndecl && new_target)
+ {
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
+ if (old_optimize != new_optimize)
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+ }
+ return ret;
+}
+
+/* Restore targets globals from NEW_TREE and invalidate s390_previous_fndecl
+ cache. */
+
+void
+s390_activate_target_options (tree new_tree)
+{
+ cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts ();
+ s390_previous_fndecl = NULL_TREE;
+}
+
+/* Establish appropriate back-end context for processing the function
+ FNDECL. The argument might be NULL to indicate processing at top
+ level, outside of any function scope. */
+static void
+s390_set_current_function (tree fndecl)
+{
+ /* Only change the context if the function changes. This hook is called
+ several times in the course of compiling a function, and we don't want to
+ slow things down too much or call target_reinit when it isn't safe. */
+ if (fndecl == s390_previous_fndecl)
+ return;
+
+ tree old_tree;
+ if (s390_previous_fndecl == NULL_TREE)
+ old_tree = target_option_current_node;
+ else if (DECL_FUNCTION_SPECIFIC_TARGET (s390_previous_fndecl))
+ old_tree = DECL_FUNCTION_SPECIFIC_TARGET (s390_previous_fndecl);
+ else
+ old_tree = target_option_default_node;
+
+ if (fndecl == NULL_TREE)
+ {
+ if (old_tree != target_option_current_node)
+ s390_activate_target_options (target_option_current_node);
+ return;
+ }
+
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+ if (new_tree == NULL_TREE)
+ new_tree = target_option_default_node;
+
+ if (old_tree != new_tree)
+ s390_activate_target_options (new_tree);
+ s390_previous_fndecl = fndecl;
+}
+#endif
+
/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
static bool
@@ -14136,6 +14648,17 @@ s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree ty
#undef TARGET_ASM_FILE_END
#define TARGET_ASM_FILE_END s390_asm_file_end
+#if S390_USE_TARGET_ATTRIBUTE
+#undef TARGET_SET_CURRENT_FUNCTION
+#define TARGET_SET_CURRENT_FUNCTION s390_set_current_function
+
+#undef TARGET_OPTION_VALID_ATTRIBUTE_P
+#define TARGET_OPTION_VALID_ATTRIBUTE_P s390_valid_target_attribute_p
+#endif
+
+#undef TARGET_OPTION_RESTORE
+#define TARGET_OPTION_RESTORE s390_function_specific_restore
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-s390.h"
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 0f9225c6f84..b96549e177a 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -50,48 +50,110 @@ enum processor_flags
#define TARGET_CPU_IEEE_FLOAT \
(s390_arch_flags & PF_IEEE_FLOAT)
+#define TARGET_CPU_IEEE_FLOAT_P(opts) \
+ (opts->x_s390_arch_flags & PF_IEEE_FLOAT)
#define TARGET_CPU_ZARCH \
(s390_arch_flags & PF_ZARCH)
+#define TARGET_CPU_ZARCH_P(opts) \
+ (opts->x_s390_arch_flags & PF_ZARCH)
#define TARGET_CPU_LONG_DISPLACEMENT \
(s390_arch_flags & PF_LONG_DISPLACEMENT)
+#define TARGET_CPU_LONG_DISPLACEMENT_P(opts) \
+ (opts->x_s390_arch_flags & PF_LONG_DISPLACEMENT)
#define TARGET_CPU_EXTIMM \
- (s390_arch_flags & PF_EXTIMM)
+ (s390_arch_flags & PF_EXTIMM)
+#define TARGET_CPU_EXTIMM_P(opts) \
+ (opts->x_s390_arch_flags & PF_EXTIMM)
#define TARGET_CPU_DFP \
- (s390_arch_flags & PF_DFP)
+ (s390_arch_flags & PF_DFP)
+#define TARGET_CPU_DFP_P(opts) \
+ (opts->x_s390_arch_flags & PF_DFP)
#define TARGET_CPU_Z10 \
- (s390_arch_flags & PF_Z10)
+ (s390_arch_flags & PF_Z10)
+#define TARGET_CPU_Z10_P(opts) \
+ (opts->x_s390_arch_flags & PF_Z10)
#define TARGET_CPU_Z196 \
- (s390_arch_flags & PF_Z196)
+ (s390_arch_flags & PF_Z196)
+#define TARGET_CPU_Z196_P(opts) \
+ (opts->x_s390_arch_flags & PF_Z196)
#define TARGET_CPU_ZEC12 \
- (s390_arch_flags & PF_ZEC12)
+ (s390_arch_flags & PF_ZEC12)
+#define TARGET_CPU_ZEC12_P(opts) \
+ (opts->x_s390_arch_flags & PF_ZEC12)
#define TARGET_CPU_HTM \
- (s390_arch_flags & PF_TX)
+ (s390_arch_flags & PF_TX)
+#define TARGET_CPU_HTM_P(opts) \
+ (opts->x_s390_arch_flags & PF_TX)
#define TARGET_CPU_Z13 \
- (s390_arch_flags & PF_Z13)
+ (s390_arch_flags & PF_Z13)
+#define TARGET_CPU_Z13_P(opts) \
+ (opts->x_s390_arch_flags & PF_Z13)
#define TARGET_CPU_VX \
(s390_arch_flags & PF_VX)
+#define TARGET_CPU_VX_P(opts) \
+ (opts->x_s390_arch_flags & PF_VX)
+
+#define TARGET_HARD_FLOAT_P(opts) (!TARGET_SOFT_FLOAT_P(opts))
/* These flags indicate that the generated code should run on a cpu
providing the respective hardware facility when run in
z/Architecture mode. */
#define TARGET_LONG_DISPLACEMENT \
- (TARGET_ZARCH && TARGET_CPU_LONG_DISPLACEMENT)
+ (TARGET_ZARCH && TARGET_CPU_LONG_DISPLACEMENT)
+#define TARGET_LONG_DISPLACEMENT_P(opts) \
+ (TARGET_ZARCH_P (opts->x_target_flags) \
+ && TARGET_CPU_LONG_DISPLACEMENT_P (opts))
#define TARGET_EXTIMM \
- (TARGET_ZARCH && TARGET_CPU_EXTIMM)
+ (TARGET_ZARCH && TARGET_CPU_EXTIMM)
+#define TARGET_EXTIMM_P(opts) \
+ (TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_EXTIMM_P (opts))
#define TARGET_DFP \
- (TARGET_ZARCH && TARGET_CPU_DFP && TARGET_HARD_FLOAT)
+ (TARGET_ZARCH && TARGET_CPU_DFP && TARGET_HARD_FLOAT)
+#define TARGET_DFP_P(opts) \
+ (TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_DFP_P (opts) \
+ && TARGET_HARD_FLOAT_P (opts->x_target_flags))
#define TARGET_Z10 \
- (TARGET_ZARCH && TARGET_CPU_Z10)
+ (TARGET_ZARCH && TARGET_CPU_Z10)
+#define TARGET_Z10_P(opts) \
+ (TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_Z10_P (opts))
#define TARGET_Z196 \
- (TARGET_ZARCH && TARGET_CPU_Z196)
+ (TARGET_ZARCH && TARGET_CPU_Z196)
+#define TARGET_Z196_P(opts) \
+ (TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_Z196_P (opts))
#define TARGET_ZEC12 \
- (TARGET_ZARCH && TARGET_CPU_ZEC12)
+ (TARGET_ZARCH && TARGET_CPU_ZEC12)
+#define TARGET_ZEC12_P(opts) \
+ (TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_ZEC12_P (opts))
#define TARGET_HTM (TARGET_OPT_HTM)
+#define TARGET_HTM_P(opts) (TARGET_OPT_HTM_P (opts->x_target_flags))
#define TARGET_Z13 \
- (TARGET_ZARCH && TARGET_CPU_Z13)
+ (TARGET_ZARCH && TARGET_CPU_Z13)
+#define TARGET_Z13_P(opts) \
+ (TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_Z13_P (opts))
#define TARGET_VX \
- (TARGET_ZARCH && TARGET_CPU_VX && TARGET_OPT_VX && TARGET_HARD_FLOAT)
+ (TARGET_ZARCH && TARGET_CPU_VX && TARGET_OPT_VX && TARGET_HARD_FLOAT)
+#define TARGET_VX_P(opts) \
+ (TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_VX_P (opts) \
+ && TARGET_OPT_VX_P (opts->x_target_flags) \
+ && TARGET_HARD_FLOAT_P (opts->x_target_flags))
+
+#ifdef HAVE_AS_MACHINE_MACHINEMODE
+#define S390_USE_TARGET_ATTRIBUTE 1
+#else
+#define S390_USE_TARGET_ATTRIBUTE 0
+#endif
+
+#ifdef HAVE_AS_ARCHITECTURE_MODIFIERS
+#define S390_USE_ARCHITECTURE_MODIFIERS 1
+#else
+#define S390_USE_ARCHITECTURE_MODIFIERS 0
+#endif
+
+#if S390_USE_TARGET_ATTRIBUTE
+/* For switching between functions with different target attributes. */
+#define SWITCHABLE_TARGET 1
+#endif
/* Use the ABI introduced with IBM z13:
- pass vector arguments <= 16 bytes in VRs
@@ -937,6 +999,16 @@ do { \
#define ASM_OUTPUT_FUNCTION_LABEL(FILE, NAME, DECL) \
s390_asm_output_function_label (FILE, NAME, DECL)
+#if S390_USE_TARGET_ATTRIBUTE
+/* Hook to output .machine and .machinemode at start of function. */
+#undef ASM_OUTPUT_FUNCTION_PREFIX
+#define ASM_OUTPUT_FUNCTION_PREFIX s390_asm_output_function_prefix
+
+/* Hook to output .machine and .machinemode at end of function. */
+#undef ASM_DECLARE_FUNCTION_SIZE
+#define ASM_DECLARE_FUNCTION_SIZE s390_asm_declare_function_size
+#endif
+
/* Miscellaneous parameters. */
/* Specify the machine mode that this machine uses for the index in the
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index af82815fd82..a37c853d03d 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -21,18 +21,27 @@
HeaderInclude
config/s390/s390-opts.h
-; The architecture name to use in diagnostics.
-Variable
-const char *s390_arch_string
+;; Definitions to add to the cl_target_option and gcc_options structures
-Variable
-int s390_tune_flags
+;; whether -march was specified
+TargetVariable
+unsigned char s390_arch_specified
-Variable
+;; Flags derived from s390_arch
+TargetVariable
int s390_arch_flags
+;; whether -mtune was specified
+TargetVariable
+unsigned char s390_tune_specified
+
+;; Flags derived from s390_tune
+TargetVariable
+int s390_tune_flags
+
+;; Cpu cost table (this is actually a "const struct processor_cost *")
Variable
-HOST_WIDE_INT s390_warn_framesize = 0
+long s390_cost_pointer
m31
Target Report RejectNegative Negative(m64) InverseMask(64BIT)
@@ -43,7 +52,7 @@ Target Report RejectNegative Negative(m31) Mask(64BIT)
64 bit ABI.
march=
-Target RejectNegative Joined Enum(processor_type) Var(s390_arch) Init(PROCESSOR_max)
+Target RejectNegative Joined Enum(processor_type) Var(s390_arch) Init(PROCESSOR_max) Save
Generate code for given CPU.
Enum
@@ -83,11 +92,11 @@ EnumValue
Enum(processor_type) String(native) Value(PROCESSOR_NATIVE) DriverOnly
mbackchain
-Target Report Mask(BACKCHAIN)
+Target Report Mask(BACKCHAIN) Save
Maintain backchain pointer.
mdebug
-Target Report Mask(DEBUG_ARG)
+Target Report Mask(DEBUG_ARG) Save
Additional debug prints.
mesa
@@ -95,11 +104,11 @@ Target Report RejectNegative Negative(mzarch) InverseMask(ZARCH)
ESA/390 architecture.
mhard-dfp
-Target Report Mask(HARD_DFP)
+Target Report Mask(HARD_DFP) Save
Enable decimal floating point hardware support.
mhard-float
-Target Report RejectNegative Negative(msoft-float) InverseMask(SOFT_FLOAT, HARD_FLOAT)
+Target Report RejectNegative Negative(msoft-float) InverseMask(SOFT_FLOAT, HARD_FLOAT) Save
Enable hardware floating point.
mhotpatch=
@@ -121,52 +130,60 @@ Target Report RejectNegative Negative(mlong-double-128) InverseMask(LONG_DOUBLE_
Use 64-bit long double.
mhtm
-Target Report Mask(OPT_HTM)
+Target Report Mask(OPT_HTM) Save
Use hardware transactional execution instructions.
mvx
-Target Report Mask(OPT_VX)
+Target Report Mask(OPT_VX) Save
Use hardware vector facility instructions and enable the vector ABI.
mpacked-stack
-Target Report Mask(PACKED_STACK)
+Target Report Mask(PACKED_STACK) Save
Use packed stack layout.
msmall-exec
-Target Report Mask(SMALL_EXEC)
+Target Report Mask(SMALL_EXEC) Save
Use bras for executable < 64k.
msoft-float
-Target Report RejectNegative Negative(mhard-float) Mask(SOFT_FLOAT)
+Target Report RejectNegative Negative(mhard-float) Mask(SOFT_FLOAT) Save
Disable hardware floating point.
mstack-guard=
-Target RejectNegative Joined UInteger Var(s390_stack_guard)
+Target RejectNegative Negative(mno-stack-guard) Joined UInteger Var(s390_stack_guard) Save
Set the max. number of bytes which has to be left to stack size before a trap instruction is triggered.
+mno-stack-guard
+Target RejectNegative Alias(mstack-guard=,0) Negative(mstack-guard=)
+Switches off the -mstack-guard= option.
+
mstack-size=
-Target RejectNegative Joined UInteger Var(s390_stack_size)
+Target RejectNegative Joined UInteger Var(s390_stack_size) Save
Emit extra code in the function prologue in order to trap if the stack size exceeds the given limit.
+mno-stack-size
+Target RejectNegative Alias(mstack-size=,0) Negative(mstack-size=)
+Switches off the -mstack-size= option.
+
mtune=
-Target RejectNegative Joined Enum(processor_type) Var(s390_tune) Init(PROCESSOR_max)
+Target RejectNegative Joined Enum(processor_type) Var(s390_tune) Init(PROCESSOR_max) Save
Schedule code for given CPU.
mmvcle
-Target Report Mask(MVCLE)
+Target Report Mask(MVCLE) Save
mvcle use.
mzvector
-Target Report Mask(ZVECTOR)
+Target Report Mask(ZVECTOR) Save
Enable the z vector language extension providing the context-sensitive
vector macro and enable the Altivec-style builtins in vecintrin.h
mwarn-dynamicstack
-Target RejectNegative Var(s390_warn_dynamicstack_p)
+Target Var(s390_warn_dynamicstack_p) Save
Warn if a function uses alloca or creates an array with dynamic size.
mwarn-framesize=
-Target RejectNegative Joined
+Target RejectNegative Joined UInteger Var(s390_warn_framesize) Save
Warn if a single function's framesize exceeds the given framesize.
mzarch
@@ -174,7 +191,7 @@ Target Report RejectNegative Negative(mesa) Mask(ZARCH)
z/Architecture.
mbranch-cost=
-Target Report Joined RejectNegative UInteger Var(s390_branch_cost) Init(1)
+Target Report Joined RejectNegative UInteger Var(s390_branch_cost) Init(1) Save
Set the branch costs for conditional branch instructions. Reasonable
values are small, non-negative integers. The default branch cost is
1.
diff --git a/gcc/config/s390/vecintrin.h b/gcc/config/s390/vecintrin.h
index c24dcb42eb4..621f96c9cc8 100644
--- a/gcc/config/s390/vecintrin.h
+++ b/gcc/config/s390/vecintrin.h
@@ -21,8 +21,6 @@ along with GCC; see the file COPYING3. If not see
#ifndef _VECINTRIN_H
#define _VECINTRIN_H
-#ifdef __VEC__
-
#define __VFTCI_ZERO 1<<11
#define __VFTCI_ZERO_N 1<<10
#define __VFTCI_NORMAL 1<<9
@@ -96,53 +94,50 @@ __lcbb(const void *ptr, int bndry)
#define vec_madd __builtin_s390_vfmadb
#define vec_msub __builtin_s390_vfmsdb
-static inline int
-vec_all_nan (__vector double a)
-{
- int cc;
- __builtin_s390_vftcidb (a,
- __VFTCI_QNAN
- | __VFTCI_QNAN_N
- | __VFTCI_SNAN
- | __VFTCI_SNAN_N, &cc);
- return cc == 0 ? 1 : 0;
-}
+#define vec_all_nan(a) \
+ __extension__ ({ \
+ int __cc; \
+ __builtin_s390_vftcidb (a, \
+ __VFTCI_QNAN \
+ | __VFTCI_QNAN_N \
+ | __VFTCI_SNAN \
+ | __VFTCI_SNAN_N, &__cc); \
+ __cc == 0 ? 1 : 0; \
+ })
-static inline int
-vec_all_numeric (__vector double a)
-{
- int cc;
- __builtin_s390_vftcidb (a,
- __VFTCI_NORMAL
- | __VFTCI_NORMAL_N
- | __VFTCI_SUBNORMAL
- | __VFTCI_SUBNORMAL_N, &cc);
- return cc == 0 ? 1 : 0;
-}
+#define vec_all_numeric(a) \
+ __extension__ ({ \
+ int __cc; \
+ __builtin_s390_vftcidb (a, \
+ __VFTCI_NORMAL \
+ | __VFTCI_NORMAL_N \
+ | __VFTCI_SUBNORMAL \
+ | __VFTCI_SUBNORMAL_N, &__cc); \
+ __cc == 0 ? 1 : 0; \
+ })
-static inline int
-vec_any_nan (__vector double a)
-{
- int cc;
- __builtin_s390_vftcidb (a,
- __VFTCI_QNAN
- | __VFTCI_QNAN_N
- | __VFTCI_SNAN
- | __VFTCI_SNAN_N, &cc);
- return cc != 3 ? 1 : 0;
-}
+#define vec_any_nan(a) \
+ __extension__ ({ \
+ int __cc; \
+ __builtin_s390_vftcidb (a, \
+ __VFTCI_QNAN \
+ | __VFTCI_QNAN_N \
+ | __VFTCI_SNAN \
+ | __VFTCI_SNAN_N, &cc); \
+ cc != 3 ? 1 : 0; \
+ })
+
+#define vec_any_numeric(a) \
+ __extension__ ({ \
+ int __cc; \
+ __builtin_s390_vftcidb (a, \
+ __VFTCI_NORMAL \
+ | __VFTCI_NORMAL_N \
+ | __VFTCI_SUBNORMAL \
+ | __VFTCI_SUBNORMAL_N, &cc); \
+ cc != 3 ? 1 : 0; \
+ })
-static inline int
-vec_any_numeric (__vector double a)
-{
- int cc;
- __builtin_s390_vftcidb (a,
- __VFTCI_NORMAL
- | __VFTCI_NORMAL_N
- | __VFTCI_SUBNORMAL
- | __VFTCI_SUBNORMAL_N, &cc);
- return cc != 3 ? 1 : 0;
-}
#define vec_gather_element __builtin_s390_vec_gather_element
#define vec_xld2 __builtin_s390_vec_xld2
#define vec_xlw4 __builtin_s390_vec_xlw4
@@ -272,5 +267,4 @@ vec_any_numeric (__vector double a)
#define vec_ctul __builtin_s390_vec_ctul
#define vec_ld2f __builtin_s390_vec_ld2f
#define vec_st2f __builtin_s390_vec_st2f
-#endif /* __VEC__ */
#endif /* _VECINTRIN_H */