aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorChristian Bruel <christian.bruel@st.com>2015-06-11 10:51:17 +0200
committerChristian Bruel <chrbr@gcc.gnu.org>2015-06-11 10:51:17 +0200
commitc84f825ca6438ea3c137342677b3c879499638da (patch)
tree162e2b98e73df673621c73b9c34bee20d5c00f08 /gcc/config
parent1e5df998631330662f7fb51bd0ae0725c8b1327f (diff)
downloadgcc-c84f825ca6438ea3c137342677b3c879499638da.zip
gcc-c84f825ca6438ea3c137342677b3c879499638da.tar.gz
gcc-c84f825ca6438ea3c137342677b3c879499638da.tar.bz2
Add ARM/thumb pragma target
PR target/52144 * config/arm/arm-c.c (arm_cpu_cpp_builtins): Conditionally define macros in ... (arm_cpu_builtins): New function. (arm_pragma_target_parse): Call arm_cpu_builtins. * config/arm/arm-protos.h (arm_cpu_builtins): Declare. (arm_register_target_pragmas): Likewise. * config/arm/arm.h (REGISTER_TARGET_PRAGMAS): Call arm_register_target_pragmas. * config/arm/arm-c.c (arm_register_target_pragmas): New function. (arm_pragma_target_parse): Likewise. PR target/52144 * gcc.target/arm/pragma_attribute.c: New test. From-SVN: r224365
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm-c.c94
-rw-r--r--gcc/config/arm/arm-protos.h6
-rw-r--r--gcc/config/arm/arm.h3
3 files changed, 93 insertions, 10 deletions
diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c
index fde0966..f02dfb4 100644
--- a/gcc/config/arm/arm-c.c
+++ b/gcc/config/arm/arm-c.c
@@ -25,7 +25,11 @@
#include "alias.h"
#include "symtab.h"
#include "tree.h"
+#include "tm_p.h"
#include "c-family/c-common.h"
+#include "target.h"
+#include "target-def.h"
+#include "c-family/c-pragma.h"
/* Output C specific EABI object attributes. These can not be done in
arm.c because they require information from the C frontend. */
@@ -62,10 +66,8 @@ def_or_undef_macro(struct cpp_reader* pfile, const char *name, bool def_p)
}
void
-arm_cpu_cpp_builtins (struct cpp_reader * pfile)
+arm_cpu_builtins (struct cpp_reader* pfile, int flags)
{
- int flags = target_flags;
-
def_or_undef_macro (pfile, "__ARM_FEATURE_DSP",
TARGET_DSP_MULTIPLY_P (flags));
def_or_undef_macro (pfile, "__ARM_FEATURE_QBIT",
@@ -157,8 +159,6 @@ arm_cpu_cpp_builtins (struct cpp_reader * pfile)
if (arm_cpp_interwork)
builtin_define ("__THUMB_INTERWORK__");
- builtin_assert ("cpu=arm");
- builtin_assert ("machine=arm");
builtin_define (arm_arch_name);
if (arm_arch_xscale)
@@ -179,10 +179,90 @@ arm_cpu_cpp_builtins (struct cpp_reader * pfile)
builtin_define ("__ARM_EABI__");
}
-
-
def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV_P (flags));
def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV_P (flags));
def_or_undef_macro (pfile, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified);
}
+
+void
+arm_cpu_cpp_builtins (struct cpp_reader * pfile)
+{
+ builtin_assert ("cpu=arm");
+ builtin_assert ("machine=arm");
+
+ arm_cpu_builtins (pfile, target_flags);
+}
+
+/* Hook to validate the current #pragma GCC target and set the arch custom
+ mode state. If ARGS is NULL, then POP_TARGET is used to reset
+ the options. */
+static bool
+arm_pragma_target_parse (tree args, tree pop_target)
+{
+ tree prev_tree = build_target_option_node (&global_options);
+ tree cur_tree;
+ struct cl_target_option *prev_opt;
+ struct cl_target_option *cur_opt;
+
+ if (! args)
+ {
+ cur_tree = ((pop_target) ? pop_target : target_option_default_node);
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (cur_tree));
+ }
+ else
+ {
+ cur_tree = arm_valid_target_attribute_tree (args, &global_options,
+ &global_options_set);
+ if (cur_tree == NULL_TREE)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (prev_tree));
+ return false;
+ }
+ }
+
+ target_option_current_node = cur_tree;
+ arm_reset_previous_fndecl ();
+
+ /* Figure out the previous mode. */
+ prev_opt = TREE_TARGET_OPTION (prev_tree);
+ cur_opt = TREE_TARGET_OPTION (cur_tree);
+
+ gcc_assert (prev_opt);
+ gcc_assert (cur_opt);
+
+ if (cur_opt->x_target_flags != prev_opt->x_target_flags)
+ {
+ /* 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;
+
+ /* Update macros. */
+ arm_cpu_builtins (parse_in, cur_opt->x_target_flags);
+
+ cpp_opts->warn_unused_macros = saved_warn_unused_macros;
+ }
+
+ return true;
+}
+
+/* Register target pragmas. We need to add the hook for parsing #pragma GCC
+ option here rather than in arm.c since it will pull in various preprocessor
+ functions, and those are not present in languages like fortran without a
+ preprocessor. */
+
+void
+arm_register_target_pragmas (void)
+{
+ /* Update pragma hook to allow parsing #pragma GCC target. */
+ targetm.target_option.pragma_parse = arm_pragma_target_parse;
+
+#ifdef REGISTER_SUBTARGET_PRAGMAS
+ REGISTER_SUBTARGET_PRAGMAS ();
+#endif
+}
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 3092b1a..1abe54e 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -211,10 +211,10 @@ extern int arm_dllimport_p (tree);
extern void arm_mark_dllexport (tree);
extern void arm_mark_dllimport (tree);
extern bool arm_change_mode_p (tree);
-extern tree arm_valid_target_attribute_tree (tree, struct gcc_options *,
- struct gcc_options *);
#endif
+extern tree arm_valid_target_attribute_tree (tree, struct gcc_options *,
+ struct gcc_options *);
extern void arm_pr_long_calls (struct cpp_reader *);
extern void arm_pr_no_long_calls (struct cpp_reader *);
extern void arm_pr_long_calls_off (struct cpp_reader *);
@@ -336,7 +336,9 @@ extern const char *arm_rewrite_selected_cpu (const char *name);
/* Defined in gcc/common/config/arm-c.c. */
extern void arm_lang_object_attributes_init (void);
+extern void arm_register_target_pragmas (void);
extern void arm_cpu_cpp_builtins (struct cpp_reader *);
+extern void arm_cpu_builtins (struct cpp_reader *, int);
extern bool arm_is_constant_pool_ref (rtx);
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index b24b4fb..373dc85 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1991,7 +1991,8 @@ extern int making_const_table;
c_register_pragma (0, "long_calls", arm_pr_long_calls); \
c_register_pragma (0, "no_long_calls", arm_pr_no_long_calls); \
c_register_pragma (0, "long_calls_off", arm_pr_long_calls_off); \
- arm_lang_object_attributes_init(); \
+ arm_lang_object_attributes_init(); \
+ arm_register_target_pragmas(); \
} while (0)
/* Condition code information. */