Add ARM/thumb pragma target
authorChristian Bruel <christian.bruel@st.com>
Thu, 11 Jun 2015 08:51:17 +0000 (10:51 +0200)
committerChristian Bruel <chrbr@gcc.gnu.org>
Thu, 11 Jun 2015 08:51:17 +0000 (10:51 +0200)
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

gcc/ChangeLog
gcc/config/arm/arm-c.c
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pragma_attribute.c [new file with mode: 0644]

index c874789..f89cbb6 100644 (file)
@@ -1,3 +1,17 @@
+2015-06-11  Christian Bruel  <christian.bruel@st.com>
+
+       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.
+
 2015-06-10  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        * config/sh/sh.md (tstsi_t): Add '?' modifier to 'r' alternative
index fde0966..f02dfb4 100644 (file)
 #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
+}
index 3092b1a..1abe54e 100644 (file)
@@ -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);
 
index b24b4fb..373dc85 100644 (file)
@@ -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.  */
index 80a4c82..0accb7c 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-11  Christian Bruel  <christian.bruel@st.com>
+
+       PR target/52144
+       * gcc.target/arm/pragma_attribute.c: New test.
+
 2015-06-10  Uros Bizjak  <ubizjak@gmail.com>
 
        * g++.dg/abi/mangle-regparm.C (dg-optiond): Add -save-temps.
@@ -13,7 +18,7 @@
        * gcc.dg/tls/pr66470.c: New test.
        * gcc.target/i386/pr66470.c: New test.
 
-2015-06-09  Christian Bruel  <christian.bruel@st.com>
+2015-06-10  Christian Bruel  <christian.bruel@st.com>
 
        PR target/52144
        * gcc.target/arm/attr_arm.c: New test
diff --git a/gcc/testsuite/gcc.target/arm/pragma_attribute.c b/gcc/testsuite/gcc.target/arm/pragma_attribute.c
new file mode 100644 (file)
index 0000000..12afc97
--- /dev/null
@@ -0,0 +1,35 @@
+/* Test for #prama target macros.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+#pragma GCC target ("thumb")
+
+#ifndef __thumb__
+#error "__thumb__ is not defined"
+#endif
+
+#ifdef __thumb2__
+#ifndef __ARM_32BIT_STATE
+#error  "__ARM_32BIT_STATE is not defined"
+#endif
+#else /* thumb1 */
+#ifdef __ARM_32BIT_STATE
+#error  "__ARM_32BIT_STATE is defined"
+#endif
+#endif /* thumb1 */
+
+#pragma GCC target ("arm")
+
+#ifdef __thumb__
+#error "__thumb__ is defined"
+#endif
+
+#if defined (__thumb2__) || defined (__thumb1__)
+#error "thumb is defined"
+#endif 
+
+#ifndef __ARM_32BIT_STATE
+#error  "__ARM_32BIT_STATE is not defined"
+#endif
+
+#pragma GCC reset_options