This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][GCC][ARM] Generate .arch and .arch_extensions for each function if required. [Patch (3/3)]


Hi All,

This patch adds the needed machinery to generate the appropriate
.arch and .arch_extension directives per function.

Borrowing from AArch64 this is only done when it's required (i.e. when
the directives to be set differ from the currently set one).

As part if this the .fpu directive has also been cleaned up to follow the
same logic.

Regtested on arm-none-eabi and no regressions.

Ok for trunk?

gcc/
2017-11-06  Tamar Christina  <tamar.christina@arm.com>

	PR target/82641
	* config/arm/arm.c (INCLUDE_STRING): Define.
	(arm_last_printed_arch_string, arm_last_printed_fpu_string): New.
	(arm_declare_function_name): Conservatively emit .arch, .arch_extensions
	and .fpu.

gcc/testsuite/
2017-11-06  Tamar Christina  <tamar.christina@arm.com>

	PR target/82641
	* gcc.target/arm/pragma_arch_attribute_2.c: New.
	* gcc.target/arm/pragma_arch_attribute_2.c: New.
	* gcc.target/arm/pragma_arch_attribute_3.c: New.
	* gcc.target/arm/pragma_fpu_attribute.c: New.
	* gcc.target/arm/pragma_fpu_attribute_2.c: New.

-- 
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 2b308fa2e3d5274682cc32dd9b91712c5604267e..ffcfc776eab165f5652e281cdc004f1d0878e120 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -21,6 +21,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_STRING
 #include "system.h"
 #include "coretypes.h"
 #include "backend.h"
@@ -30830,9 +30831,57 @@ arm_identify_fpu_from_isa (sbitmap isa)
   gcc_unreachable ();
 }
 
+/* The last .arch and .fpu assembly strings that we printed.  */
+static std::string arm_last_printed_arch_string;
+static std::string arm_last_printed_fpu_string;
+
+/* Implement ASM_DECLARE_FUNCTION_NAME.  Output the ISA features used
+   by the function fndecl.  */
 void
 arm_declare_function_name (FILE *stream, const char *name, tree decl)
 {
+  tree target_parts = DECL_FUNCTION_SPECIFIC_TARGET (decl);
+
+  struct cl_target_option *targ_options;
+  if (target_parts)
+    targ_options = TREE_TARGET_OPTION (target_parts);
+  else
+    targ_options = TREE_TARGET_OPTION (target_option_current_node);
+  gcc_assert (targ_options);
+
+  /* Only update the assembler .arch string if it is distinct from the last
+     such string we printed.  */
+  std::string arch_to_print = targ_options->x_arm_arch_string;
+  if (arch_to_print != arm_last_printed_arch_string)
+    {
+      std::string arch_name
+	= arch_to_print.substr (0, arch_to_print.find ("+"));
+      asm_fprintf (asm_out_file, "\t.arch %s\n", arch_name.c_str ());
+      const arch_option *arch
+	= arm_parse_arch_option_name (all_architectures, "-march",
+				      targ_options->x_arm_arch_string);
+      auto_sbitmap opt_bits (isa_num_bits);
+
+      gcc_assert (arch);
+      if (arch->common.extensions)
+	{
+	  for (const struct cpu_arch_extension *opt = arch->common.extensions;
+	       opt->name != NULL;
+	       opt++)
+	    {
+	      if (!opt->remove)
+		{
+		  arm_initialize_isa (opt_bits, opt->isa_bits);
+		  if (bitmap_subset_p (opt_bits, arm_active_target.isa)
+		      && !bitmap_subset_p (opt_bits, isa_all_fpubits))
+		    asm_fprintf (asm_out_file, "\t.arch_extension %s\n",
+				 opt->name);
+		}
+	     }
+	}
+
+      arm_last_printed_arch_string = arch_to_print;
+    }
 
   fprintf (stream, "\t.syntax unified\n");
 
@@ -30850,10 +30899,15 @@ arm_declare_function_name (FILE *stream, const char *name, tree decl)
   else
     fprintf (stream, "\t.arm\n");
 
-  asm_fprintf (asm_out_file, "\t.fpu %s\n",
-	       (TARGET_SOFT_FLOAT
-		? "softvfp"
-		: arm_identify_fpu_from_isa (arm_active_target.isa)));
+  std::string fpu_to_print
+    = TARGET_SOFT_FLOAT
+	? "softvfp" : arm_identify_fpu_from_isa (arm_active_target.isa);
+
+  if (fpu_to_print != arm_last_printed_arch_string)
+    {
+      asm_fprintf (asm_out_file, "\t.fpu %s\n", fpu_to_print.c_str ());
+      arm_last_printed_fpu_string = fpu_to_print;
+    }
 
   if (TARGET_POKE_FUNCTION_NAME)
     arm_poke_function_name (stream, (const char *) name);
diff --git a/gcc/testsuite/gcc.target/arm/pragma_arch_attribute_2.c b/gcc/testsuite/gcc.target/arm/pragma_arch_attribute_2.c
new file mode 100644
index 0000000000000000000000000000000000000000..2e8e385774b004a8f04e281a0449ed977210b540
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pragma_arch_attribute_2.c
@@ -0,0 +1,25 @@
+/* Test for target attribute assembly extension generations.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
+/* { dg-add-options arm_arch_v8a } */
+/* { dg-additional-options "-std=gnu99" } */
+
+#include <stdint.h>
+
+extern uint32_t bar();
+
+__attribute__((target("arch=armv8-a+crc"))) uint32_t crc32cw(uint32_t crc, uint32_t val)
+{
+    uint32_t res;
+    asm("crc32cw %0, %1, %2" : "=r"(res) : "r"(crc), "r"(val));
+    return res;
+}
+
+uint32_t restored ()
+{
+  return bar();
+}
+
+/* { dg-final { scan-assembler-times {\.arch\s+armv8-a} 3 } } */
+/* { dg-final { scan-assembler-times {\.arch_extension\s+crc} 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/arm/pragma_arch_attribute_3.c b/gcc/testsuite/gcc.target/arm/pragma_arch_attribute_3.c
new file mode 100644
index 0000000000000000000000000000000000000000..3714812cf26c08b08ccce834ca8511d53403d26d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pragma_arch_attribute_3.c
@@ -0,0 +1,28 @@
+/* Test for #pragma assembly extension generations.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
+/* { dg-add-options arm_arch_v8a } */
+/* { dg-additional-options "-std=gnu99" } */
+
+#include <stdint.h>
+
+extern uint32_t bar();
+
+#pragma GCC push_options
+#pragma GCC target("arch=armv8-a+crc")
+uint32_t crc32cw(uint32_t crc, uint32_t val)
+{
+    uint32_t res;
+    asm("crc32cw %0, %1, %2" : "=r"(res) : "r"(crc), "r"(val));
+    return res;
+}
+#pragma GCC pop_options
+
+uint32_t restored ()
+{
+  return bar();
+}
+
+/* { dg-final { scan-assembler-times {\.arch\s+armv8-a} 3 } } */
+/* { dg-final { scan-assembler-times {\.arch_extension\s+crc} 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/arm/pragma_fpu_attribute.c b/gcc/testsuite/gcc.target/arm/pragma_fpu_attribute.c
new file mode 100644
index 0000000000000000000000000000000000000000..f47c745855e4acc099afd554838dcf7d031f798c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pragma_fpu_attribute.c
@@ -0,0 +1,24 @@
+/* Test for target attribute assembly extension generations.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
+/* { dg-additional-options "-std=gnu99 -mfpu=vfpv3-d16" } */
+
+#include <stdint.h>
+#include <arm_neon.h>
+
+extern uint32_t bar();
+
+__attribute__((target("fpu=crypto-neon-fp-armv8"))) poly64x1_t vsricw(poly64x1_t crc, uint32_t val)
+{
+    poly64x1_t res;
+    asm("vsri %0, %1, %2" : "=r"(res) : "r"(crc), "r"(val));
+    return res;
+}
+
+uint32_t restored ()
+{
+  return bar();
+}
+
+/* { dg-final { scan-assembler-times {\.fpu\s+crypto-neon-fp-armv8} 1 } } */
+/* { dg-final { scan-assembler-times {\.fpu\s+vfpv3-d16} 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/pragma_fpu_attribute_2.c b/gcc/testsuite/gcc.target/arm/pragma_fpu_attribute_2.c
new file mode 100644
index 0000000000000000000000000000000000000000..f23fd83779e57e48c0035b6688a21850d12cb4ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pragma_fpu_attribute_2.c
@@ -0,0 +1,27 @@
+/* Test for #pragma assembly extension generations.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
+/* { dg-additional-options "-std=gnu99 -mfpu=vfpv3-d16" } */
+
+#include <stdint.h>
+#include <arm_neon.h>
+
+extern uint32_t bar();
+
+#pragma GCC push_options
+#pragma GCC target("fpu=crypto-neon-fp-armv8")
+poly64x1_t vsricw(poly64x1_t crc, uint32_t val)
+{
+    poly64x1_t res;
+    asm("vsri %0, %1, %2" : "=r"(res) : "r"(crc), "r"(val));
+    return res;
+}
+#pragma GCC pop_options
+
+uint32_t restored ()
+{
+  return bar();
+}
+
+/* { dg-final { scan-assembler-times {\.fpu\s+crypto-neon-fp-armv8} 1 } } */
+/* { dg-final { scan-assembler-times {\.fpu\s+vfpv3-d16} 1 } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]