public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][AArch64][10/14] Implement target pragmas
@ 2015-07-16 15:25 Kyrill Tkachov
  2015-07-21 16:58 ` James Greenhalgh
  0 siblings, 1 reply; 5+ messages in thread
From: Kyrill Tkachov @ 2015-07-16 15:25 UTC (permalink / raw)
  To: GCC Patches; +Cc: Marcus Shawcroft, Richard Earnshaw, James Greenhalgh

[-- Attachment #1: Type: text/plain, Size: 2129 bytes --]

Hi all,

This patch implements target pragmas for aarch64.
The pragmas accepted are the same as for target attributes (as required).
In addition pragmas will need to redefine the target-specific preprocessor
macros if appropriate.

A new file: aarch64-c.c is added and the code from TARGET_CPU_CPP_BUILTINS is moved there
and split up into the unconditional parts that are always defined and the conditional stuff
that depends on certain architectural features.  The pragma processing code calls that
to redefine preprocessor macros on the fly.
The implementation is similar to the rs6000 one.

With target pragmas implemented, we can use them in the arm_neon.h and arm_acle.h headers to
specify the architectural features required for those intrinsics, rather than #ifdef'ing them
out when FP/SIMD is not available from the command line.

We need to do this in order to handle cases where the user compiles a file with -mgeneral-regs-only
but has a function tagged with +simd and tries to use the arm_neon.h intrinsics.
Tests and documentation comes as a separate patch later on in the series

Bootstrapped and tested on aarch64.

Ok for trunk?

Thanks,
Kyrill

2015-07-16  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * config.gcc (aarch64*-*-*): Specify c_target_objs and cxx_target_objs.
     * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS):
     (TARGET_CPU_CPP_BUILTINS): Redefine to call aarch64_cpu_cpp_builtins.
     * config/aarch64/aarch64.c (aarch64_override_options_internal): Remove
     static keyword.
     (aarch64_reset_previous_fndecl): New function.
     * config/aarch64/aarch64-c.c: New file.
     * config/aarch64/arm_acle.h: Add pragma +crc+nofp at the top.
     Push and pop options at beginning and end.  Remove ifdef
     __ARM_FEATURE_CRC32.
     * config/aarch64/arm_neon.h: Remove #ifdef check on __ARM_NEON.
     Add pragma arch=armv8-a+simd and +crypto where appropriate.
     * config/aarch64/t-aarch64 (aarch64-c.o): New rule.

2015-07-16  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * gcc.target/aarch64/arm_neon-nosimd-error.c: Delete.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: aarch64-attrs-10.patch --]
[-- Type: text/x-patch; name=aarch64-attrs-10.patch, Size: 16837 bytes --]

commit 62979865acc0a1c832882cbb8871e6860efce620
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date:   Thu May 14 15:36:07 2015 +0100

    [AArch64][10/N] Implement target pragmas

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 900aa18..5da8442 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -302,6 +302,8 @@ m32c*-*-*)
 aarch64*-*-*)
 	cpu_type=aarch64
 	extra_headers="arm_neon.h arm_acle.h"
+        c_target_objs="aarch64-c.o"
+        cxx_target_objs="aarch64-c.o"
 	extra_objs="aarch64-builtins.o aarch-common.o cortex-a57-fma-steering.o"
 	target_gtfiles="\$(srcdir)/config/aarch64/aarch64-builtins.c"
 	target_has_targetm_common=yes
diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c
new file mode 100644
index 0000000..c3798a1
--- /dev/null
+++ b/gcc/config/aarch64/aarch64-c.c
@@ -0,0 +1,192 @@
+/* Target-specific code for C family languages.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "input.h"
+#include "tm_p.h"
+#include "flags.h"
+#include "c-family/c-common.h"
+#include "cpplib.h"
+#include "c-family/c-pragma.h"
+#include "langhooks.h"
+#include "target.h"
+
+
+#define builtin_define(TXT) cpp_define (pfile, TXT)
+#define builtin_assert(TXT) cpp_assert (pfile, TXT)
+
+
+static void
+aarch64_def_or_undef (bool def_p, const char *macro, cpp_reader *pfile)
+{
+  if (def_p)
+    cpp_define (pfile, macro);
+  else
+    cpp_undef (pfile, macro);
+}
+
+/* Define the macros that we always expect to have on AArch64.  */
+static void
+aarch64_define_unconditional_macros (cpp_reader *pfile)
+{
+  builtin_define ("__aarch64__");
+  builtin_define ("__ARM_64BIT_STATE");
+
+  builtin_define ("__ARM_ARCH_ISA_A64");
+  builtin_define_with_int_value ("__ARM_ALIGN_MAX_PWR", 28);
+  builtin_define_with_int_value ("__ARM_ALIGN_MAX_STACK_PWR", 16);
+
+  /* __ARM_ARCH_8A is not mandated by ACLE but we define it unconditionally
+     as interoperability with the same arm macro.  */
+  builtin_define ("__ARM_ARCH_8A");
+
+  builtin_define_with_int_value ("__ARM_ARCH_PROFILE", 'A');
+  builtin_define ("__ARM_FEATURE_CLZ");
+  builtin_define ("__ARM_FEATURE_IDIV");
+  builtin_define ("__ARM_FEATURE_UNALIGNED");
+  builtin_define ("__ARM_PCS_AAPCS64");
+  builtin_define_with_int_value ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8);
+
+}
+
+/* Undefine/redefine macros that depend on the current backend state and may
+   need to change when a target pragma modifies the backend state.  */
+
+static void
+aarch64_update_cpp_builtins (cpp_reader *pfile)
+{
+  aarch64_def_or_undef (flag_unsafe_math_optimizations, "__ARM_FP_FAST", pfile);
+
+  builtin_define_with_int_value ("__ARM_ARCH", aarch64_architecture_version);
+
+  builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
+				 flag_short_enums ? 1 : 4);
+  aarch64_def_or_undef (TARGET_BIG_END, "__AARCH64EB__", pfile);
+  aarch64_def_or_undef (TARGET_BIG_END, "__ARM_BIG_ENDIAN", pfile);
+  aarch64_def_or_undef (!TARGET_BIG_END, "__AARCH64EL__", pfile);
+
+  aarch64_def_or_undef (TARGET_FLOAT, "__ARM_FEATURE_FMA", pfile);
+
+  if (TARGET_FLOAT || TARGET_SIMD)
+    builtin_define_with_int_value ("__ARM_FP", 0x0C);
+  else
+    cpp_undef (pfile, "__ARM_FP");
+
+  aarch64_def_or_undef (TARGET_SIMD, "__ARM_FEATURE_NUMERIC_MAXMIN", pfile);
+  aarch64_def_or_undef (TARGET_SIMD, "__ARM_NEON", pfile);
+
+
+  aarch64_def_or_undef (TARGET_CRC32, "__ARM_FEATURE_CRC32", pfile);
+
+  cpp_undef (pfile, "__AARCH64_CMODEL_TINY__");
+  cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__");
+  cpp_undef (pfile, "__AARCH64_CMODEL_LARGE__");
+
+  switch (aarch64_cmodel)
+    {
+      case AARCH64_CMODEL_TINY:
+      case AARCH64_CMODEL_TINY_PIC:
+	builtin_define ("__AARCH64_CMODEL_TINY__");
+	break;
+      case AARCH64_CMODEL_SMALL:
+      case AARCH64_CMODEL_SMALL_PIC:
+	builtin_define ("__AARCH64_CMODEL_SMALL__");
+	break;
+      case AARCH64_CMODEL_LARGE:
+	builtin_define ("__AARCH64_CMODEL_LARGE__");
+	break;
+      default:
+	break;
+    }
+
+  aarch64_def_or_undef (TARGET_ILP32, "_ILP32", pfile);
+  aarch64_def_or_undef (TARGET_ILP32, "__ILP32__", pfile);
+
+  aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile);
+
+}
+
+/* Implement TARGET_CPU_CPP_BUILTINS.  */
+
+void
+aarch64_cpu_cpp_builtins (cpp_reader *pfile)
+{
+  aarch64_define_unconditional_macros (pfile);
+  aarch64_update_cpp_builtins (pfile);
+}
+
+/* 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
+aarch64_pragma_target_parse (tree args, tree pop_target)
+{
+
+  bool ret;
+
+  /* If args is not NULL then process it and setup the target-specific
+     information that it specifies.  */
+  if (args)
+    {
+      ret = aarch64_process_target_attr (args, "pragma");
+      if (ret)
+	aarch64_override_options_internal (&global_options);
+      else
+	return false;
+    }
+
+  /* args is NULL, restore to the state described in pop_target.  */
+  else
+    {
+      pop_target = pop_target ? pop_target : target_option_default_node;
+      cl_target_option_restore (&global_options,
+				TREE_TARGET_OPTION (pop_target));
+      ret = true;
+    }
+
+  target_option_current_node
+    = build_target_option_node (&global_options);
+
+  aarch64_reset_previous_fndecl ();
+  /* 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;
+
+  aarch64_update_cpp_builtins (parse_in);
+
+  cpp_opts->warn_unused_macros = saved_warn_unused_macros;
+
+  return ret;
+}
+
+/* Implement REGISTER_TARGET_PRAGMAS.  */
+
+void
+aarch64_register_pragmas (void)
+{
+  /* Update pragma hook to allow parsing #pragma GCC target.  */
+  targetm.target_option.pragma_parse = aarch64_pragma_target_parse;
+}
\ No newline at end of file
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 3a5482d..4704736 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -360,6 +360,10 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, enum machine_mode, RTX_CODE);
 #endif /* RTX_CODE */
 
 void aarch64_init_builtins (void);
+
+bool aarch64_process_target_attr (tree, const char*);
+void aarch64_override_options_internal (struct gcc_options *);
+
 rtx aarch64_expand_builtin (tree exp,
 			    rtx target,
 			    rtx subtarget ATTRIBUTE_UNUSED,
@@ -376,6 +380,9 @@ extern void aarch64_split_combinev16qi (rtx operands[3]);
 extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
 extern bool aarch64_madd_needs_nop (rtx_insn *);
 extern void aarch64_final_prescan_insn (rtx_insn *);
+extern void aarch64_reset_previous_fndecl (void);
+extern void aarch64_cpu_cpp_builtins (cpp_reader *);
+extern void aarch64_register_pragmas (void);
 extern bool
 aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
 bool aarch64_handle_option (struct gcc_options *, struct gcc_options *,
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 34cd986..3faf3c1 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7534,7 +7534,7 @@ aarch64_override_options_after_change_1 (struct gcc_options *opts)
     as all the other target-specific codegen decisions are
     derived from them.  */
 
-static void
+void
 aarch64_override_options_internal (struct gcc_options *opts)
 {
   aarch64_tune_flags = selected_tune->flags;
@@ -7932,6 +7932,12 @@ aarch64_option_print (FILE *file, int indent, struct cl_target_option *ptr)
 
 static GTY(()) tree aarch64_previous_fndecl;
 
+void
+aarch64_reset_previous_fndecl (void)
+{
+  aarch64_previous_fndecl = NULL;
+}
+
 /* Implement TARGET_SET_CURRENT_FUNCTION.  Unpack the codegen decisions
    like tuning and ISA features from the DECL_FUNCTION_SPECIFIC_TARGET
    of the function, if such exists.  This function may be called multiple
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 2c1b6ce..7c31376 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -23,83 +23,14 @@
 #define GCC_AARCH64_H
 
 /* Target CPU builtins.  */
-#define TARGET_CPU_CPP_BUILTINS()			\
-  do							\
-    {							\
-      builtin_define ("__aarch64__");                   \
-      builtin_define ("__ARM_64BIT_STATE");             \
-      builtin_define_with_int_value                     \
-        ("__ARM_ALIGN_MAX_PWR", 28);                    \
-      builtin_define_with_int_value                     \
-        ("__ARM_ALIGN_MAX_STACK_PWR", 16);              \
-      builtin_define_with_int_value                     \
-        ("__ARM_ARCH", aarch64_architecture_version);   \
-      builtin_define ("__ARM_ARCH_8A");                   \
-      builtin_define ("__ARM_ARCH_ISA_A64");            \
-      builtin_define_with_int_value                     \
-        ("__ARM_ARCH_PROFILE", 'A');                    \
-      builtin_define ("__ARM_FEATURE_CLZ");             \
-      builtin_define ("__ARM_FEATURE_IDIV");            \
-      builtin_define ("__ARM_FEATURE_UNALIGNED");       \
-      if (flag_unsafe_math_optimizations)               \
-        builtin_define ("__ARM_FP_FAST");               \
-      builtin_define ("__ARM_PCS_AAPCS64");             \
-      builtin_define_with_int_value                     \
-        ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8);  \
-      builtin_define_with_int_value                     \
-        ("__ARM_SIZEOF_MINIMAL_ENUM",                   \
-         flag_short_enums? 1 : 4);                      \
-      if (TARGET_BIG_END)				\
-        {                                               \
-          builtin_define ("__AARCH64EB__");             \
-          builtin_define ("__ARM_BIG_ENDIAN");          \
-        }                                               \
-      else						\
-	builtin_define ("__AARCH64EL__");		\
-							\
-      if (TARGET_FLOAT)                                         \
-        {                                                       \
-          builtin_define ("__ARM_FEATURE_FMA");                 \
-          builtin_define_with_int_value ("__ARM_FP", 0x0C);     \
-        }                                                       \
-      if (TARGET_SIMD)                                          \
-        {                                                       \
-          builtin_define ("__ARM_FEATURE_NUMERIC_MAXMIN");      \
-          builtin_define ("__ARM_NEON");			\
-          builtin_define_with_int_value ("__ARM_NEON_FP", 0x0C);\
-        }                                                       \
-							        \
-      if (TARGET_CRC32)				        \
-	builtin_define ("__ARM_FEATURE_CRC32");		\
-							\
-      switch (aarch64_cmodel)				\
-	{						\
-	  case AARCH64_CMODEL_TINY:			\
-	  case AARCH64_CMODEL_TINY_PIC:			\
-	    builtin_define ("__AARCH64_CMODEL_TINY__");	\
-	    break;					\
-	  case AARCH64_CMODEL_SMALL:			\
-	  case AARCH64_CMODEL_SMALL_PIC:		\
-	    builtin_define ("__AARCH64_CMODEL_SMALL__");\
-	    break;					\
-	  case AARCH64_CMODEL_LARGE:			\
-	    builtin_define ("__AARCH64_CMODEL_LARGE__");	\
-	    break;					\
-	  default:					\
-	    break;					\
-	}						\
-							\
-      if (TARGET_ILP32)					\
-	{						\
-	  cpp_define (parse_in, "_ILP32");		\
-	  cpp_define (parse_in, "__ILP32__");		\
-	}						\
-      if (TARGET_CRYPTO)				\
-	builtin_define ("__ARM_FEATURE_CRYPTO");	\
-    } while (0)
+
+#define TARGET_CPU_CPP_BUILTINS()	\
+  aarch64_cpu_cpp_builtins (pfile)
 
 \f
 
+#define REGISTER_TARGET_PRAGMAS() aarch64_register_pragmas ()
+
 /* Target machine storage layout.  */
 
 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)	\
diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
index 7af4ad2..f6b2c11 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -28,11 +28,16 @@
 #define _GCC_ARM_ACLE_H
 
 #include <stdint.h>
+
+#pragma GCC push_options
+/* Add +nofp to make sure that 'fp' is not required to compile these
+   intrinsics.  */
+#pragma GCC target("+crc+nofp")
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#ifdef __ARM_FEATURE_CRC32
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
 __crc32b (uint32_t __a, uint8_t __b)
 {
@@ -81,10 +86,10 @@ __crc32d (uint32_t __a, uint64_t __b)
   return __builtin_aarch64_crc32x (__a, __b);
 }
 
-#endif
-
 #ifdef __cplusplus
 }
 #endif
 
+#pragma GCC pop_options
+
 #endif
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index 114994e..1c29e2f 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -27,9 +27,8 @@
 #ifndef _AARCH64_NEON_H_
 #define _AARCH64_NEON_H_
 
-#ifndef __ARM_NEON
-#error You must enable AdvancedSIMD instructions to use arm_neon.h
-#else
+#pragma GCC push_options
+#pragma GCC target("arch=armv8-a+simd")
 
 #include <stdint.h>
 
@@ -11396,8 +11395,8 @@ vbslq_u64 (uint64x2_t __a, uint64x2_t __b, uint64x2_t __c)
   return __builtin_aarch64_simd_bslv2di_uuuu (__a, __b, __c);
 }
 
-#ifdef __ARM_FEATURE_CRYPTO
-
+#pragma GCC push_options
+#pragma GCC target("+crypto")
 /* vaes  */
 
 __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
@@ -11423,8 +11422,7 @@ vaesimcq_u8 (uint8x16_t data)
 {
   return __builtin_aarch64_crypto_aesimcv16qi_uu (data);
 }
-
-#endif
+#pragma GCC pop_options
 
 /* vcage  */
 
@@ -21049,7 +21047,8 @@ vrsrad_n_u64 (uint64_t __a, uint64_t __b, const int __c)
   return __builtin_aarch64_ursra_ndi_uuus (__a, __b, __c);
 }
 
-#ifdef __ARM_FEATURE_CRYPTO
+#pragma GCC push_options
+#pragma GCC target("+crypto")
 
 /* vsha1  */
 
@@ -21126,7 +21125,7 @@ vmull_high_p64 (poly64x2_t a, poly64x2_t b)
   return __builtin_aarch64_crypto_pmullv2di_ppp (a, b);
 }
 
-#endif
+#pragma GCC pop_options
 
 /* vshl */
 
@@ -24894,6 +24893,6 @@ __INTERLEAVE_LIST (zip)
 #undef __aarch64_vdupq_laneq_u32
 #undef __aarch64_vdupq_laneq_u64
 
-#endif
+#pragma GCC pop_options
 
 #endif
diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64
index af154f4..782853b 100644
--- a/gcc/config/aarch64/t-aarch64
+++ b/gcc/config/aarch64/t-aarch64
@@ -48,6 +48,11 @@ aarch-common.o: $(srcdir)/config/arm/aarch-common.c $(CONFIG_H) $(SYSTEM_H) \
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$(srcdir)/config/arm/aarch-common.c
 
+aarch64-c.o: $(srcdir)/config/aarch64/aarch64-c.c $(CONFIG_H) $(SYSTEM_H) \
+    coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+		$(srcdir)/config/aarch64/aarch64-c.c
+
 cortex-a57-fma-steering.o: $(srcdir)/config/aarch64/cortex-a57-fma-steering.c \
     $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(REGS_H) insn-config.h $(RTL_BASE_H) \
     dominance.h cfg.h cfganal.h $(BASIC_BLOCK_H) $(INSN_ATTR_H) $(RECOG_H) \
diff --git a/gcc/testsuite/gcc.target/aarch64/arm_neon-nosimd-error.c b/gcc/testsuite/gcc.target/aarch64/arm_neon-nosimd-error.c
deleted file mode 100644
index 6c508ec..0000000
--- a/gcc/testsuite/gcc.target/aarch64/arm_neon-nosimd-error.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mgeneral-regs-only" } */
-/* { dg-excess-errors "You must enable" } */
-
-#include "arm_neon.h"
-
-int
-foo ()
-{
-  return 0;
-}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH][AArch64][10/14] Implement target pragmas
  2015-07-16 15:25 [PATCH][AArch64][10/14] Implement target pragmas Kyrill Tkachov
@ 2015-07-21 16:58 ` James Greenhalgh
  2015-07-24  8:40   ` Kyrill Tkachov
  0 siblings, 1 reply; 5+ messages in thread
From: James Greenhalgh @ 2015-07-21 16:58 UTC (permalink / raw)
  To: Kyrill Tkachov; +Cc: GCC Patches, Marcus Shawcroft, Richard Earnshaw

On Thu, Jul 16, 2015 at 04:21:05PM +0100, Kyrill Tkachov wrote:
> Hi all,
> 
> This patch implements target pragmas for aarch64.
> The pragmas accepted are the same as for target attributes (as required).
> In addition pragmas will need to redefine the target-specific preprocessor
> macros if appropriate.
> 
> A new file: aarch64-c.c is added and the code from TARGET_CPU_CPP_BUILTINS is moved there
> and split up into the unconditional parts that are always defined and the conditional stuff
> that depends on certain architectural features.  The pragma processing code calls that
> to redefine preprocessor macros on the fly.
> The implementation is similar to the rs6000 one.
> 
> With target pragmas implemented, we can use them in the arm_neon.h and arm_acle.h headers to
> specify the architectural features required for those intrinsics, rather than #ifdef'ing them
> out when FP/SIMD is not available from the command line.
> 
> We need to do this in order to handle cases where the user compiles a file with -mgeneral-regs-only
> but has a function tagged with +simd and tries to use the arm_neon.h intrinsics.
> Tests and documentation comes as a separate patch later on in the series
> 
> Bootstrapped and tested on aarch64.
> 
> Ok for trunk?

A couple of ChangeLog nits and some comments below.

> 
> 2015-07-16  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
> 
>      * config.gcc (aarch64*-*-*): Specify c_target_objs and cxx_target_objs.
>      * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS):

This should say 

>      * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS): New.

Presumably (or maybe "Define.").


>      (TARGET_CPU_CPP_BUILTINS): Redefine to call aarch64_cpu_cpp_builtins.
>      * config/aarch64/aarch64.c (aarch64_override_options_internal): Remove
>      static keyword.
>      (aarch64_reset_previous_fndecl): New function.
>      * config/aarch64/aarch64-c.c: New file.
>      * config/aarch64/arm_acle.h: Add pragma +crc+nofp at the top.
>      Push and pop options at beginning and end.  Remove ifdef
>      __ARM_FEATURE_CRC32.
>      * config/aarch64/arm_neon.h: Remove #ifdef check on __ARM_NEON.
>      Add pragma arch=armv8-a+simd and +crypto where appropriate.
>      * config/aarch64/t-aarch64 (aarch64-c.o): New rule.

I don't see a ChangeLog entry for these hunks:

> diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
> index 3a5482d..4704736 100644
> --- a/gcc/config/aarch64/aarch64-protos.h
> +++ b/gcc/config/aarch64/aarch64-protos.h
> @@ -360,6 +360,10 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, enum machine_mode, RTX_CODE);
>  #endif /* RTX_CODE */
>  
>  void aarch64_init_builtins (void);
> +
> +bool aarch64_process_target_attr (tree, const char*);
> +void aarch64_override_options_internal (struct gcc_options *);
> +
>  rtx aarch64_expand_builtin (tree exp,
>  			    rtx target,
>  			    rtx subtarget ATTRIBUTE_UNUSED,
> @@ -376,6 +380,9 @@ extern void aarch64_split_combinev16qi (rtx operands[3]);
>  extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
>  extern bool aarch64_madd_needs_nop (rtx_insn *);
>  extern void aarch64_final_prescan_insn (rtx_insn *);
> +extern void aarch64_reset_previous_fndecl (void);
> +extern void aarch64_cpu_cpp_builtins (cpp_reader *);
> +extern void aarch64_register_pragmas (void);
>  extern bool
>  aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
>  bool aarch64_handle_option (struct gcc_options *, struct gcc_options *,




> +static bool
> +aarch64_pragma_target_parse (tree args, tree pop_target)
> +{
> +
> +  bool ret;
> +
> +  /* If args is not NULL then process it and setup the target-specific
> +     information that it specifies.  */
> +  if (args)
> +    {
> +      ret = aarch64_process_target_attr (args, "pragma");
> +      if (ret)
> +	aarch64_override_options_internal (&global_options);

RET must equal true.

> +      else
> +	return false;

Early return of false closes the other control path here.

> +    }
> +
> +  /* args is NULL, restore to the state described in pop_target.  */
> +  else
> +    {
> +      pop_target = pop_target ? pop_target : target_option_default_node;
> +      cl_target_option_restore (&global_options,
> +				TREE_TARGET_OPTION (pop_target));
> +      ret = true;
> +    }

Therefore RET must equal true here.

> +
> +  target_option_current_node
> +    = build_target_option_node (&global_options);
> +
> +  aarch64_reset_previous_fndecl ();
> +  /* 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;
> +
> +  aarch64_update_cpp_builtins (parse_in);
> +
> +  cpp_opts->warn_unused_macros = saved_warn_unused_macros;
> +
> +  return ret;

So we don't need "RET" !

> +}
> +
> +/* Implement REGISTER_TARGET_PRAGMAS.  */
> +
> +void
> +aarch64_register_pragmas (void)
> +{
> +  /* Update pragma hook to allow parsing #pragma GCC target.  */
> +  targetm.target_option.pragma_parse = aarch64_pragma_target_parse;
> +}
> \ No newline at end of file

I can't remember if GNU style mandates it, but in my opinion your new
file should have a trailing newline.

> diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
> index 3a5482d..4704736 100644
> --- a/gcc/config/aarch64/aarch64-protos.h
> +++ b/gcc/config/aarch64/aarch64-protos.h
> @@ -360,6 +360,10 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, enum machine_mode, RTX_CODE);
>  #endif /* RTX_CODE */
>  
>  void aarch64_init_builtins (void);
> +
> +bool aarch64_process_target_attr (tree, const char*);
> +void aarch64_override_options_internal (struct gcc_options *);
> +
>  rtx aarch64_expand_builtin (tree exp,
>  			    rtx target,
>  			    rtx subtarget ATTRIBUTE_UNUSED,
> @@ -376,6 +380,9 @@ extern void aarch64_split_combinev16qi (rtx operands[3]);
>  extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
>  extern bool aarch64_madd_needs_nop (rtx_insn *);
>  extern void aarch64_final_prescan_insn (rtx_insn *);
> +extern void aarch64_reset_previous_fndecl (void);
> +extern void aarch64_cpu_cpp_builtins (cpp_reader *);
> +extern void aarch64_register_pragmas (void);

At one point aarch64-protos.h was in alphabetical order. While we have
a number of mistakes already, we should try not to make the situation
worse!

> diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
> index 7af4ad2..f6b2c11 100644
> --- a/gcc/config/aarch64/arm_acle.h
> +++ b/gcc/config/aarch64/arm_acle.h
> @@ -28,11 +28,16 @@
>  #define _GCC_ARM_ACLE_H
>  
>  #include <stdint.h>
> +
> +#pragma GCC push_options
> +/* Add +nofp to make sure that 'fp' is not required to compile these
> +   intrinsics.  */
> +#pragma GCC target("+crc+nofp")

Hm, how does this work with the ARMv8.1 Extensions added by Matthew
Wahab recently? Presumably this needs to expand to have a "+no" for
all possible extensions. This seems messy, it might be neater to
implement something like +nothing which resets the state of the extension
features bitmask to zero.

> +
>  #ifdef __cplusplus
>  extern "C" {
>  #endif
>  
> -#ifdef __ARM_FEATURE_CRC32
>  __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
>  __crc32b (uint32_t __a, uint8_t __b)
>  {
> @@ -81,10 +86,10 @@ __crc32d (uint32_t __a, uint64_t __b)
>    return __builtin_aarch64_crc32x (__a, __b);
>  }
>  
> -#endif
> -
>  #ifdef __cplusplus
>  }
>  #endif
>  
> +#pragma GCC pop_options
> +
>  #endif

Thanks,
James

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH][AArch64][10/14] Implement target pragmas
  2015-07-21 16:58 ` James Greenhalgh
@ 2015-07-24  8:40   ` Kyrill Tkachov
  2015-08-03  9:36     ` Kyrill Tkachov
  0 siblings, 1 reply; 5+ messages in thread
From: Kyrill Tkachov @ 2015-07-24  8:40 UTC (permalink / raw)
  To: James Greenhalgh; +Cc: GCC Patches, Marcus Shawcroft, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 9860 bytes --]


On 21/07/15 17:52, James Greenhalgh wrote:
> On Thu, Jul 16, 2015 at 04:21:05PM +0100, Kyrill Tkachov wrote:
>> Hi all,
>>
>> This patch implements target pragmas for aarch64.
>> The pragmas accepted are the same as for target attributes (as required).
>> In addition pragmas will need to redefine the target-specific preprocessor
>> macros if appropriate.
>>
>> A new file: aarch64-c.c is added and the code from TARGET_CPU_CPP_BUILTINS is moved there
>> and split up into the unconditional parts that are always defined and the conditional stuff
>> that depends on certain architectural features.  The pragma processing code calls that
>> to redefine preprocessor macros on the fly.
>> The implementation is similar to the rs6000 one.
>>
>> With target pragmas implemented, we can use them in the arm_neon.h and arm_acle.h headers to
>> specify the architectural features required for those intrinsics, rather than #ifdef'ing them
>> out when FP/SIMD is not available from the command line.
>>
>> We need to do this in order to handle cases where the user compiles a file with -mgeneral-regs-only
>> but has a function tagged with +simd and tries to use the arm_neon.h intrinsics.
>> Tests and documentation comes as a separate patch later on in the series
>>
>> Bootstrapped and tested on aarch64.
>>
>> Ok for trunk?
> A couple of ChangeLog nits and some comments below.
>
>> 2015-07-16  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>
>>       * config.gcc (aarch64*-*-*): Specify c_target_objs and cxx_target_objs.
>>       * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS):
> This should say
>
>>       * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS): New.
> Presumably (or maybe "Define.").
>
>
>>       (TARGET_CPU_CPP_BUILTINS): Redefine to call aarch64_cpu_cpp_builtins.
>>       * config/aarch64/aarch64.c (aarch64_override_options_internal): Remove
>>       static keyword.
>>       (aarch64_reset_previous_fndecl): New function.
>>       * config/aarch64/aarch64-c.c: New file.
>>       * config/aarch64/arm_acle.h: Add pragma +crc+nofp at the top.
>>       Push and pop options at beginning and end.  Remove ifdef
>>       __ARM_FEATURE_CRC32.
>>       * config/aarch64/arm_neon.h: Remove #ifdef check on __ARM_NEON.
>>       Add pragma arch=armv8-a+simd and +crypto where appropriate.
>>       * config/aarch64/t-aarch64 (aarch64-c.o): New rule.
> I don't see a ChangeLog entry for these hunks:
>
>> diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
>> index 3a5482d..4704736 100644
>> --- a/gcc/config/aarch64/aarch64-protos.h
>> +++ b/gcc/config/aarch64/aarch64-protos.h
>> @@ -360,6 +360,10 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, enum machine_mode, RTX_CODE);
>>   #endif /* RTX_CODE */
>>   
>>   void aarch64_init_builtins (void);
>> +
>> +bool aarch64_process_target_attr (tree, const char*);
>> +void aarch64_override_options_internal (struct gcc_options *);
>> +
>>   rtx aarch64_expand_builtin (tree exp,
>>   			    rtx target,
>>   			    rtx subtarget ATTRIBUTE_UNUSED,
>> @@ -376,6 +380,9 @@ extern void aarch64_split_combinev16qi (rtx operands[3]);
>>   extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
>>   extern bool aarch64_madd_needs_nop (rtx_insn *);
>>   extern void aarch64_final_prescan_insn (rtx_insn *);
>> +extern void aarch64_reset_previous_fndecl (void);
>> +extern void aarch64_cpu_cpp_builtins (cpp_reader *);
>> +extern void aarch64_register_pragmas (void);
>>   extern bool
>>   aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
>>   bool aarch64_handle_option (struct gcc_options *, struct gcc_options *,
>
>
>
>> +static bool
>> +aarch64_pragma_target_parse (tree args, tree pop_target)
>> +{
>> +
>> +  bool ret;
>> +
>> +  /* If args is not NULL then process it and setup the target-specific
>> +     information that it specifies.  */
>> +  if (args)
>> +    {
>> +      ret = aarch64_process_target_attr (args, "pragma");
>> +      if (ret)
>> +	aarch64_override_options_internal (&global_options);
> RET must equal true.
>
>> +      else
>> +	return false;
> Early return of false closes the other control path here.
>
>> +    }
>> +
>> +  /* args is NULL, restore to the state described in pop_target.  */
>> +  else
>> +    {
>> +      pop_target = pop_target ? pop_target : target_option_default_node;
>> +      cl_target_option_restore (&global_options,
>> +				TREE_TARGET_OPTION (pop_target));
>> +      ret = true;
>> +    }
> Therefore RET must equal true here.
>
>> +
>> +  target_option_current_node
>> +    = build_target_option_node (&global_options);
>> +
>> +  aarch64_reset_previous_fndecl ();
>> +  /* 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;
>> +
>> +  aarch64_update_cpp_builtins (parse_in);
>> +
>> +  cpp_opts->warn_unused_macros = saved_warn_unused_macros;
>> +
>> +  return ret;
> So we don't need "RET" !
>
>> +}
>> +
>> +/* Implement REGISTER_TARGET_PRAGMAS.  */
>> +
>> +void
>> +aarch64_register_pragmas (void)
>> +{
>> +  /* Update pragma hook to allow parsing #pragma GCC target.  */
>> +  targetm.target_option.pragma_parse = aarch64_pragma_target_parse;
>> +}
>> \ No newline at end of file
> I can't remember if GNU style mandates it, but in my opinion your new
> file should have a trailing newline.
>
>> diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
>> index 3a5482d..4704736 100644
>> --- a/gcc/config/aarch64/aarch64-protos.h
>> +++ b/gcc/config/aarch64/aarch64-protos.h
>> @@ -360,6 +360,10 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, enum machine_mode, RTX_CODE);
>>   #endif /* RTX_CODE */
>>   
>>   void aarch64_init_builtins (void);
>> +
>> +bool aarch64_process_target_attr (tree, const char*);
>> +void aarch64_override_options_internal (struct gcc_options *);
>> +
>>   rtx aarch64_expand_builtin (tree exp,
>>   			    rtx target,
>>   			    rtx subtarget ATTRIBUTE_UNUSED,
>> @@ -376,6 +380,9 @@ extern void aarch64_split_combinev16qi (rtx operands[3]);
>>   extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
>>   extern bool aarch64_madd_needs_nop (rtx_insn *);
>>   extern void aarch64_final_prescan_insn (rtx_insn *);
>> +extern void aarch64_reset_previous_fndecl (void);
>> +extern void aarch64_cpu_cpp_builtins (cpp_reader *);
>> +extern void aarch64_register_pragmas (void);
> At one point aarch64-protos.h was in alphabetical order. While we have
> a number of mistakes already, we should try not to make the situation
> worse!
>
>> diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
>> index 7af4ad2..f6b2c11 100644
>> --- a/gcc/config/aarch64/arm_acle.h
>> +++ b/gcc/config/aarch64/arm_acle.h
>> @@ -28,11 +28,16 @@
>>   #define _GCC_ARM_ACLE_H
>>   
>>   #include <stdint.h>
>> +
>> +#pragma GCC push_options
>> +/* Add +nofp to make sure that 'fp' is not required to compile these
>> +   intrinsics.  */
>> +#pragma GCC target("+crc+nofp")
> Hm, how does this work with the ARMv8.1 Extensions added by Matthew
> Wahab recently? Presumably this needs to expand to have a "+no" for
> all possible extensions. This seems messy, it might be neater to
> implement something like +nothing which resets the state of the extension
> features bitmask to zero.

Thanks, I've implemented the "+nothing" architectural feature modifier
that can appear only in target attributes and pragmas like so:
#pragma GCC target ("+nothing+crc") where the +nothing clears out aarch64_isa_flags,
allowing the rest of the string to enable features one by one.

Also fixed the other issues you pointed.

How's this?

Thanks,
Kyrill

2015-07-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * config.gcc (aarch64*-*-*): Specify c_target_objs and cxx_target_objs.
     * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS): Define.
     (TARGET_CPU_CPP_BUILTINS): Redefine to call aarch64_cpu_cpp_builtins.
     * config/aarch64/aarch64.c (aarch64_override_options_internal): Remove
     static keyword.
     (aarch64_reset_previous_fndecl): New function.
     (aarch64_handle_attr_isa_flags): Handle "+nothing" in the beginning of
     the string.
     * config/aarch64/aarch64-c.c: New file.
     * config/aarch64/arm_acle.h: Add pragma +crc+nofp at the top.
     Push and pop options at beginning and end.  Remove ifdef
     __ARM_FEATURE_CRC32.
     * config/aarch64/arm_neon.h: Remove #ifdef check on __ARM_NEON.
     Add pragma arch=armv8-a+simd and +crypto where appropriate.
     * config/aarch64/t-aarch64 (aarch64-c.o): New rule.
     * config/aarch64/aarch64-protos.h (aarch64_cpu_cpp_builtins):
     Define prototype.
     (aarch64_register_pragmas): Likewise.
     (aarch64_reset_previous_fndecl): Likewise.
     (aarch64_process_target_attr): Likewise.
     (aarch64_override_options_internal): Likewise.


>
>> +
>>   #ifdef __cplusplus
>>   extern "C" {
>>   #endif
>>   
>> -#ifdef __ARM_FEATURE_CRC32
>>   __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
>>   __crc32b (uint32_t __a, uint8_t __b)
>>   {
>> @@ -81,10 +86,10 @@ __crc32d (uint32_t __a, uint64_t __b)
>>     return __builtin_aarch64_crc32x (__a, __b);
>>   }
>>   
>> -#endif
>> -
>>   #ifdef __cplusplus
>>   }
>>   #endif
>>   
>> +#pragma GCC pop_options
>> +
>>   #endif
> Thanks,
> James
>


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: aarch64-attrs-10.patch --]
[-- Type: text/x-patch; name=aarch64-attrs-10.patch, Size: 17392 bytes --]

commit 3083294b65ff7415d09af3fb2c7a30bb96133b13
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date:   Thu May 14 15:36:07 2015 +0100

    [AArch64][10/N] Implement target pragmas

diff --git a/gcc/config.gcc b/gcc/config.gcc
index d6b928d..24f6d35 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -302,6 +302,8 @@ m32c*-*-*)
 aarch64*-*-*)
 	cpu_type=aarch64
 	extra_headers="arm_neon.h arm_acle.h"
+	c_target_objs="aarch64-c.o"
+	cxx_target_objs="aarch64-c.o"
 	extra_objs="aarch64-builtins.o aarch-common.o cortex-a57-fma-steering.o"
 	target_gtfiles="\$(srcdir)/config/aarch64/aarch64-builtins.c"
 	target_has_targetm_common=yes
diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c
new file mode 100644
index 0000000..e5e8a1f
--- /dev/null
+++ b/gcc/config/aarch64/aarch64-c.c
@@ -0,0 +1,187 @@
+/* Target-specific code for C family languages.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "input.h"
+#include "tm_p.h"
+#include "flags.h"
+#include "c-family/c-common.h"
+#include "cpplib.h"
+#include "c-family/c-pragma.h"
+#include "langhooks.h"
+#include "target.h"
+
+
+#define builtin_define(TXT) cpp_define (pfile, TXT)
+#define builtin_assert(TXT) cpp_assert (pfile, TXT)
+
+
+static void
+aarch64_def_or_undef (bool def_p, const char *macro, cpp_reader *pfile)
+{
+  if (def_p)
+    cpp_define (pfile, macro);
+  else
+    cpp_undef (pfile, macro);
+}
+
+/* Define the macros that we always expect to have on AArch64.  */
+
+static void
+aarch64_define_unconditional_macros (cpp_reader *pfile)
+{
+  builtin_define ("__aarch64__");
+  builtin_define ("__ARM_64BIT_STATE");
+
+  builtin_define ("__ARM_ARCH_ISA_A64");
+  builtin_define_with_int_value ("__ARM_ALIGN_MAX_PWR", 28);
+  builtin_define_with_int_value ("__ARM_ALIGN_MAX_STACK_PWR", 16);
+
+  /* __ARM_ARCH_8A is not mandated by ACLE but we define it unconditionally
+     as interoperability with the same arm macro.  */
+  builtin_define ("__ARM_ARCH_8A");
+
+  builtin_define_with_int_value ("__ARM_ARCH_PROFILE", 'A');
+  builtin_define ("__ARM_FEATURE_CLZ");
+  builtin_define ("__ARM_FEATURE_IDIV");
+  builtin_define ("__ARM_FEATURE_UNALIGNED");
+  builtin_define ("__ARM_PCS_AAPCS64");
+  builtin_define_with_int_value ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8);
+
+}
+
+/* Undefine/redefine macros that depend on the current backend state and may
+   need to change when a target pragma modifies the backend state.  */
+
+static void
+aarch64_update_cpp_builtins (cpp_reader *pfile)
+{
+  aarch64_def_or_undef (flag_unsafe_math_optimizations, "__ARM_FP_FAST", pfile);
+
+  builtin_define_with_int_value ("__ARM_ARCH", aarch64_architecture_version);
+
+  builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
+				 flag_short_enums ? 1 : 4);
+  aarch64_def_or_undef (TARGET_BIG_END, "__AARCH64EB__", pfile);
+  aarch64_def_or_undef (TARGET_BIG_END, "__ARM_BIG_ENDIAN", pfile);
+  aarch64_def_or_undef (!TARGET_BIG_END, "__AARCH64EL__", pfile);
+
+  aarch64_def_or_undef (TARGET_FLOAT, "__ARM_FEATURE_FMA", pfile);
+
+  if (TARGET_FLOAT || TARGET_SIMD)
+    builtin_define_with_int_value ("__ARM_FP", 0x0C);
+  else
+    cpp_undef (pfile, "__ARM_FP");
+
+  aarch64_def_or_undef (TARGET_SIMD, "__ARM_FEATURE_NUMERIC_MAXMIN", pfile);
+  aarch64_def_or_undef (TARGET_SIMD, "__ARM_NEON", pfile);
+
+
+  aarch64_def_or_undef (TARGET_CRC32, "__ARM_FEATURE_CRC32", pfile);
+
+  cpp_undef (pfile, "__AARCH64_CMODEL_TINY__");
+  cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__");
+  cpp_undef (pfile, "__AARCH64_CMODEL_LARGE__");
+
+  switch (aarch64_cmodel)
+    {
+      case AARCH64_CMODEL_TINY:
+      case AARCH64_CMODEL_TINY_PIC:
+	builtin_define ("__AARCH64_CMODEL_TINY__");
+	break;
+      case AARCH64_CMODEL_SMALL:
+      case AARCH64_CMODEL_SMALL_PIC:
+	builtin_define ("__AARCH64_CMODEL_SMALL__");
+	break;
+      case AARCH64_CMODEL_LARGE:
+	builtin_define ("__AARCH64_CMODEL_LARGE__");
+	break;
+      default:
+	break;
+    }
+
+  aarch64_def_or_undef (TARGET_ILP32, "_ILP32", pfile);
+  aarch64_def_or_undef (TARGET_ILP32, "__ILP32__", pfile);
+
+  aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile);
+}
+
+/* Implement TARGET_CPU_CPP_BUILTINS.  */
+
+void
+aarch64_cpu_cpp_builtins (cpp_reader *pfile)
+{
+  aarch64_define_unconditional_macros (pfile);
+  aarch64_update_cpp_builtins (pfile);
+}
+
+/* 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
+aarch64_pragma_target_parse (tree args, tree pop_target)
+{
+  /* If args is not NULL then process it and setup the target-specific
+     information that it specifies.  */
+  if (args)
+    {
+      if (!aarch64_process_target_attr (args, "pragma"))
+	return false;
+
+      aarch64_override_options_internal (&global_options);
+    }
+
+  /* args is NULL, restore to the state described in pop_target.  */
+  else
+    {
+      pop_target = pop_target ? pop_target : target_option_default_node;
+      cl_target_option_restore (&global_options,
+				TREE_TARGET_OPTION (pop_target));
+    }
+
+  target_option_current_node
+    = build_target_option_node (&global_options);
+
+  aarch64_reset_previous_fndecl ();
+  /* 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;
+
+  aarch64_update_cpp_builtins (parse_in);
+
+  cpp_opts->warn_unused_macros = saved_warn_unused_macros;
+
+  return true;
+}
+
+/* Implement REGISTER_TARGET_PRAGMAS.  */
+
+void
+aarch64_register_pragmas (void)
+{
+  /* Update pragma hook to allow parsing #pragma GCC target.  */
+  targetm.target_option.pragma_parse = aarch64_pragma_target_parse;
+}
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 3a5482d..6844c90 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -249,6 +249,7 @@ enum aarch64_symbol_type
 aarch64_classify_symbolic_expression (rtx, enum aarch64_symbol_context);
 bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
 bool aarch64_constant_address_p (rtx);
+extern void aarch64_cpu_cpp_builtins (cpp_reader *);
 bool aarch64_expand_movmem (rtx *);
 bool aarch64_float_const_zero_rtx_p (rtx);
 bool aarch64_function_arg_regno_p (unsigned);
@@ -323,6 +324,8 @@ void aarch64_init_expanders (void);
 void aarch64_print_operand (FILE *, rtx, char);
 void aarch64_print_operand_address (FILE *, rtx);
 void aarch64_emit_call_insn (rtx);
+void aarch64_register_pragmas (void);
+void aarch64_reset_previous_fndecl (void);
 
 /* Initialize builtins for SIMD intrinsics.  */
 void init_aarch64_simd_builtins (void);
@@ -360,6 +363,10 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, enum machine_mode, RTX_CODE);
 #endif /* RTX_CODE */
 
 void aarch64_init_builtins (void);
+
+bool aarch64_process_target_attr (tree, const char*);
+void aarch64_override_options_internal (struct gcc_options *);
+
 rtx aarch64_expand_builtin (tree exp,
 			    rtx target,
 			    rtx subtarget ATTRIBUTE_UNUSED,
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b182975..62cf9a2 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7528,7 +7528,7 @@ aarch64_override_options_after_change_1 (struct gcc_options *opts)
     as all the other target-specific codegen decisions are
     derived from them.  */
 
-static void
+void
 aarch64_override_options_internal (struct gcc_options *opts)
 {
   aarch64_tune_flags = selected_tune->flags;
@@ -7919,6 +7919,12 @@ aarch64_option_print (FILE *file, int indent, struct cl_target_option *ptr)
 
 static GTY(()) tree aarch64_previous_fndecl;
 
+void
+aarch64_reset_previous_fndecl (void)
+{
+  aarch64_previous_fndecl = NULL;
+}
+
 /* Implement TARGET_SET_CURRENT_FUNCTION.  Unpack the codegen decisions
    like tuning and ISA features from the DECL_FUNCTION_SPECIFIC_TARGET
    of the function, if such exists.  This function may be called multiple
@@ -8122,6 +8128,14 @@ aarch64_handle_attr_isa_flags (char *str, const char *pragma_or_attr)
   enum aarch64_parse_opt_result parse_res;
   unsigned long isa_flags = aarch64_isa_flags;
 
+  /* We allow "+nothing" in the beginning to clear out all architectural
+     features if the user wants to handpick specific features.  */
+  if (strncmp ("+nothing", str, 8) == 0)
+    {
+      isa_flags = 0;
+      str += 8;
+    }
+
   parse_res = aarch64_parse_extension (str, &isa_flags);
 
   if (parse_res == AARCH64_PARSE_OK)
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 16bc178..5dd974d 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -23,83 +23,14 @@
 #define GCC_AARCH64_H
 
 /* Target CPU builtins.  */
-#define TARGET_CPU_CPP_BUILTINS()			\
-  do							\
-    {							\
-      builtin_define ("__aarch64__");                   \
-      builtin_define ("__ARM_64BIT_STATE");             \
-      builtin_define_with_int_value                     \
-        ("__ARM_ALIGN_MAX_PWR", 28);                    \
-      builtin_define_with_int_value                     \
-        ("__ARM_ALIGN_MAX_STACK_PWR", 16);              \
-      builtin_define_with_int_value                     \
-        ("__ARM_ARCH", aarch64_architecture_version);   \
-      builtin_define ("__ARM_ARCH_8A");                   \
-      builtin_define ("__ARM_ARCH_ISA_A64");            \
-      builtin_define_with_int_value                     \
-        ("__ARM_ARCH_PROFILE", 'A');                    \
-      builtin_define ("__ARM_FEATURE_CLZ");             \
-      builtin_define ("__ARM_FEATURE_IDIV");            \
-      builtin_define ("__ARM_FEATURE_UNALIGNED");       \
-      if (flag_unsafe_math_optimizations)               \
-        builtin_define ("__ARM_FP_FAST");               \
-      builtin_define ("__ARM_PCS_AAPCS64");             \
-      builtin_define_with_int_value                     \
-        ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8);  \
-      builtin_define_with_int_value                     \
-        ("__ARM_SIZEOF_MINIMAL_ENUM",                   \
-         flag_short_enums? 1 : 4);                      \
-      if (TARGET_BIG_END)				\
-        {                                               \
-          builtin_define ("__AARCH64EB__");             \
-          builtin_define ("__ARM_BIG_ENDIAN");          \
-        }                                               \
-      else						\
-	builtin_define ("__AARCH64EL__");		\
-							\
-      if (TARGET_FLOAT)                                         \
-        {                                                       \
-          builtin_define ("__ARM_FEATURE_FMA");                 \
-          builtin_define_with_int_value ("__ARM_FP", 0x0C);     \
-        }                                                       \
-      if (TARGET_SIMD)                                          \
-        {                                                       \
-          builtin_define ("__ARM_FEATURE_NUMERIC_MAXMIN");      \
-          builtin_define ("__ARM_NEON");			\
-          builtin_define_with_int_value ("__ARM_NEON_FP", 0x0C);\
-        }                                                       \
-							        \
-      if (TARGET_CRC32)				        \
-	builtin_define ("__ARM_FEATURE_CRC32");		\
-							\
-      switch (aarch64_cmodel)				\
-	{						\
-	  case AARCH64_CMODEL_TINY:			\
-	  case AARCH64_CMODEL_TINY_PIC:			\
-	    builtin_define ("__AARCH64_CMODEL_TINY__");	\
-	    break;					\
-	  case AARCH64_CMODEL_SMALL:			\
-	  case AARCH64_CMODEL_SMALL_PIC:		\
-	    builtin_define ("__AARCH64_CMODEL_SMALL__");\
-	    break;					\
-	  case AARCH64_CMODEL_LARGE:			\
-	    builtin_define ("__AARCH64_CMODEL_LARGE__");	\
-	    break;					\
-	  default:					\
-	    break;					\
-	}						\
-							\
-      if (TARGET_ILP32)					\
-	{						\
-	  cpp_define (parse_in, "_ILP32");		\
-	  cpp_define (parse_in, "__ILP32__");		\
-	}						\
-      if (TARGET_CRYPTO)				\
-	builtin_define ("__ARM_FEATURE_CRYPTO");	\
-    } while (0)
+
+#define TARGET_CPU_CPP_BUILTINS()	\
+  aarch64_cpu_cpp_builtins (pfile)
 
 \f
 
+#define REGISTER_TARGET_PRAGMAS() aarch64_register_pragmas ()
+
 /* Target machine storage layout.  */
 
 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)	\
diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
index 7af4ad2..addbc6a 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -28,11 +28,15 @@
 #define _GCC_ARM_ACLE_H
 
 #include <stdint.h>
+
+#pragma GCC push_options
+
+#pragma GCC target ("+nothing+crc")
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#ifdef __ARM_FEATURE_CRC32
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
 __crc32b (uint32_t __a, uint8_t __b)
 {
@@ -81,10 +85,10 @@ __crc32d (uint32_t __a, uint64_t __b)
   return __builtin_aarch64_crc32x (__a, __b);
 }
 
-#endif
-
 #ifdef __cplusplus
 }
 #endif
 
+#pragma GCC pop_options
+
 #endif
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index fce5577..f5d183f 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -27,9 +27,8 @@
 #ifndef _AARCH64_NEON_H_
 #define _AARCH64_NEON_H_
 
-#ifndef __ARM_NEON
-#error You must enable AdvancedSIMD instructions to use arm_neon.h
-#else
+#pragma GCC push_options
+#pragma GCC target ("+nothing+simd")
 
 #include <stdint.h>
 
@@ -11414,8 +11413,8 @@ vbslq_u64 (uint64x2_t __a, uint64x2_t __b, uint64x2_t __c)
   return __builtin_aarch64_simd_bslv2di_uuuu (__a, __b, __c);
 }
 
-#ifdef __ARM_FEATURE_CRYPTO
-
+#pragma GCC push_options
+#pragma GCC target ("+crypto")
 /* vaes  */
 
 __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
@@ -11441,8 +11440,7 @@ vaesimcq_u8 (uint8x16_t data)
 {
   return __builtin_aarch64_crypto_aesimcv16qi_uu (data);
 }
-
-#endif
+#pragma GCC pop_options
 
 /* vcage  */
 
@@ -21067,7 +21065,8 @@ vrsrad_n_u64 (uint64_t __a, uint64_t __b, const int __c)
   return __builtin_aarch64_ursra_ndi_uuus (__a, __b, __c);
 }
 
-#ifdef __ARM_FEATURE_CRYPTO
+#pragma GCC push_options
+#pragma GCC target ("+crypto")
 
 /* vsha1  */
 
@@ -21144,7 +21143,7 @@ vmull_high_p64 (poly64x2_t a, poly64x2_t b)
   return __builtin_aarch64_crypto_pmullv2di_ppp (a, b);
 }
 
-#endif
+#pragma GCC pop_options
 
 /* vshl */
 
@@ -24912,6 +24911,6 @@ __INTERLEAVE_LIST (zip)
 #undef __aarch64_vdupq_laneq_u32
 #undef __aarch64_vdupq_laneq_u64
 
-#endif
+#pragma GCC pop_options
 
 #endif
diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64
index af154f4..782853b 100644
--- a/gcc/config/aarch64/t-aarch64
+++ b/gcc/config/aarch64/t-aarch64
@@ -48,6 +48,11 @@ aarch-common.o: $(srcdir)/config/arm/aarch-common.c $(CONFIG_H) $(SYSTEM_H) \
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$(srcdir)/config/arm/aarch-common.c
 
+aarch64-c.o: $(srcdir)/config/aarch64/aarch64-c.c $(CONFIG_H) $(SYSTEM_H) \
+    coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+		$(srcdir)/config/aarch64/aarch64-c.c
+
 cortex-a57-fma-steering.o: $(srcdir)/config/aarch64/cortex-a57-fma-steering.c \
     $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(REGS_H) insn-config.h $(RTL_BASE_H) \
     dominance.h cfg.h cfganal.h $(BASIC_BLOCK_H) $(INSN_ATTR_H) $(RECOG_H) \
diff --git a/gcc/testsuite/gcc.target/aarch64/arm_neon-nosimd-error.c b/gcc/testsuite/gcc.target/aarch64/arm_neon-nosimd-error.c
deleted file mode 100644
index 6c508ec..0000000
--- a/gcc/testsuite/gcc.target/aarch64/arm_neon-nosimd-error.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mgeneral-regs-only" } */
-/* { dg-excess-errors "You must enable" } */
-
-#include "arm_neon.h"
-
-int
-foo ()
-{
-  return 0;
-}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH][AArch64][10/14] Implement target pragmas
  2015-07-24  8:40   ` Kyrill Tkachov
@ 2015-08-03  9:36     ` Kyrill Tkachov
  2015-08-03 11:18       ` James Greenhalgh
  0 siblings, 1 reply; 5+ messages in thread
From: Kyrill Tkachov @ 2015-08-03  9:36 UTC (permalink / raw)
  To: James Greenhalgh; +Cc: GCC Patches, Marcus Shawcroft, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 11773 bytes --]


On 24/07/15 09:36, Kyrill Tkachov wrote:
> On 21/07/15 17:52, James Greenhalgh wrote:
>> On Thu, Jul 16, 2015 at 04:21:05PM +0100, Kyrill Tkachov wrote:
>>> Hi all,
>>>
>>> This patch implements target pragmas for aarch64.
>>> The pragmas accepted are the same as for target attributes (as required).
>>> In addition pragmas will need to redefine the target-specific preprocessor
>>> macros if appropriate.
>>>
>>> A new file: aarch64-c.c is added and the code from TARGET_CPU_CPP_BUILTINS is moved there
>>> and split up into the unconditional parts that are always defined and the conditional stuff
>>> that depends on certain architectural features.  The pragma processing code calls that
>>> to redefine preprocessor macros on the fly.
>>> The implementation is similar to the rs6000 one.
>>>
>>> With target pragmas implemented, we can use them in the arm_neon.h and arm_acle.h headers to
>>> specify the architectural features required for those intrinsics, rather than #ifdef'ing them
>>> out when FP/SIMD is not available from the command line.
>>>
>>> We need to do this in order to handle cases where the user compiles a file with -mgeneral-regs-only
>>> but has a function tagged with +simd and tries to use the arm_neon.h intrinsics.
>>> Tests and documentation comes as a separate patch later on in the series
>>>
>>> Bootstrapped and tested on aarch64.
>>>
>>> Ok for trunk?
>> A couple of ChangeLog nits and some comments below.
>>
>>> 2015-07-16  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>>
>>>        * config.gcc (aarch64*-*-*): Specify c_target_objs and cxx_target_objs.
>>>        * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS):
>> This should say
>>
>>>        * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS): New.
>> Presumably (or maybe "Define.").
>>
>>
>>>        (TARGET_CPU_CPP_BUILTINS): Redefine to call aarch64_cpu_cpp_builtins.
>>>        * config/aarch64/aarch64.c (aarch64_override_options_internal): Remove
>>>        static keyword.
>>>        (aarch64_reset_previous_fndecl): New function.
>>>        * config/aarch64/aarch64-c.c: New file.
>>>        * config/aarch64/arm_acle.h: Add pragma +crc+nofp at the top.
>>>        Push and pop options at beginning and end.  Remove ifdef
>>>        __ARM_FEATURE_CRC32.
>>>        * config/aarch64/arm_neon.h: Remove #ifdef check on __ARM_NEON.
>>>        Add pragma arch=armv8-a+simd and +crypto where appropriate.
>>>        * config/aarch64/t-aarch64 (aarch64-c.o): New rule.
>> I don't see a ChangeLog entry for these hunks:
>>
>>> diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
>>> index 3a5482d..4704736 100644
>>> --- a/gcc/config/aarch64/aarch64-protos.h
>>> +++ b/gcc/config/aarch64/aarch64-protos.h
>>> @@ -360,6 +360,10 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, enum machine_mode, RTX_CODE);
>>>    #endif /* RTX_CODE */
>>>
>>>    void aarch64_init_builtins (void);
>>> +
>>> +bool aarch64_process_target_attr (tree, const char*);
>>> +void aarch64_override_options_internal (struct gcc_options *);
>>> +
>>>    rtx aarch64_expand_builtin (tree exp,
>>>                           rtx target,
>>>                           rtx subtarget ATTRIBUTE_UNUSED,
>>> @@ -376,6 +380,9 @@ extern void aarch64_split_combinev16qi (rtx operands[3]);
>>>    extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
>>>    extern bool aarch64_madd_needs_nop (rtx_insn *);
>>>    extern void aarch64_final_prescan_insn (rtx_insn *);
>>> +extern void aarch64_reset_previous_fndecl (void);
>>> +extern void aarch64_cpu_cpp_builtins (cpp_reader *);
>>> +extern void aarch64_register_pragmas (void);
>>>    extern bool
>>>    aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
>>>    bool aarch64_handle_option (struct gcc_options *, struct gcc_options *,
>>
>>
>>> +static bool
>>> +aarch64_pragma_target_parse (tree args, tree pop_target)
>>> +{
>>> +
>>> +  bool ret;
>>> +
>>> +  /* If args is not NULL then process it and setup the target-specific
>>> +     information that it specifies.  */
>>> +  if (args)
>>> +    {
>>> +      ret = aarch64_process_target_attr (args, "pragma");
>>> +      if (ret)
>>> +    aarch64_override_options_internal (&global_options);
>> RET must equal true.
>>
>>> +      else
>>> +    return false;
>> Early return of false closes the other control path here.
>>
>>> +    }
>>> +
>>> +  /* args is NULL, restore to the state described in pop_target.  */
>>> +  else
>>> +    {
>>> +      pop_target = pop_target ? pop_target : target_option_default_node;
>>> +      cl_target_option_restore (&global_options,
>>> +                            TREE_TARGET_OPTION (pop_target));
>>> +      ret = true;
>>> +    }
>> Therefore RET must equal true here.
>>
>>> +
>>> +  target_option_current_node
>>> +    = build_target_option_node (&global_options);
>>> +
>>> +  aarch64_reset_previous_fndecl ();
>>> +  /* 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;
>>> +
>>> +  aarch64_update_cpp_builtins (parse_in);
>>> +
>>> +  cpp_opts->warn_unused_macros = saved_warn_unused_macros;
>>> +
>>> +  return ret;
>> So we don't need "RET" !
>>
>>> +}
>>> +
>>> +/* Implement REGISTER_TARGET_PRAGMAS.  */
>>> +
>>> +void
>>> +aarch64_register_pragmas (void)
>>> +{
>>> +  /* Update pragma hook to allow parsing #pragma GCC target.  */
>>> +  targetm.target_option.pragma_parse = aarch64_pragma_target_parse;
>>> +}
>>> \ No newline at end of file
>> I can't remember if GNU style mandates it, but in my opinion your new
>> file should have a trailing newline.
>>
>>> diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
>>> index 3a5482d..4704736 100644
>>> --- a/gcc/config/aarch64/aarch64-protos.h
>>> +++ b/gcc/config/aarch64/aarch64-protos.h
>>> @@ -360,6 +360,10 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, enum machine_mode, RTX_CODE);
>>>    #endif /* RTX_CODE */
>>>
>>>    void aarch64_init_builtins (void);
>>> +
>>> +bool aarch64_process_target_attr (tree, const char*);
>>> +void aarch64_override_options_internal (struct gcc_options *);
>>> +
>>>    rtx aarch64_expand_builtin (tree exp,
>>>                           rtx target,
>>>                           rtx subtarget ATTRIBUTE_UNUSED,
>>> @@ -376,6 +380,9 @@ extern void aarch64_split_combinev16qi (rtx operands[3]);
>>>    extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
>>>    extern bool aarch64_madd_needs_nop (rtx_insn *);
>>>    extern void aarch64_final_prescan_insn (rtx_insn *);
>>> +extern void aarch64_reset_previous_fndecl (void);
>>> +extern void aarch64_cpu_cpp_builtins (cpp_reader *);
>>> +extern void aarch64_register_pragmas (void);
>> At one point aarch64-protos.h was in alphabetical order. While we have
>> a number of mistakes already, we should try not to make the situation
>> worse!
>>
>>> diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
>>> index 7af4ad2..f6b2c11 100644
>>> --- a/gcc/config/aarch64/arm_acle.h
>>> +++ b/gcc/config/aarch64/arm_acle.h
>>> @@ -28,11 +28,16 @@
>>>    #define _GCC_ARM_ACLE_H
>>>
>>>    #include <stdint.h>
>>> +
>>> +#pragma GCC push_options
>>> +/* Add +nofp to make sure that 'fp' is not required to compile these
>>> +   intrinsics.  */
>>> +#pragma GCC target("+crc+nofp")
>> Hm, how does this work with the ARMv8.1 Extensions added by Matthew
>> Wahab recently? Presumably this needs to expand to have a "+no" for
>> all possible extensions. This seems messy, it might be neater to
>> implement something like +nothing which resets the state of the extension
>> features bitmask to zero.
> Thanks, I've implemented the "+nothing" architectural feature modifier
> that can appear only in target attributes and pragmas like so:
> #pragma GCC target ("+nothing+crc") where the +nothing clears out aarch64_isa_flags,
> allowing the rest of the string to enable features one by one.
>
> Also fixed the other issues you pointed.
>
> How's this?

And here is a rebased version to resolve a conflict after Alan's patches went in.

Thanks,
Kyrill


2015-08-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

      * config.gcc (aarch64*-*-*): Specify c_target_objs and cxx_target_objs.
      * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS): Define.
      (TARGET_CPU_CPP_BUILTINS): Redefine to call aarch64_cpu_cpp_builtins.
      * config/aarch64/aarch64.c (aarch64_override_options_internal): Remove
      static keyword.
      (aarch64_reset_previous_fndecl): New function.
      (aarch64_handle_attr_isa_flags): Handle "+nothing" in the beginning of
      the string.
      * config/aarch64/aarch64-c.c: New file.
      * config/aarch64/arm_acle.h: Add pragma +crc+nofp at the top.
      Push and pop options at beginning and end.  Remove ifdef
      __ARM_FEATURE_CRC32.
      * config/aarch64/arm_neon.h: Remove #ifdef check on __ARM_NEON.
      Add pragma arch=armv8-a+simd and +crypto where appropriate.
      * config/aarch64/t-aarch64 (aarch64-c.o): New rule.
      * config/aarch64/aarch64-protos.h (aarch64_cpu_cpp_builtins):
      Define prototype.
      (aarch64_register_pragmas): Likewise.
      (aarch64_reset_previous_fndecl): Likewise.
      (aarch64_process_target_attr): Likewise.
      (aarch64_override_options_internal): Likewise.

2015-08-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * gcc.target/aarch64/arm_neon-nosimd-error.c: Delete.


> Thanks,
> Kyrill
>
> 2015-07-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>
>       * config.gcc (aarch64*-*-*): Specify c_target_objs and cxx_target_objs.
>       * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS): Define.
>       (TARGET_CPU_CPP_BUILTINS): Redefine to call aarch64_cpu_cpp_builtins.
>       * config/aarch64/aarch64.c (aarch64_override_options_internal): Remove
>       static keyword.
>       (aarch64_reset_previous_fndecl): New function.
>       (aarch64_handle_attr_isa_flags): Handle "+nothing" in the beginning of
>       the string.
>       * config/aarch64/aarch64-c.c: New file.
>       * config/aarch64/arm_acle.h: Add pragma +crc+nofp at the top.
>       Push and pop options at beginning and end.  Remove ifdef
>       __ARM_FEATURE_CRC32.
>       * config/aarch64/arm_neon.h: Remove #ifdef check on __ARM_NEON.
>       Add pragma arch=armv8-a+simd and +crypto where appropriate.
>       * config/aarch64/t-aarch64 (aarch64-c.o): New rule.
>       * config/aarch64/aarch64-protos.h (aarch64_cpu_cpp_builtins):
>       Define prototype.
>       (aarch64_register_pragmas): Likewise.
>       (aarch64_reset_previous_fndecl): Likewise.
>       (aarch64_process_target_attr): Likewise.
>       (aarch64_override_options_internal): Likewise.
>
>
>>> +
>>>    #ifdef __cplusplus
>>>    extern "C" {
>>>    #endif
>>>
>>> -#ifdef __ARM_FEATURE_CRC32
>>>    __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
>>>    __crc32b (uint32_t __a, uint8_t __b)
>>>    {
>>> @@ -81,10 +86,10 @@ __crc32d (uint32_t __a, uint64_t __b)
>>>      return __builtin_aarch64_crc32x (__a, __b);
>>>    }
>>>
>>> -#endif
>>> -
>>>    #ifdef __cplusplus
>>>    }
>>>    #endif
>>>
>>> +#pragma GCC pop_options
>>> +
>>>    #endif
>> Thanks,
>> James
>>


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: aarch64-attrs-10.patch --]
[-- Type: text/x-patch; name=aarch64-attrs-10.patch, Size: 17591 bytes --]

commit eef5b2cf262c76fbfed80e9a5e3795d4667d473a
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date:   Thu May 14 15:36:07 2015 +0100

    [AArch64][10/N] Implement target pragmas

diff --git a/gcc/config.gcc b/gcc/config.gcc
index d6b928d..24f6d35 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -302,6 +302,8 @@ m32c*-*-*)
 aarch64*-*-*)
 	cpu_type=aarch64
 	extra_headers="arm_neon.h arm_acle.h"
+	c_target_objs="aarch64-c.o"
+	cxx_target_objs="aarch64-c.o"
 	extra_objs="aarch64-builtins.o aarch-common.o cortex-a57-fma-steering.o"
 	target_gtfiles="\$(srcdir)/config/aarch64/aarch64-builtins.c"
 	target_has_targetm_common=yes
diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c
new file mode 100644
index 0000000..a9020ab
--- /dev/null
+++ b/gcc/config/aarch64/aarch64-c.c
@@ -0,0 +1,191 @@
+/* Target-specific code for C family languages.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "input.h"
+#include "tm_p.h"
+#include "flags.h"
+#include "c-family/c-common.h"
+#include "cpplib.h"
+#include "c-family/c-pragma.h"
+#include "langhooks.h"
+#include "target.h"
+
+
+#define builtin_define(TXT) cpp_define (pfile, TXT)
+#define builtin_assert(TXT) cpp_assert (pfile, TXT)
+
+
+static void
+aarch64_def_or_undef (bool def_p, const char *macro, cpp_reader *pfile)
+{
+  if (def_p)
+    cpp_define (pfile, macro);
+  else
+    cpp_undef (pfile, macro);
+}
+
+/* Define the macros that we always expect to have on AArch64.  */
+
+static void
+aarch64_define_unconditional_macros (cpp_reader *pfile)
+{
+  builtin_define ("__aarch64__");
+  builtin_define ("__ARM_64BIT_STATE");
+
+  builtin_define ("__ARM_ARCH_ISA_A64");
+  builtin_define_with_int_value ("__ARM_ALIGN_MAX_PWR", 28);
+  builtin_define_with_int_value ("__ARM_ALIGN_MAX_STACK_PWR", 16);
+
+  /* __ARM_ARCH_8A is not mandated by ACLE but we define it unconditionally
+     as interoperability with the same arm macro.  */
+  builtin_define ("__ARM_ARCH_8A");
+
+  builtin_define_with_int_value ("__ARM_ARCH_PROFILE", 'A');
+  builtin_define ("__ARM_FEATURE_CLZ");
+  builtin_define ("__ARM_FEATURE_IDIV");
+  builtin_define ("__ARM_FEATURE_UNALIGNED");
+  builtin_define ("__ARM_PCS_AAPCS64");
+  builtin_define_with_int_value ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8);
+
+}
+
+/* Undefine/redefine macros that depend on the current backend state and may
+   need to change when a target pragma modifies the backend state.  */
+
+static void
+aarch64_update_cpp_builtins (cpp_reader *pfile)
+{
+  aarch64_def_or_undef (flag_unsafe_math_optimizations, "__ARM_FP_FAST", pfile);
+
+  builtin_define_with_int_value ("__ARM_ARCH", aarch64_architecture_version);
+
+  builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
+				 flag_short_enums ? 1 : 4);
+  aarch64_def_or_undef (TARGET_BIG_END, "__AARCH64EB__", pfile);
+  aarch64_def_or_undef (TARGET_BIG_END, "__ARM_BIG_ENDIAN", pfile);
+  aarch64_def_or_undef (!TARGET_BIG_END, "__AARCH64EL__", pfile);
+
+  aarch64_def_or_undef (TARGET_FLOAT, "__ARM_FEATURE_FMA", pfile);
+
+  if (TARGET_FLOAT || TARGET_SIMD)
+    {
+      builtin_define_with_int_value ("__ARM_FP", 0x0E);
+      builtin_define ("__ARM_FP16_FORMAT_IEEE");
+      builtin_define ("__ARM_FP16_ARGS");
+    }
+  else
+    cpp_undef (pfile, "__ARM_FP");
+
+  aarch64_def_or_undef (TARGET_SIMD, "__ARM_FEATURE_NUMERIC_MAXMIN", pfile);
+  aarch64_def_or_undef (TARGET_SIMD, "__ARM_NEON", pfile);
+
+
+  aarch64_def_or_undef (TARGET_CRC32, "__ARM_FEATURE_CRC32", pfile);
+
+  cpp_undef (pfile, "__AARCH64_CMODEL_TINY__");
+  cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__");
+  cpp_undef (pfile, "__AARCH64_CMODEL_LARGE__");
+
+  switch (aarch64_cmodel)
+    {
+      case AARCH64_CMODEL_TINY:
+      case AARCH64_CMODEL_TINY_PIC:
+	builtin_define ("__AARCH64_CMODEL_TINY__");
+	break;
+      case AARCH64_CMODEL_SMALL:
+      case AARCH64_CMODEL_SMALL_PIC:
+	builtin_define ("__AARCH64_CMODEL_SMALL__");
+	break;
+      case AARCH64_CMODEL_LARGE:
+	builtin_define ("__AARCH64_CMODEL_LARGE__");
+	break;
+      default:
+	break;
+    }
+
+  aarch64_def_or_undef (TARGET_ILP32, "_ILP32", pfile);
+  aarch64_def_or_undef (TARGET_ILP32, "__ILP32__", pfile);
+
+  aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile);
+}
+
+/* Implement TARGET_CPU_CPP_BUILTINS.  */
+
+void
+aarch64_cpu_cpp_builtins (cpp_reader *pfile)
+{
+  aarch64_define_unconditional_macros (pfile);
+  aarch64_update_cpp_builtins (pfile);
+}
+
+/* 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
+aarch64_pragma_target_parse (tree args, tree pop_target)
+{
+  /* If args is not NULL then process it and setup the target-specific
+     information that it specifies.  */
+  if (args)
+    {
+      if (!aarch64_process_target_attr (args, "pragma"))
+	return false;
+
+      aarch64_override_options_internal (&global_options);
+    }
+
+  /* args is NULL, restore to the state described in pop_target.  */
+  else
+    {
+      pop_target = pop_target ? pop_target : target_option_default_node;
+      cl_target_option_restore (&global_options,
+				TREE_TARGET_OPTION (pop_target));
+    }
+
+  target_option_current_node
+    = build_target_option_node (&global_options);
+
+  aarch64_reset_previous_fndecl ();
+  /* 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;
+
+  aarch64_update_cpp_builtins (parse_in);
+
+  cpp_opts->warn_unused_macros = saved_warn_unused_macros;
+
+  return true;
+}
+
+/* Implement REGISTER_TARGET_PRAGMAS.  */
+
+void
+aarch64_register_pragmas (void)
+{
+  /* Update pragma hook to allow parsing #pragma GCC target.  */
+  targetm.target_option.pragma_parse = aarch64_pragma_target_parse;
+}
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 3a5482d..6844c90 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -249,6 +249,7 @@ enum aarch64_symbol_type
 aarch64_classify_symbolic_expression (rtx, enum aarch64_symbol_context);
 bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
 bool aarch64_constant_address_p (rtx);
+extern void aarch64_cpu_cpp_builtins (cpp_reader *);
 bool aarch64_expand_movmem (rtx *);
 bool aarch64_float_const_zero_rtx_p (rtx);
 bool aarch64_function_arg_regno_p (unsigned);
@@ -323,6 +324,8 @@ void aarch64_init_expanders (void);
 void aarch64_print_operand (FILE *, rtx, char);
 void aarch64_print_operand_address (FILE *, rtx);
 void aarch64_emit_call_insn (rtx);
+void aarch64_register_pragmas (void);
+void aarch64_reset_previous_fndecl (void);
 
 /* Initialize builtins for SIMD intrinsics.  */
 void init_aarch64_simd_builtins (void);
@@ -360,6 +363,10 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, enum machine_mode, RTX_CODE);
 #endif /* RTX_CODE */
 
 void aarch64_init_builtins (void);
+
+bool aarch64_process_target_attr (tree, const char*);
+void aarch64_override_options_internal (struct gcc_options *);
+
 rtx aarch64_expand_builtin (tree exp,
 			    rtx target,
 			    rtx subtarget ATTRIBUTE_UNUSED,
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 7fdcffa..addcc5c 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7524,7 +7524,7 @@ aarch64_override_options_after_change_1 (struct gcc_options *opts)
     as all the other target-specific codegen decisions are
     derived from them.  */
 
-static void
+void
 aarch64_override_options_internal (struct gcc_options *opts)
 {
   aarch64_tune_flags = selected_tune->flags;
@@ -7915,6 +7915,12 @@ aarch64_option_print (FILE *file, int indent, struct cl_target_option *ptr)
 
 static GTY(()) tree aarch64_previous_fndecl;
 
+void
+aarch64_reset_previous_fndecl (void)
+{
+  aarch64_previous_fndecl = NULL;
+}
+
 /* Implement TARGET_SET_CURRENT_FUNCTION.  Unpack the codegen decisions
    like tuning and ISA features from the DECL_FUNCTION_SPECIFIC_TARGET
    of the function, if such exists.  This function may be called multiple
@@ -8118,6 +8124,14 @@ aarch64_handle_attr_isa_flags (char *str, const char *pragma_or_attr)
   enum aarch64_parse_opt_result parse_res;
   unsigned long isa_flags = aarch64_isa_flags;
 
+  /* We allow "+nothing" in the beginning to clear out all architectural
+     features if the user wants to handpick specific features.  */
+  if (strncmp ("+nothing", str, 8) == 0)
+    {
+      isa_flags = 0;
+      str += 8;
+    }
+
   parse_res = aarch64_parse_extension (str, &isa_flags);
 
   if (parse_res == AARCH64_PARSE_OK)
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 41f50fe..721927f 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -23,85 +23,13 @@
 #define GCC_AARCH64_H
 
 /* Target CPU builtins.  */
-#define TARGET_CPU_CPP_BUILTINS()			\
-  do							\
-    {							\
-      builtin_define ("__aarch64__");                   \
-      builtin_define ("__ARM_64BIT_STATE");             \
-      builtin_define_with_int_value                     \
-        ("__ARM_ALIGN_MAX_PWR", 28);                    \
-      builtin_define_with_int_value                     \
-        ("__ARM_ALIGN_MAX_STACK_PWR", 16);              \
-      builtin_define_with_int_value                     \
-        ("__ARM_ARCH", aarch64_architecture_version);   \
-      builtin_define ("__ARM_ARCH_8A");                   \
-      builtin_define ("__ARM_ARCH_ISA_A64");            \
-      builtin_define_with_int_value                     \
-        ("__ARM_ARCH_PROFILE", 'A');                    \
-      builtin_define ("__ARM_FEATURE_CLZ");             \
-      builtin_define ("__ARM_FEATURE_IDIV");            \
-      builtin_define ("__ARM_FEATURE_UNALIGNED");       \
-      if (flag_unsafe_math_optimizations)               \
-        builtin_define ("__ARM_FP_FAST");               \
-      builtin_define ("__ARM_PCS_AAPCS64");             \
-      builtin_define_with_int_value                     \
-        ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8);  \
-      builtin_define_with_int_value                     \
-        ("__ARM_SIZEOF_MINIMAL_ENUM",                   \
-         flag_short_enums? 1 : 4);                      \
-      if (TARGET_BIG_END)				\
-        {                                               \
-          builtin_define ("__AARCH64EB__");             \
-          builtin_define ("__ARM_BIG_ENDIAN");          \
-        }                                               \
-      else						\
-	builtin_define ("__AARCH64EL__");		\
-							\
-      if (TARGET_FLOAT)                                         \
-        {                                                       \
-          builtin_define ("__ARM_FEATURE_FMA");                 \
-	  builtin_define_with_int_value ("__ARM_FP", 0x0E);     \
-	  builtin_define ("__ARM_FP16_FORMAT_IEEE");		\
-	  builtin_define ("__ARM_FP16_ARGS");			\
-        }                                                       \
-      if (TARGET_SIMD)                                          \
-        {                                                       \
-          builtin_define ("__ARM_FEATURE_NUMERIC_MAXMIN");      \
-          builtin_define ("__ARM_NEON");			\
-          builtin_define_with_int_value ("__ARM_NEON_FP", 0x0C);\
-        }                                                       \
-							        \
-      if (TARGET_CRC32)				        \
-	builtin_define ("__ARM_FEATURE_CRC32");		\
-							\
-      switch (aarch64_cmodel)				\
-	{						\
-	  case AARCH64_CMODEL_TINY:			\
-	  case AARCH64_CMODEL_TINY_PIC:			\
-	    builtin_define ("__AARCH64_CMODEL_TINY__");	\
-	    break;					\
-	  case AARCH64_CMODEL_SMALL:			\
-	  case AARCH64_CMODEL_SMALL_PIC:		\
-	    builtin_define ("__AARCH64_CMODEL_SMALL__");\
-	    break;					\
-	  case AARCH64_CMODEL_LARGE:			\
-	    builtin_define ("__AARCH64_CMODEL_LARGE__");	\
-	    break;					\
-	  default:					\
-	    break;					\
-	}						\
-							\
-      if (TARGET_ILP32)					\
-	{						\
-	  cpp_define (parse_in, "_ILP32");		\
-	  cpp_define (parse_in, "__ILP32__");		\
-	}						\
-      if (TARGET_CRYPTO)				\
-	builtin_define ("__ARM_FEATURE_CRYPTO");	\
-    } while (0)
+#define TARGET_CPU_CPP_BUILTINS()	\
+  aarch64_cpu_cpp_builtins (pfile)
 
 \f
 
+#define REGISTER_TARGET_PRAGMAS() aarch64_register_pragmas ()
+
 /* Target machine storage layout.  */
 
 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)	\
diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
index 7af4ad2..addbc6a 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -28,11 +28,15 @@
 #define _GCC_ARM_ACLE_H
 
 #include <stdint.h>
+
+#pragma GCC push_options
+
+#pragma GCC target ("+nothing+crc")
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#ifdef __ARM_FEATURE_CRC32
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
 __crc32b (uint32_t __a, uint8_t __b)
 {
@@ -81,10 +85,10 @@ __crc32d (uint32_t __a, uint64_t __b)
   return __builtin_aarch64_crc32x (__a, __b);
 }
 
-#endif
-
 #ifdef __cplusplus
 }
 #endif
 
+#pragma GCC pop_options
+
 #endif
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index fce5577..f5d183f 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -27,9 +27,8 @@
 #ifndef _AARCH64_NEON_H_
 #define _AARCH64_NEON_H_
 
-#ifndef __ARM_NEON
-#error You must enable AdvancedSIMD instructions to use arm_neon.h
-#else
+#pragma GCC push_options
+#pragma GCC target ("+nothing+simd")
 
 #include <stdint.h>
 
@@ -11414,8 +11413,8 @@ vbslq_u64 (uint64x2_t __a, uint64x2_t __b, uint64x2_t __c)
   return __builtin_aarch64_simd_bslv2di_uuuu (__a, __b, __c);
 }
 
-#ifdef __ARM_FEATURE_CRYPTO
-
+#pragma GCC push_options
+#pragma GCC target ("+crypto")
 /* vaes  */
 
 __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
@@ -11441,8 +11440,7 @@ vaesimcq_u8 (uint8x16_t data)
 {
   return __builtin_aarch64_crypto_aesimcv16qi_uu (data);
 }
-
-#endif
+#pragma GCC pop_options
 
 /* vcage  */
 
@@ -21067,7 +21065,8 @@ vrsrad_n_u64 (uint64_t __a, uint64_t __b, const int __c)
   return __builtin_aarch64_ursra_ndi_uuus (__a, __b, __c);
 }
 
-#ifdef __ARM_FEATURE_CRYPTO
+#pragma GCC push_options
+#pragma GCC target ("+crypto")
 
 /* vsha1  */
 
@@ -21144,7 +21143,7 @@ vmull_high_p64 (poly64x2_t a, poly64x2_t b)
   return __builtin_aarch64_crypto_pmullv2di_ppp (a, b);
 }
 
-#endif
+#pragma GCC pop_options
 
 /* vshl */
 
@@ -24912,6 +24911,6 @@ __INTERLEAVE_LIST (zip)
 #undef __aarch64_vdupq_laneq_u32
 #undef __aarch64_vdupq_laneq_u64
 
-#endif
+#pragma GCC pop_options
 
 #endif
diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64
index af154f4..782853b 100644
--- a/gcc/config/aarch64/t-aarch64
+++ b/gcc/config/aarch64/t-aarch64
@@ -48,6 +48,11 @@ aarch-common.o: $(srcdir)/config/arm/aarch-common.c $(CONFIG_H) $(SYSTEM_H) \
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$(srcdir)/config/arm/aarch-common.c
 
+aarch64-c.o: $(srcdir)/config/aarch64/aarch64-c.c $(CONFIG_H) $(SYSTEM_H) \
+    coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+		$(srcdir)/config/aarch64/aarch64-c.c
+
 cortex-a57-fma-steering.o: $(srcdir)/config/aarch64/cortex-a57-fma-steering.c \
     $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(REGS_H) insn-config.h $(RTL_BASE_H) \
     dominance.h cfg.h cfganal.h $(BASIC_BLOCK_H) $(INSN_ATTR_H) $(RECOG_H) \
diff --git a/gcc/testsuite/gcc.target/aarch64/arm_neon-nosimd-error.c b/gcc/testsuite/gcc.target/aarch64/arm_neon-nosimd-error.c
deleted file mode 100644
index 6c508ec..0000000
--- a/gcc/testsuite/gcc.target/aarch64/arm_neon-nosimd-error.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mgeneral-regs-only" } */
-/* { dg-excess-errors "You must enable" } */
-
-#include "arm_neon.h"
-
-int
-foo ()
-{
-  return 0;
-}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH][AArch64][10/14] Implement target pragmas
  2015-08-03  9:36     ` Kyrill Tkachov
@ 2015-08-03 11:18       ` James Greenhalgh
  0 siblings, 0 replies; 5+ messages in thread
From: James Greenhalgh @ 2015-08-03 11:18 UTC (permalink / raw)
  To: Kyrill Tkachov; +Cc: GCC Patches, Marcus Shawcroft, Richard Earnshaw

On Mon, Aug 03, 2015 at 10:36:17AM +0100, Kyrill Tkachov wrote:
> And here is a rebased version to resolve a conflict after Alan's patches went in.
> 

OK with the nits below fixed.

> 2015-08-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
> 
>       * config.gcc (aarch64*-*-*): Specify c_target_objs and cxx_target_objs.
>       * config/aarch64/aarch64.h (REGISTER_TARGET_PRAGMAS): Define.
>       (TARGET_CPU_CPP_BUILTINS): Redefine to call aarch64_cpu_cpp_builtins.
>       * config/aarch64/aarch64.c (aarch64_override_options_internal): Remove
>       static keyword.
>       (aarch64_reset_previous_fndecl): New function.
>       (aarch64_handle_attr_isa_flags): Handle "+nothing" in the beginning of
>       the string.
>       * config/aarch64/aarch64-c.c: New file.
>       * config/aarch64/arm_acle.h: Add pragma +crc+nofp at the top.
>       Push and pop options at beginning and end.  Remove ifdef
>       __ARM_FEATURE_CRC32.
>       * config/aarch64/arm_neon.h: Remove #ifdef check on __ARM_NEON.
>       Add pragma arch=armv8-a+simd and +crypto where appropriate.
>       * config/aarch64/t-aarch64 (aarch64-c.o): New rule.
>       * config/aarch64/aarch64-protos.h (aarch64_cpu_cpp_builtins):
>       Define prototype.
>       (aarch64_register_pragmas): Likewise.
>       (aarch64_reset_previous_fndecl): Likewise.
>       (aarch64_process_target_attr): Likewise.
>       (aarch64_override_options_internal): Likewise.
> 
> 2015-08-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
> 
>      * gcc.target/aarch64/arm_neon-nosimd-error.c: Delete.
> 
> 

> +/* Define the macros that we always expect to have on AArch64.  */
> +
> +static void
> +aarch64_define_unconditional_macros (cpp_reader *pfile)
> +{
> +  builtin_define ("__aarch64__");
> +  builtin_define ("__ARM_64BIT_STATE");
> +
> +  builtin_define ("__ARM_ARCH_ISA_A64");
> +  builtin_define_with_int_value ("__ARM_ALIGN_MAX_PWR", 28);
> +  builtin_define_with_int_value ("__ARM_ALIGN_MAX_STACK_PWR", 16);
> +
> +  /* __ARM_ARCH_8A is not mandated by ACLE but we define it unconditionally
> +     as interoperability with the same arm macro.  */
> +  builtin_define ("__ARM_ARCH_8A");
> +
> +  builtin_define_with_int_value ("__ARM_ARCH_PROFILE", 'A');
> +  builtin_define ("__ARM_FEATURE_CLZ");
> +  builtin_define ("__ARM_FEATURE_IDIV");
> +  builtin_define ("__ARM_FEATURE_UNALIGNED");
> +  builtin_define ("__ARM_PCS_AAPCS64");
> +  builtin_define_with_int_value ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8);
> +
> +}

Extra newline.

> diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
> index 3a5482d..6844c90 100644
> --- a/gcc/config/aarch64/aarch64-protos.h
> +++ b/gcc/config/aarch64/aarch64-protos.h
> @@ -249,6 +249,7 @@ enum aarch64_symbol_type
>  aarch64_classify_symbolic_expression (rtx, enum aarch64_symbol_context);
>  bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
>  bool aarch64_constant_address_p (rtx);
> +extern void aarch64_cpu_cpp_builtins (cpp_reader *);

No need for this "extern" - and keep this in alphabetical order (first by
return type, then by name).

> +#pragma GCC push_options
> +#pragma GCC target ("+crypto")

Keep things simple to manage and understand by inspection, and make these
"+nothing+crypto".

> @@ -21067,7 +21065,8 @@ vrsrad_n_u64 (uint64_t __a, uint64_t __b, const int __c)
>    return __builtin_aarch64_ursra_ndi_uuus (__a, __b, __c);
>  }
>  
> -#ifdef __ARM_FEATURE_CRYPTO
> +#pragma GCC push_options
> +#pragma GCC target ("+crypto")
>  
>  /* vsha1  */
>  

Likewise here.

Thanks,
James

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-08-03 11:18 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-16 15:25 [PATCH][AArch64][10/14] Implement target pragmas Kyrill Tkachov
2015-07-21 16:58 ` James Greenhalgh
2015-07-24  8:40   ` Kyrill Tkachov
2015-08-03  9:36     ` Kyrill Tkachov
2015-08-03 11:18       ` James Greenhalgh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).