aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorChristian Bruel <christian.bruel@st.com>2015-11-16 11:21:09 +0100
committerChristian Bruel <chrbr@gcc.gnu.org>2015-11-16 11:21:09 +0100
commitc91062822060a9cab744b3d10fda6456822740aa (patch)
treeee314e0dd14d265464bb96c6e9abbc167b1599e8 /gcc/config
parentf39cdf66d6e7f9b42b9339315aabfea40af44460 (diff)
downloadgcc-c91062822060a9cab744b3d10fda6456822740aa.zip
gcc-c91062822060a9cab744b3d10fda6456822740aa.tar.gz
gcc-c91062822060a9cab744b3d10fda6456822740aa.tar.bz2
re PR target/65837 ([arm-linux-gnueabihf] lto1 target specific builtin not available)
2015-11-16 Christian Bruel <christian.bruel@st.com> PR target/65837 * config/arm/arm-c.c (arm_cpu_builtins): Set or reset __ARM_FEATURE_CRYPTO, __VFP_FP__, __ARM_NEON__ (arm_pragma_target_parse): Change check for arm_cpu_builtins. undefine __ARM_FP. * config/arm/arm.c (arm_can_inline_p): Check FPUs. (arm_valid_target_attribute_rec): Handle -mfpu attribute target. * doc/invoke.texi (-mfpu=): Mention attribute and pragma. * doc/extend.texi (-mfpu=): Describe attribute. 2015-11-16 Christian Bruel <christian.bruel@st.com> PR target/65837 gcc.target/arm/lto/pr65837_0.c gcc.target/arm/attr-neon2.c gcc.target/arm/attr-neon.c gcc.target/arm/attr-neon-builtin-fail.c gcc.target/arm/attr-crypto.c From-SVN: r230408
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm-c.c30
-rw-r--r--gcc/config/arm/arm.c72
2 files changed, 70 insertions, 32 deletions
diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c
index 6471dba..e94fa10 100644
--- a/gcc/config/arm/arm-c.c
+++ b/gcc/config/arm/arm-c.c
@@ -64,8 +64,8 @@ arm_cpu_builtins (struct cpp_reader* pfile)
def_or_undef_macro (pfile, "__ARM_FEATURE_DSP", TARGET_DSP_MULTIPLY);
def_or_undef_macro (pfile, "__ARM_FEATURE_QBIT", TARGET_ARM_QBIT);
def_or_undef_macro (pfile, "__ARM_FEATURE_SAT", TARGET_ARM_SAT);
- if (TARGET_CRYPTO)
- builtin_define ("__ARM_FEATURE_CRYPTO");
+ def_or_undef_macro (pfile, "__ARM_FEATURE_CRYPTO", TARGET_CRYPTO);
+
if (unaligned_access)
builtin_define ("__ARM_FEATURE_UNALIGNED");
if (TARGET_CRC32)
@@ -125,9 +125,8 @@ arm_cpu_builtins (struct cpp_reader* pfile)
if (TARGET_SOFT_FLOAT)
builtin_define ("__SOFTFP__");
- if (TARGET_VFP)
- builtin_define ("__VFP_FP__");
-
+ def_or_undef_macro (pfile, "__VFP_FP__", TARGET_VFP);
+
if (TARGET_ARM_FP)
builtin_define_with_int_value ("__ARM_FP", TARGET_ARM_FP);
if (arm_fp16_format == ARM_FP16_FORMAT_IEEE)
@@ -137,19 +136,16 @@ arm_cpu_builtins (struct cpp_reader* pfile)
if (TARGET_FMA)
builtin_define ("__ARM_FEATURE_FMA");
- if (TARGET_NEON)
- {
- builtin_define ("__ARM_NEON__");
- builtin_define ("__ARM_NEON");
- }
+ def_or_undef_macro (pfile, "__ARM_NEON__", TARGET_NEON);
+ def_or_undef_macro (pfile, "__ARM_NEON", TARGET_NEON);
+
if (TARGET_NEON_FP)
builtin_define_with_int_value ("__ARM_NEON_FP", TARGET_NEON_FP);
-
+
/* Add a define for interworking. Needed when building libgcc.a. */
if (arm_cpp_interwork)
builtin_define ("__THUMB_INTERWORK__");
-
builtin_define (arm_arch_name);
if (arm_arch_xscale)
builtin_define ("__XSCALE__");
@@ -228,19 +224,27 @@ arm_pragma_target_parse (tree args, tree pop_target)
gcc_assert (prev_opt);
gcc_assert (cur_opt);
- if (cur_opt->x_target_flags != prev_opt->x_target_flags)
+ if (cur_opt != prev_opt)
{
/* 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;
+ unsigned char saved_warn_builtin_macro_redefined
+ = cpp_opts->warn_builtin_macro_redefined;
+
cpp_opts->warn_unused_macros = 0;
+ cpp_opts->warn_builtin_macro_redefined = 0;
/* Update macros. */
gcc_assert (cur_opt->x_target_flags == target_flags);
+ /* This one can be redefined by the pragma without warning. */
+ cpp_undef (parse_in, "__ARM_FP");
+
arm_cpu_builtins (parse_in);
+ cpp_opts->warn_builtin_macro_redefined = saved_warn_builtin_macro_redefined;
cpp_opts->warn_unused_macros = saved_warn_unused_macros;
}
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 98b5c82..a6b25dc 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -29759,11 +29759,36 @@ arm_option_print (FILE *file, int indent, struct cl_target_option *ptr)
/* Hook to determine if one function can safely inline another. */
static bool
-arm_can_inline_p (tree caller ATTRIBUTE_UNUSED, tree callee ATTRIBUTE_UNUSED)
+arm_can_inline_p (tree caller, tree callee)
{
- /* Overidde default hook: Always OK to inline between different modes.
- Function with mode specific instructions, e.g using asm, must be explicitely
- protected with noinline. */
+ tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
+ tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
+
+ struct cl_target_option *caller_opts
+ = TREE_TARGET_OPTION (caller_tree ? caller_tree
+ : target_option_default_node);
+
+ struct cl_target_option *callee_opts
+ = TREE_TARGET_OPTION (callee_tree ? callee_tree
+ : target_option_default_node);
+
+ const struct arm_fpu_desc *caller_fpu
+ = &all_fpus[caller_opts->x_arm_fpu_index];
+ const struct arm_fpu_desc *callee_fpu
+ = &all_fpus[callee_opts->x_arm_fpu_index];
+
+ /* Callee's fpu features should be a subset of the caller's. */
+ if ((caller_fpu->features & callee_fpu->features) != callee_fpu->features)
+ return false;
+
+ /* Need same model and regs. */
+ if (callee_fpu->model != caller_fpu->model
+ || callee_fpu->regs != callee_fpu->regs)
+ return false;
+
+ /* OK to inline between different modes.
+ Function with mode specific instructions, e.g using asm,
+ must be explicitly protected with noinline. */
return true;
}
@@ -29794,6 +29819,7 @@ arm_valid_target_attribute_rec (tree args, struct gcc_options *opts)
if (TREE_CODE (args) == TREE_LIST)
{
bool ret = true;
+
for (; args; args = TREE_CHAIN (args))
if (TREE_VALUE (args)
&& !arm_valid_target_attribute_rec (TREE_VALUE (args), opts))
@@ -29808,30 +29834,38 @@ arm_valid_target_attribute_rec (tree args, struct gcc_options *opts)
}
char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
- while (argstr && *argstr != '\0')
+ char *q;
+
+ while ((q = strtok (argstr, ",")) != NULL)
{
- while (ISSPACE (*argstr))
- argstr++;
+ while (ISSPACE (*q)) ++q;
- if (!strcmp (argstr, "thumb"))
- {
+ argstr = NULL;
+ if (!strncmp (q, "thumb", 5))
opts->x_target_flags |= MASK_THUMB;
- arm_option_check_internal (opts);
- return true;
- }
- if (!strcmp (argstr, "arm"))
- {
+ else if (!strncmp (q, "arm", 3))
opts->x_target_flags &= ~MASK_THUMB;
- arm_option_check_internal (opts);
- return true;
+
+ else if (!strncmp (q, "fpu=", 4))
+ {
+ if (! opt_enum_arg_to_value (OPT_mfpu_, q+4,
+ &opts->x_arm_fpu_index, CL_TARGET))
+ {
+ error ("invalid fpu for attribute(target(\"%s\"))", q);
+ return false;
+ }
+ }
+ else
+ {
+ error ("attribute(target(\"%s\")) is unknown", q);
+ return false;
}
- warning (0, "attribute(target(\"%s\")) is unknown", argstr);
- return false;
+ arm_option_check_internal (opts);
}
- return false;
+ return true;
}
/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */