public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][ARM] Implement CRC32 intrinsics for AArch32 in ARMv8-A
@ 2013-11-19 12:22 Kyrill Tkachov
  2013-11-19 16:56 ` Joseph S. Myers
  0 siblings, 1 reply; 8+ messages in thread
From: Kyrill Tkachov @ 2013-11-19 12:22 UTC (permalink / raw)
  To: GCC Patches, Ramana Radhakrishnan, Richard Earnshaw

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

Hi all,

This patch implements the CRC32 intrinsics that map down to the optional CRC32 
instructions in ARMv8-A as defined by ACLE. They are exposed by a new header 
file: arm_acle.h which can be included in user programs similarly to the 
existing arm_neon.h header.

To enable the use of these intrinsics (and instructions) we define a new 
-march=armv8-a+crc option. We will pass the "crc" option as a .arch_extension 
directive in the generated assembly to gas.

Documentation and testsuite changes are included (a new effective target check 
and option-adding procedure in testsuite/lib). A new directory: 
gcc.target/arm/acle/ is added that contains the new tests and can be used to 
contain tests for other non-NEON ACLE intrinsics that might be implemented in 
the future.


Regtested arm-none-eabi on a model and bootstrapped arm-none-linux-gnueabihf on 
a Chromebook.

Ok for trunk?

Thanks,
Kyrill

gcc/
2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * Makefile.in (TEXI_GCC_FILES): Add arm-acle-intrinsics.texi.
     * config.gcc (extra_headers): Add arm_acle.h.
     * config/arm/arm.c (FL_CRC32): Define.
     (arm_have_crc): Likewise.
     (arm_option_override): Set arm_have_crc.
     (arm_builtins): Add CRC32 builtins.
     (bdesc_2arg): Likewise.
     (arm_init_crc32_builtins): New function.
     (arm_init_builtins): Initialise CRC32 builtins.
     (arm_file_start): Handle architecture extensions.
     * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __ARM_FEATURE_CRC32.
     Define __ARM_32BIT_STATE.
     (TARGET_CRC32): Define.
     * config/arm/arm-arches.def: Add armv8-a+crc.
     * config/arm/arm-tables.opt: Regenerate.
     * config/arm/arm.md (type): Add crc.
     (<crc_variant>): New insn.
     * config/arm/arm_acle.h: New file.
     * config/arm/iterators.md (CRC): New int iterator.
     (crc_variant, crc_mode): New int attributes.
     * confg/arm/unspecs.md (UNSPEC_CRC32B, UNSPEC_CRC32H, UNSPEC_CRC32W,
     UNSPEC_CRC32CB, UNSPEC_CRC32CH, UNSPEC_CRC32CW): New unspecs.
     * doc/invoke.texi: Document -march=armv8-a+crc option.
     * doc/extend.texi: Document ACLE intrinsics.
     * doc/arm-acle-intrinsics.texi: New.


gcc/testsuite
2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * lib/target-supports.exp (add_options_for_arm_crc): New procedure.
     (check_effective_target_arm_crc_ok_nocache): Likewise.
     (check_effective_target_arm_crc_ok): Likewise.
     * gcc.target/arm/acle/: New directory.
     * gcc.target/arm/acle/acle.exp: New.
     * gcc.target/arm/acle/crc32b.c: New test.
     * gcc.target/arm/acle/crc32h.c: Likewise.
     * gcc.target/arm/acle/crc32w.c: Likewise.
     * gcc.target/arm/acle/crc32d.c: Likewise.
     * gcc.target/arm/acle/crc32cb.c: Likewise.
     * gcc.target/arm/acle/crc32ch.c: Likewise.
     * gcc.target/arm/acle/crc32cw.c: Likewise.
     * gcc.target/arm/acle/crc32cd.c: Likewise.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: crc-intrinsics-all.patch --]
[-- Type: text/x-patch; name=crc-intrinsics-all.patch, Size: 28260 bytes --]

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 77fba80..08f1ea1 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2793,7 +2793,8 @@ TEXI_GCC_FILES = gcc.texi gcc-common.texi gcc-vers.texi frontends.texi	\
 	 gcov.texi trouble.texi bugreport.texi service.texi		\
 	 contribute.texi compat.texi funding.texi gnu.texi gpl_v3.texi	\
 	 fdl.texi contrib.texi cppenv.texi cppopts.texi avr-mmcu.texi	\
-	 implement-c.texi implement-cxx.texi arm-neon-intrinsics.texi
+	 implement-c.texi implement-cxx.texi arm-neon-intrinsics.texi	\
+	 arm-acle-intrinsics.texi
 
 # we explicitly use $(srcdir)/doc/tm.texi here to avoid confusion with
 # the generated tm.texi; the latter might have a more recent timestamp,
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 2907018..ebbdc59 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -329,8 +329,8 @@ arc*-*-*)
 	;;
 arm*-*-*)
 	cpu_type=arm
-	extra_headers="mmintrin.h arm_neon.h"
 	extra_objs="aarch-common.o"
+	extra_headers="mmintrin.h arm_neon.h arm_acle.h"
 	target_type_format_char='%'
 	c_target_objs="arm-c.o"
 	cxx_target_objs="arm-c.o"
diff --git a/gcc/config/arm/arm-arches.def b/gcc/config/arm/arm-arches.def
index fcf3401..9b7d20c 100644
--- a/gcc/config/arm/arm-arches.def
+++ b/gcc/config/arm/arm-arches.def
@@ -54,5 +54,6 @@ ARM_ARCH("armv7-r", cortexr4,	7R,  FL_CO_PROC |	      FL_FOR_ARCH7R)
 ARM_ARCH("armv7-m", cortexm3,	7M,  FL_CO_PROC |	      FL_FOR_ARCH7M)
 ARM_ARCH("armv7e-m", cortexm4,  7EM, FL_CO_PROC |	      FL_FOR_ARCH7EM)
 ARM_ARCH("armv8-a", cortexa53,  8A,  FL_CO_PROC |             FL_FOR_ARCH8A)
+ARM_ARCH("armv8-a+crc",cortexa53, 8A,FL_CO_PROC | FL_CRC32  | FL_FOR_ARCH8A)
 ARM_ARCH("iwmmxt",  iwmmxt,     5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT)
 ARM_ARCH("iwmmxt2", iwmmxt2,    5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT | FL_IWMMXT2)
diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt
index b3e7a7c..8851876 100644
--- a/gcc/config/arm/arm-tables.opt
+++ b/gcc/config/arm/arm-tables.opt
@@ -362,10 +362,13 @@ EnumValue
 Enum(arm_arch) String(armv8-a) Value(23)
 
 EnumValue
-Enum(arm_arch) String(iwmmxt) Value(24)
+Enum(arm_arch) String(armv8-a+crc) Value(24)
 
 EnumValue
-Enum(arm_arch) String(iwmmxt2) Value(25)
+Enum(arm_arch) String(iwmmxt) Value(25)
+
+EnumValue
+Enum(arm_arch) String(iwmmxt2) Value(26)
 
 Enum
 Name(arm_fpu) Type(int)
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 1686f1d..cb35e56 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -732,6 +732,7 @@ static int thumb_call_reg_needed;
 #define FL_ARCH7      (1 << 22)       /* Architecture 7.  */
 #define FL_ARM_DIV    (1 << 23)	      /* Hardware divide (ARM mode).  */
 #define FL_ARCH8      (1 << 24)       /* Architecture 8.  */
+#define FL_CRC32      (1 << 25)	      /* ARMv8 CRC32 instructions.  */
 
 #define FL_IWMMXT     (1 << 29)	      /* XScale v2 or "Intel Wireless MMX technology".  */
 #define FL_IWMMXT2    (1 << 30)       /* "Intel Wireless MMX2 technology".  */
@@ -894,6 +895,9 @@ int arm_condexec_mask = 0;
 /* The number of bits used in arm_condexec_mask.  */
 int arm_condexec_masklen = 0;
 
+/* Nonzero if chip supports the ARMv8 CRC instructions.  */
+int arm_arch_crc = 0;
+
 /* The condition codes of the ARM, and the inverse function.  */
 static const char * const arm_condition_codes[] =
 {
@@ -2370,6 +2374,7 @@ arm_option_override (void)
   arm_arch_thumb_hwdiv = (insn_flags & FL_THUMB_DIV) != 0;
   arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0;
   arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0;
+  arm_arch_crc = (insn_flags & FL_CRC32) != 0;
   if (arm_restrict_it == 2)
     arm_restrict_it = arm_arch8 && TARGET_THUMB2;
 
@@ -22916,6 +22921,13 @@ enum arm_builtins
 
   ARM_BUILTIN_WMERGE,
 
+  ARM_BUILTIN_CRC32B,
+  ARM_BUILTIN_CRC32H,
+  ARM_BUILTIN_CRC32W,
+  ARM_BUILTIN_CRC32CB,
+  ARM_BUILTIN_CRC32CH,
+  ARM_BUILTIN_CRC32CW,
+
 #include "arm_neon_builtins.def"
 
   ,ARM_BUILTIN_MAX
@@ -23495,7 +23507,7 @@ struct builtin_description
   const enum rtx_code      comparison;
   const unsigned int       flag;
 };
-  
+
 static const struct builtin_description bdesc_2arg[] =
 {
 #define IWMMXT_BUILTIN(code, string, builtin) \
@@ -23601,6 +23613,17 @@ static const struct builtin_description bdesc_2arg[] =
   IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
   IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
   IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
+
+#define CRC32_BUILTIN(L, U) \
+  {0, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
+   UNKNOWN, 0},
+   CRC32_BUILTIN (crc32b, CRC32B)
+   CRC32_BUILTIN (crc32h, CRC32H)
+   CRC32_BUILTIN (crc32w, CRC32W)
+   CRC32_BUILTIN (crc32cb, CRC32CB)
+   CRC32_BUILTIN (crc32ch, CRC32CH)
+   CRC32_BUILTIN (crc32cw, CRC32CW)
+#undef CRC32_BUILTIN
 };
 
 static const struct builtin_description bdesc_1arg[] =
@@ -24020,6 +24043,42 @@ arm_init_fp16_builtins (void)
 }
 
 static void
+arm_init_crc32_builtins ()
+{
+  tree si_ftype_si_qi
+    = build_function_type_list (unsigned_intSI_type_node,
+                                unsigned_intSI_type_node,
+                                unsigned_intQI_type_node, NULL_TREE);
+  tree si_ftype_si_hi
+    = build_function_type_list (unsigned_intSI_type_node,
+                                unsigned_intSI_type_node,
+                                unsigned_intHI_type_node, NULL_TREE);
+  tree si_ftype_si_si
+    = build_function_type_list (unsigned_intSI_type_node,
+                                unsigned_intSI_type_node,
+                                unsigned_intSI_type_node, NULL_TREE);
+
+  arm_builtin_decls[ARM_BUILTIN_CRC32B]
+    = add_builtin_function ("__builtin_arm_crc32b", si_ftype_si_qi,
+                            ARM_BUILTIN_CRC32B, BUILT_IN_MD, NULL, NULL_TREE);
+  arm_builtin_decls[ARM_BUILTIN_CRC32H]
+    = add_builtin_function ("__builtin_arm_crc32h", si_ftype_si_hi,
+                            ARM_BUILTIN_CRC32H, BUILT_IN_MD, NULL, NULL_TREE);
+  arm_builtin_decls[ARM_BUILTIN_CRC32W]
+    = add_builtin_function ("__builtin_arm_crc32w", si_ftype_si_si,
+                            ARM_BUILTIN_CRC32W, BUILT_IN_MD, NULL, NULL_TREE);
+  arm_builtin_decls[ARM_BUILTIN_CRC32CB]
+    = add_builtin_function ("__builtin_arm_crc32cb", si_ftype_si_qi,
+                            ARM_BUILTIN_CRC32CB, BUILT_IN_MD, NULL, NULL_TREE);
+  arm_builtin_decls[ARM_BUILTIN_CRC32CH]
+    = add_builtin_function ("__builtin_arm_crc32ch", si_ftype_si_hi,
+                            ARM_BUILTIN_CRC32CH, BUILT_IN_MD, NULL, NULL_TREE);
+  arm_builtin_decls[ARM_BUILTIN_CRC32CW]
+    = add_builtin_function ("__builtin_arm_crc32cw", si_ftype_si_si,
+                            ARM_BUILTIN_CRC32CW, BUILT_IN_MD, NULL, NULL_TREE);
+}
+
+static void
 arm_init_builtins (void)
 {
   if (TARGET_REALLY_IWMMXT)
@@ -24030,6 +24089,9 @@ arm_init_builtins (void)
 
   if (arm_fp16_format)
     arm_init_fp16_builtins ();
+
+  if (TARGET_CRC32)
+    arm_init_crc32_builtins ();
 }
 
 /* Return the ARM builtin for CODE.  */
@@ -27303,7 +27365,22 @@ arm_file_start (void)
     {
       const char *fpu_name;
       if (arm_selected_arch)
-	asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_arch->name);
+        {
+          const char* pos = strchr (arm_selected_arch->name, '+');
+	  if (pos)
+	    {
+	      char buf[15];
+	      gcc_assert (strlen (arm_selected_arch->name)
+	                  <= sizeof (buf) / sizeof (*pos));
+	      strncpy (buf, arm_selected_arch->name,
+	                    (pos - arm_selected_arch->name) * sizeof (*pos));
+	      buf[pos - arm_selected_arch->name] = '\0';
+	      asm_fprintf (asm_out_file, "\t.arch %s\n", buf);
+	      asm_fprintf (asm_out_file, "\t.arch_extension %s\n", pos + 1);
+	    }
+	  else
+	    asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_arch->name);
+        }
       else if (strncmp (arm_selected_cpu->name, "generic", 7) == 0)
 	asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_cpu->name + 8);
       else
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 1781b75..85eeb2a 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -51,6 +51,10 @@ extern char arm_arch_name[];
            builtin_define ("__ARM_FEATURE_SAT");	\
 	if (unaligned_access)				\
 	  builtin_define ("__ARM_FEATURE_UNALIGNED");	\
+	if (TARGET_CRC32)				\
+	  builtin_define ("__ARM_FEATURE_CRC32");	\
+	if (TARGET_32BIT)				\
+	  builtin_define ("__ARM_32BIT_STATE");		\
 	if (TARGET_ARM_FEATURE_LDREX)				\
 	  builtin_define_with_int_value (			\
 	    "__ARM_FEATURE_LDREX", TARGET_ARM_FEATURE_LDREX);	\
@@ -274,6 +278,8 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
 #define TARGET_LDRD			(arm_arch5e && ARM_DOUBLEWORD_ALIGN \
                                          && !TARGET_THUMB1)
 
+#define TARGET_CRC32			(arm_arch_crc)
+
 /* The following two macros concern the ability to execute coprocessor
    instructions for VFPv3 or NEON.  TARGET_VFP3/TARGET_VFPD32 are currently
    only ever tested when we know we are generating for VFP hardware; we need
@@ -554,6 +560,9 @@ extern int arm_arch_thumb_hwdiv;
    than core registers.  */
 extern int prefer_neon_for_64bits;
 
+/* Nonzero if chip supports the ARMv8 CRC instructions.  */
+extern int arm_arch_crc;
+
 #ifndef TARGET_DEFAULT
 #define TARGET_DEFAULT  (MASK_APCS_FRAME)
 #endif
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 3726201..75444d2 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -12756,6 +12756,16 @@
    (set_attr "predicable" "yes")
    (set_attr "predicable_short_it" "no")])
 
+;; ARMv8 CRC32 instructions.
+(define_insn "<crc_variant>"
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
+                    (match_operand:<crc_mode> 2 "s_register_operand" "r")]
+         CRC))]
+  "TARGET_CRC32"
+  "<crc_variant>\\t%0, %1, %2"
+  [(set_attr "type" "crc")]
+)
 
 ;; Load the load/store double peephole optimizations.
 (include "ldrdstrd.md")
diff --git a/gcc/config/arm/arm_acle.h b/gcc/config/arm/arm_acle.h
new file mode 100644
index 0000000..b04605b
--- /dev/null
+++ b/gcc/config/arm/arm_acle.h
@@ -0,0 +1,100 @@
+/* ARM Non-NEON ACLE intrinsics include file.
+
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   Contributed by ARM Ltd.
+
+   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.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GCC_ARM_ACLE_H
+#define _GCC_ARM_ACLE_H
+
+#include <stdint.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __ARM_FEATURE_CRC32
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32b (uint32_t a, uint8_t b)
+{
+  return __builtin_arm_crc32b (a, b);
+}
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32h (uint32_t a, uint16_t b)
+{
+  return __builtin_arm_crc32h (a, b);
+}
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32w (uint32_t a, uint32_t b)
+{
+  return __builtin_arm_crc32w (a, b);
+}
+
+#ifdef __ARM_32BIT_STATE
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32d (uint32_t a, uint64_t b)
+{
+  uint32_t d;
+
+  d = __crc32w (__crc32w (a, b & 0xffffffffULL), b >> 32);
+  return d;
+}
+#endif
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32cb (uint32_t a, uint8_t b)
+{
+  return __builtin_arm_crc32cb (a, b);
+}
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32ch (uint32_t a, uint16_t b)
+{
+  return __builtin_arm_crc32ch (a, b);
+}
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32cw (uint32_t a, uint32_t b)
+{
+  return __builtin_arm_crc32cw (a, b);
+}
+
+#ifdef __ARM_32BIT_STATE
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32cd (uint32_t a, uint64_t b)
+{
+  uint32_t d;
+
+  d = __crc32cw (__crc32cw (a, b & 0xffffffffULL), b >> 32);
+  return d;
+}
+#endif
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index 38777b8..fcffc87 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -201,6 +201,9 @@
 (define_int_iterator NEON_VRINT [UNSPEC_NVRINTP UNSPEC_NVRINTZ UNSPEC_NVRINTM
                               UNSPEC_NVRINTX UNSPEC_NVRINTA UNSPEC_NVRINTN])
 
+(define_int_iterator CRC [UNSPEC_CRC32B UNSPEC_CRC32H UNSPEC_CRC32W
+                          UNSPEC_CRC32CB UNSPEC_CRC32CH UNSPEC_CRC32CW])
+
 ;;----------------------------------------------------------------------------
 ;; Mode attributes
 ;;----------------------------------------------------------------------------
@@ -514,6 +517,15 @@
 (define_int_attr nvrint_variant [(UNSPEC_NVRINTZ "z") (UNSPEC_NVRINTP "p")
                                 (UNSPEC_NVRINTA "a") (UNSPEC_NVRINTM "m")
                                 (UNSPEC_NVRINTX "x") (UNSPEC_NVRINTN "n")])
+
+(define_int_attr crc_variant [(UNSPEC_CRC32B "crc32b") (UNSPEC_CRC32H "crc32h")
+                        (UNSPEC_CRC32W "crc32w") (UNSPEC_CRC32CB "crc32cb")
+                        (UNSPEC_CRC32CH "crc32ch") (UNSPEC_CRC32CW "crc32cw")])
+
+(define_int_attr crc_mode [(UNSPEC_CRC32B "QI") (UNSPEC_CRC32H "HI")
+                        (UNSPEC_CRC32W "SI") (UNSPEC_CRC32CB "QI")
+                        (UNSPEC_CRC32CH "HI") (UNSPEC_CRC32CW "SI")])
+
 ;; Both kinds of return insn.
 (define_code_iterator returns [return simple_return])
 (define_code_attr return_str [(return "") (simple_return "simple_")])
diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md
index 1c4b9e3..b505be3 100644
--- a/gcc/config/arm/types.md
+++ b/gcc/config/arm/types.md
@@ -543,6 +543,7 @@
   clz,\
   no_insn,\
   csel,\
+  crc,\
   extend,\
   f_cvt,\
   f_cvtf2i,\
diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md
index 508603c..f8faba3 100644
--- a/gcc/config/arm/unspecs.md
+++ b/gcc/config/arm/unspecs.md
@@ -149,6 +149,12 @@
 (define_c_enum "unspec" [
   UNSPEC_ASHIFT_SIGNED
   UNSPEC_ASHIFT_UNSIGNED
+  UNSPEC_CRC32B
+  UNSPEC_CRC32H
+  UNSPEC_CRC32W
+  UNSPEC_CRC32CB
+  UNSPEC_CRC32CH
+  UNSPEC_CRC32CW
   UNSPEC_LOAD_COUNT
   UNSPEC_VABD
   UNSPEC_VABDL
diff --git a/gcc/doc/arm-acle-intrinsics.texi b/gcc/doc/arm-acle-intrinsics.texi
new file mode 100644
index 0000000..bb6290b
--- /dev/null
+++ b/gcc/doc/arm-acle-intrinsics.texi
@@ -0,0 +1,55 @@
+@c Copyright (C) 2013 Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+
+@subsubsection CRC32 intrinsics
+
+@itemize @bullet
+@item uint32_t __crc32b (uint32_t, uint8_t)
+@*@emph{Form of expected instruction(s):} @code{crc32b @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32h (uint32_t, uint16_t)
+@*@emph{Form of expected instruction(s):} @code{crc32h @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32w (uint32_t, uint32_t)
+@*@emph{Form of expected instruction(s):} @code{crc32w @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32d (uint32_t, uint64_t)
+@*@emph{Form of expected instruction(s):} Two @code{crc32w @var{r0}, @var{r0}, @var{r0}}
+instructions for AArch32. One @code{crc32w @var{w0}, @var{w0}, @var{x0}} instruction for
+AArch64.
+@end itemize
+
+@itemize @bullet
+@item uint32_t __crc32cb (uint32_t, uint8_t)
+@*@emph{Form of expected instruction(s):} @code{crc32cb @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32ch (uint32_t, uint16_t)
+@*@emph{Form of expected instruction(s):} @code{crc32ch @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32cw (uint32_t, uint32_t)
+@*@emph{Form of expected instruction(s):} @code{crc32cw @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32cd (uint32_t, uint64_t)
+@*@emph{Form of expected instruction(s):} Two @code{crc32cw @var{r0}, @var{r0}, @var{r0}}
+instructions for AArch32. One @code{crc32cw @var{w0}, @var{w0}, @var{x0}} instruction for
+AArch64.
+@end itemize
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 88eba80..2880953 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -9204,6 +9204,7 @@ instructions, but allow the compiler to schedule those calls.
 * ARC SIMD Built-in Functions::
 * ARM iWMMXt Built-in Functions::
 * ARM NEON Intrinsics::
+* ARM ACLE Intrinsics::
 * AVR Built-in Functions::
 * Blackfin Built-in Functions::
 * FR-V Built-in Functions::
@@ -9895,6 +9896,14 @@ when the @option{-mfpu=neon} switch is used:
 
 @include arm-neon-intrinsics.texi
 
+@node ARM ACLE Intrinsics
+@subsection ARM ACLE Intrinsics
+
+These built-in intrinsics for the ARMv8-A CRC32 extension are available when
+the @option{-march=armv8-a+crc} switch is used:
+
+@include arm-acle-intrinsics.texi
+
 @node AVR Built-in Functions
 @subsection AVR Built-in Functions
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8855fb7..87bcc1c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -12093,9 +12093,12 @@ of the @option{-mcpu=} option.  Permissible names are: @samp{armv2},
 @samp{armv6}, @samp{armv6j},
 @samp{armv6t2}, @samp{armv6z}, @samp{armv6zk}, @samp{armv6-m},
 @samp{armv7}, @samp{armv7-a}, @samp{armv7-r}, @samp{armv7-m},
-@samp{armv8-a},
+@samp{armv8-a}, @samp{armv8-a+crc},
 @samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312}.
 
+@option{-march=armv8-a+crc} enables code generation for the ARMv8-A
+architecture together with the optional CRC32 extensions.
+
 @option{-march=native} causes the compiler to auto-detect the architecture
 of the build computer.  At present, this feature is only supported on
 Linux, and not all architectures are recognized.  If the auto-detect is
diff --git a/gcc/testsuite/gcc.target/arm/acle/acle.exp b/gcc/testsuite/gcc.target/arm/acle/acle.exp
new file mode 100644
index 0000000..a1822a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/acle.exp
@@ -0,0 +1,35 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an ARM target.
+if ![istarget arm*-*-*] then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+	"" ""
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32b.c b/gcc/testsuite/gcc.target/arm/acle/crc32b.c
new file mode 100644
index 0000000..d6f35e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32b.c
@@ -0,0 +1,20 @@
+/* Test the crc32b ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32b (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint8_t arg1_uint8_t;
+
+  out_uint32_t = __crc32b (arg0_uint32_t, arg1_uint8_t);
+}
+
+/* { dg-final { scan-assembler "crc32b\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32cb.c b/gcc/testsuite/gcc.target/arm/acle/crc32cb.c
new file mode 100644
index 0000000..44aea21
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32cb.c
@@ -0,0 +1,20 @@
+/* Test the crc32cb ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32cb (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint8_t arg1_uint8_t;
+
+  out_uint32_t = __crc32cb (arg0_uint32_t, arg1_uint8_t);
+}
+
+/* { dg-final { scan-assembler "crc32cb\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32cd.c b/gcc/testsuite/gcc.target/arm/acle/crc32cd.c
new file mode 100644
index 0000000..cb7ee0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32cd.c
@@ -0,0 +1,20 @@
+/* Test the crc32cd ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32cd (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint64_t arg1_uint64_t;
+
+  out_uint32_t = __crc32cd (arg0_uint32_t, arg1_uint64_t);
+}
+
+/* { dg-final { scan-assembler-times "crc32cw\t...?, ...?, ...?\n" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32ch.c b/gcc/testsuite/gcc.target/arm/acle/crc32ch.c
new file mode 100644
index 0000000..d8e7338
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32ch.c
@@ -0,0 +1,20 @@
+/* Test the crc32ch ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32ch (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint16_t arg1_uint16_t;
+
+  out_uint32_t = __crc32ch (arg0_uint32_t, arg1_uint16_t);
+}
+
+/* { dg-final { scan-assembler "crc32ch\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32cw.c b/gcc/testsuite/gcc.target/arm/acle/crc32cw.c
new file mode 100644
index 0000000..84384c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32cw.c
@@ -0,0 +1,20 @@
+/* Test the crc32cw ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32cw (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint32_t arg1_uint32_t;
+
+  out_uint32_t = __crc32cw (arg0_uint32_t, arg1_uint32_t);
+}
+
+/* { dg-final { scan-assembler "crc32cw\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32d.c b/gcc/testsuite/gcc.target/arm/acle/crc32d.c
new file mode 100644
index 0000000..c90fad9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32d.c
@@ -0,0 +1,20 @@
+/* Test the crc32d ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32d (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint64_t arg1_uint64_t;
+
+  out_uint32_t = __crc32d (arg0_uint32_t, arg1_uint64_t);
+}
+
+/* { dg-final { scan-assembler-times "crc32w\t...?, ...?, ...?\n" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32h.c b/gcc/testsuite/gcc.target/arm/acle/crc32h.c
new file mode 100644
index 0000000..c21a4ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32h.c
@@ -0,0 +1,20 @@
+/* Test the crc32h ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32h (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint16_t arg1_uint16_t;
+
+  out_uint32_t = __crc32h (arg0_uint32_t, arg1_uint16_t);
+}
+
+/* { dg-final { scan-assembler "crc32h\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32w.c b/gcc/testsuite/gcc.target/arm/acle/crc32w.c
new file mode 100644
index 0000000..60cd09e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32w.c
@@ -0,0 +1,20 @@
+/* Test the crc32w ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32w (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint32_t arg1_uint32_t;
+
+  out_uint32_t = __crc32w (arg0_uint32_t, arg1_uint32_t);
+}
+
+/* { dg-final { scan-assembler "crc32w\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 104818d..a256b12 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2300,6 +2300,14 @@ proc add_options_for_arm_v8_neon { flags } {
     return "$flags $et_arm_v8_neon_flags -march=armv8-a"
 }
 
+proc add_options_for_arm_crc { flags } {
+    if { ! [check_effective_target_arm_crc_ok] } {
+        return "$flags"
+    }
+    global et_arm_crc_flags
+    return "$flags $et_arm_crc_flags"
+}
+
 # Add the options needed for NEON.  We need either -mfloat-abi=softfp
 # or -mfloat-abi=hard, but if one is already specified by the
 # multilib, use it.  Similarly, if a -mfpu option already enables
@@ -2341,6 +2349,21 @@ proc check_effective_target_arm_neon_ok { } {
 		check_effective_target_arm_neon_ok_nocache]
 }
 
+proc check_effective_target_arm_crc_ok_nocache { } {
+    global et_arm_crc_flags
+    set et_arm_crc_flags "-march=armv8-a+crc"
+    return [check_no_compiler_messages_nocache arm_crc_ok object {
+	#if !defined (__ARM_FEATURE_CRC32)
+	#error FOO
+	#endif
+    } "$et_arm_crc_flags"]
+}
+
+proc check_effective_target_arm_crc_ok { } {
+    return [check_cached_effective_target arm_crc_ok \
+		check_effective_target_arm_crc_ok_nocache]
+}
+
 # Return 1 if this is an ARM target supporting -mfpu=neon-fp16
 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
 # incompatible with these options.  Also set et_arm_neon_flags to the

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

* Re: [PATCH][ARM] Implement CRC32 intrinsics for AArch32 in ARMv8-A
  2013-11-19 12:22 [PATCH][ARM] Implement CRC32 intrinsics for AArch32 in ARMv8-A Kyrill Tkachov
@ 2013-11-19 16:56 ` Joseph S. Myers
  2013-11-19 17:36   ` Kyrill Tkachov
  0 siblings, 1 reply; 8+ messages in thread
From: Joseph S. Myers @ 2013-11-19 16:56 UTC (permalink / raw)
  To: Kyrill Tkachov; +Cc: GCC Patches, Ramana Radhakrishnan, Richard Earnshaw

In any target header installed for user use, such as arm_acle.h, you need 
to be namespace-clean.  In this case, that means you need to use 
implementation-namespace identifiers such as __a, __b and __d in case the 
user has defined macros with names such as a, b and d (unless the ACLE 
says that identifiers a, b and d are in the implementation's namespace 
when this header is included, which would be a very odd thing for it to 
do).

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH][ARM] Implement CRC32 intrinsics for AArch32 in ARMv8-A
  2013-11-19 16:56 ` Joseph S. Myers
@ 2013-11-19 17:36   ` Kyrill Tkachov
  2013-11-26 11:09     ` Kyrill Tkachov
  0 siblings, 1 reply; 8+ messages in thread
From: Kyrill Tkachov @ 2013-11-19 17:36 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: GCC Patches, Ramana Radhakrishnan, Richard Earnshaw

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

On 19/11/13 16:26, Joseph S. Myers wrote:
> In any target header installed for user use, such as arm_acle.h, you need
> to be namespace-clean.  In this case, that means you need to use
> implementation-namespace identifiers such as __a, __b and __d in case the
> user has defined macros with names such as a, b and d (unless the ACLE
> says that identifiers a, b and d are in the implementation's namespace
> when this header is included, which would be a very odd thing for it to
> do).
>

Hi Joseph,

Thanks for the catch. ACLE doesn't expect a,b,d to be in the implementation 
namespace. I've added underscores before them.

Made sure tests pass.

Revised patch attached.
How's this?

Kyrill

gcc/
2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * Makefile.in (TEXI_GCC_FILES): Add arm-acle-intrinsics.texi.
     * config.gcc (extra_headers): Add arm_acle.h.
     * config/arm/arm.c (FL_CRC32): Define.
     (arm_have_crc): Likewise.
     (arm_option_override): Set arm_have_crc.
     (arm_builtins): Add CRC32 builtins.
     (bdesc_2arg): Likewise.
     (arm_init_crc32_builtins): New function.
     (arm_init_builtins): Initialise CRC32 builtins.
     (arm_file_start): Handle architecture extensions.
     * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __ARM_FEATURE_CRC32.
     Define __ARM_32BIT_STATE.
     (TARGET_CRC32): Define.
     * config/arm/arm-arches.def: Add armv8-a+crc.
     * config/arm/arm-tables.opt: Regenerate.
     * config/arm/arm.md (type): Add crc.
     (<crc_variant>): New insn.
     * config/arm/arm_acle.h: New file.
     * config/arm/iterators.md (CRC): New int iterator.
     (crc_variant, crc_mode): New int attributes.
     * confg/arm/unspecs.md (UNSPEC_CRC32B, UNSPEC_CRC32H, UNSPEC_CRC32W,
     UNSPEC_CRC32CB, UNSPEC_CRC32CH, UNSPEC_CRC32CW): New unspecs.
     * doc/invoke.texi: Document -march=armv8-a+crc option.
     * doc/extend.texi: Document ACLE intrinsics.
     * doc/arm-acle-intrinsics.texi: New.


gcc/testsuite
2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * lib/target-supports.exp (add_options_for_arm_crc): New procedure.
     (check_effective_target_arm_crc_ok_nocache): Likewise.
     (check_effective_target_arm_crc_ok): Likewise.
     * gcc.target/arm/acle/: New directory.
     * gcc.target/arm/acle/acle.exp: New.
     * gcc.target/arm/acle/crc32b.c: New test.
     * gcc.target/arm/acle/crc32h.c: Likewise.
     * gcc.target/arm/acle/crc32w.c: Likewise.
     * gcc.target/arm/acle/crc32d.c: Likewise.
     * gcc.target/arm/acle/crc32cb.c: Likewise.
     * gcc.target/arm/acle/crc32ch.c: Likewise.
     * gcc.target/arm/acle/crc32cw.c: Likewise.
     * gcc.target/arm/acle/crc32cd.c: Likewise.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: crc-intrinsics-all-2.patch --]
[-- Type: text/x-patch; name=crc-intrinsics-all-2.patch, Size: 28340 bytes --]

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 8cc8341..455c80b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2793,7 +2793,8 @@ TEXI_GCC_FILES = gcc.texi gcc-common.texi gcc-vers.texi frontends.texi	\
 	 gcov.texi trouble.texi bugreport.texi service.texi		\
 	 contribute.texi compat.texi funding.texi gnu.texi gpl_v3.texi	\
 	 fdl.texi contrib.texi cppenv.texi cppopts.texi avr-mmcu.texi	\
-	 implement-c.texi implement-cxx.texi arm-neon-intrinsics.texi
+	 implement-c.texi implement-cxx.texi arm-neon-intrinsics.texi	\
+	 arm-acle-intrinsics.texi
 
 # we explicitly use $(srcdir)/doc/tm.texi here to avoid confusion with
 # the generated tm.texi; the latter might have a more recent timestamp,
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 2907018..ebbdc59 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -329,8 +329,8 @@ arc*-*-*)
 	;;
 arm*-*-*)
 	cpu_type=arm
-	extra_headers="mmintrin.h arm_neon.h"
 	extra_objs="aarch-common.o"
+	extra_headers="mmintrin.h arm_neon.h arm_acle.h"
 	target_type_format_char='%'
 	c_target_objs="arm-c.o"
 	cxx_target_objs="arm-c.o"
diff --git a/gcc/config/arm/arm-arches.def b/gcc/config/arm/arm-arches.def
index fcf3401..9b7d20c 100644
--- a/gcc/config/arm/arm-arches.def
+++ b/gcc/config/arm/arm-arches.def
@@ -54,5 +54,6 @@ ARM_ARCH("armv7-r", cortexr4,	7R,  FL_CO_PROC |	      FL_FOR_ARCH7R)
 ARM_ARCH("armv7-m", cortexm3,	7M,  FL_CO_PROC |	      FL_FOR_ARCH7M)
 ARM_ARCH("armv7e-m", cortexm4,  7EM, FL_CO_PROC |	      FL_FOR_ARCH7EM)
 ARM_ARCH("armv8-a", cortexa53,  8A,  FL_CO_PROC |             FL_FOR_ARCH8A)
+ARM_ARCH("armv8-a+crc",cortexa53, 8A,FL_CO_PROC | FL_CRC32  | FL_FOR_ARCH8A)
 ARM_ARCH("iwmmxt",  iwmmxt,     5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT)
 ARM_ARCH("iwmmxt2", iwmmxt2,    5TE, FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT | FL_IWMMXT2)
diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt
index b3e7a7c..8851876 100644
--- a/gcc/config/arm/arm-tables.opt
+++ b/gcc/config/arm/arm-tables.opt
@@ -362,10 +362,13 @@ EnumValue
 Enum(arm_arch) String(armv8-a) Value(23)
 
 EnumValue
-Enum(arm_arch) String(iwmmxt) Value(24)
+Enum(arm_arch) String(armv8-a+crc) Value(24)
 
 EnumValue
-Enum(arm_arch) String(iwmmxt2) Value(25)
+Enum(arm_arch) String(iwmmxt) Value(25)
+
+EnumValue
+Enum(arm_arch) String(iwmmxt2) Value(26)
 
 Enum
 Name(arm_fpu) Type(int)
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 590c577..490b76f 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -736,6 +736,7 @@ static int thumb_call_reg_needed;
 #define FL_ARCH7      (1 << 22)       /* Architecture 7.  */
 #define FL_ARM_DIV    (1 << 23)	      /* Hardware divide (ARM mode).  */
 #define FL_ARCH8      (1 << 24)       /* Architecture 8.  */
+#define FL_CRC32      (1 << 25)	      /* ARMv8 CRC32 instructions.  */
 
 #define FL_IWMMXT     (1 << 29)	      /* XScale v2 or "Intel Wireless MMX technology".  */
 #define FL_IWMMXT2    (1 << 30)       /* "Intel Wireless MMX2 technology".  */
@@ -898,6 +899,9 @@ int arm_condexec_mask = 0;
 /* The number of bits used in arm_condexec_mask.  */
 int arm_condexec_masklen = 0;
 
+/* Nonzero if chip supports the ARMv8 CRC instructions.  */
+int arm_arch_crc = 0;
+
 /* The condition codes of the ARM, and the inverse function.  */
 static const char * const arm_condition_codes[] =
 {
@@ -2374,6 +2378,7 @@ arm_option_override (void)
   arm_arch_thumb_hwdiv = (insn_flags & FL_THUMB_DIV) != 0;
   arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0;
   arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0;
+  arm_arch_crc = (insn_flags & FL_CRC32) != 0;
   if (arm_restrict_it == 2)
     arm_restrict_it = arm_arch8 && TARGET_THUMB2;
 
@@ -22924,6 +22929,13 @@ enum arm_builtins
 
   ARM_BUILTIN_WMERGE,
 
+  ARM_BUILTIN_CRC32B,
+  ARM_BUILTIN_CRC32H,
+  ARM_BUILTIN_CRC32W,
+  ARM_BUILTIN_CRC32CB,
+  ARM_BUILTIN_CRC32CH,
+  ARM_BUILTIN_CRC32CW,
+
 #include "arm_neon_builtins.def"
 
   ,ARM_BUILTIN_MAX
@@ -23503,7 +23515,7 @@ struct builtin_description
   const enum rtx_code      comparison;
   const unsigned int       flag;
 };
-  
+
 static const struct builtin_description bdesc_2arg[] =
 {
 #define IWMMXT_BUILTIN(code, string, builtin) \
@@ -23609,6 +23621,17 @@ static const struct builtin_description bdesc_2arg[] =
   IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
   IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
   IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
+
+#define CRC32_BUILTIN(L, U) \
+  {0, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
+   UNKNOWN, 0},
+   CRC32_BUILTIN (crc32b, CRC32B)
+   CRC32_BUILTIN (crc32h, CRC32H)
+   CRC32_BUILTIN (crc32w, CRC32W)
+   CRC32_BUILTIN (crc32cb, CRC32CB)
+   CRC32_BUILTIN (crc32ch, CRC32CH)
+   CRC32_BUILTIN (crc32cw, CRC32CW)
+#undef CRC32_BUILTIN
 };
 
 static const struct builtin_description bdesc_1arg[] =
@@ -24028,6 +24051,42 @@ arm_init_fp16_builtins (void)
 }
 
 static void
+arm_init_crc32_builtins ()
+{
+  tree si_ftype_si_qi
+    = build_function_type_list (unsigned_intSI_type_node,
+                                unsigned_intSI_type_node,
+                                unsigned_intQI_type_node, NULL_TREE);
+  tree si_ftype_si_hi
+    = build_function_type_list (unsigned_intSI_type_node,
+                                unsigned_intSI_type_node,
+                                unsigned_intHI_type_node, NULL_TREE);
+  tree si_ftype_si_si
+    = build_function_type_list (unsigned_intSI_type_node,
+                                unsigned_intSI_type_node,
+                                unsigned_intSI_type_node, NULL_TREE);
+
+  arm_builtin_decls[ARM_BUILTIN_CRC32B]
+    = add_builtin_function ("__builtin_arm_crc32b", si_ftype_si_qi,
+                            ARM_BUILTIN_CRC32B, BUILT_IN_MD, NULL, NULL_TREE);
+  arm_builtin_decls[ARM_BUILTIN_CRC32H]
+    = add_builtin_function ("__builtin_arm_crc32h", si_ftype_si_hi,
+                            ARM_BUILTIN_CRC32H, BUILT_IN_MD, NULL, NULL_TREE);
+  arm_builtin_decls[ARM_BUILTIN_CRC32W]
+    = add_builtin_function ("__builtin_arm_crc32w", si_ftype_si_si,
+                            ARM_BUILTIN_CRC32W, BUILT_IN_MD, NULL, NULL_TREE);
+  arm_builtin_decls[ARM_BUILTIN_CRC32CB]
+    = add_builtin_function ("__builtin_arm_crc32cb", si_ftype_si_qi,
+                            ARM_BUILTIN_CRC32CB, BUILT_IN_MD, NULL, NULL_TREE);
+  arm_builtin_decls[ARM_BUILTIN_CRC32CH]
+    = add_builtin_function ("__builtin_arm_crc32ch", si_ftype_si_hi,
+                            ARM_BUILTIN_CRC32CH, BUILT_IN_MD, NULL, NULL_TREE);
+  arm_builtin_decls[ARM_BUILTIN_CRC32CW]
+    = add_builtin_function ("__builtin_arm_crc32cw", si_ftype_si_si,
+                            ARM_BUILTIN_CRC32CW, BUILT_IN_MD, NULL, NULL_TREE);
+}
+
+static void
 arm_init_builtins (void)
 {
   if (TARGET_REALLY_IWMMXT)
@@ -24038,6 +24097,9 @@ arm_init_builtins (void)
 
   if (arm_fp16_format)
     arm_init_fp16_builtins ();
+
+  if (TARGET_CRC32)
+    arm_init_crc32_builtins ();
 }
 
 /* Return the ARM builtin for CODE.  */
@@ -27311,7 +27373,22 @@ arm_file_start (void)
     {
       const char *fpu_name;
       if (arm_selected_arch)
-	asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_arch->name);
+        {
+          const char* pos = strchr (arm_selected_arch->name, '+');
+	  if (pos)
+	    {
+	      char buf[15];
+	      gcc_assert (strlen (arm_selected_arch->name)
+	                  <= sizeof (buf) / sizeof (*pos));
+	      strncpy (buf, arm_selected_arch->name,
+	                    (pos - arm_selected_arch->name) * sizeof (*pos));
+	      buf[pos - arm_selected_arch->name] = '\0';
+	      asm_fprintf (asm_out_file, "\t.arch %s\n", buf);
+	      asm_fprintf (asm_out_file, "\t.arch_extension %s\n", pos + 1);
+	    }
+	  else
+	    asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_arch->name);
+        }
       else if (strncmp (arm_selected_cpu->name, "generic", 7) == 0)
 	asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_cpu->name + 8);
       else
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index dbd841e..0043c9b 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -51,6 +51,10 @@ extern char arm_arch_name[];
            builtin_define ("__ARM_FEATURE_SAT");	\
 	if (unaligned_access)				\
 	  builtin_define ("__ARM_FEATURE_UNALIGNED");	\
+	if (TARGET_CRC32)				\
+	  builtin_define ("__ARM_FEATURE_CRC32");	\
+	if (TARGET_32BIT)				\
+	  builtin_define ("__ARM_32BIT_STATE");		\
 	if (TARGET_ARM_FEATURE_LDREX)				\
 	  builtin_define_with_int_value (			\
 	    "__ARM_FEATURE_LDREX", TARGET_ARM_FEATURE_LDREX);	\
@@ -274,6 +278,8 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
 #define TARGET_LDRD			(arm_arch5e && ARM_DOUBLEWORD_ALIGN \
                                          && !TARGET_THUMB1)
 
+#define TARGET_CRC32			(arm_arch_crc)
+
 /* The following two macros concern the ability to execute coprocessor
    instructions for VFPv3 or NEON.  TARGET_VFP3/TARGET_VFPD32 are currently
    only ever tested when we know we are generating for VFP hardware; we need
@@ -554,6 +560,9 @@ extern int arm_arch_thumb_hwdiv;
    than core registers.  */
 extern int prefer_neon_for_64bits;
 
+/* Nonzero if chip supports the ARMv8 CRC instructions.  */
+extern int arm_arch_crc;
+
 #ifndef TARGET_DEFAULT
 #define TARGET_DEFAULT  (MASK_APCS_FRAME)
 #endif
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 3726201..75444d2 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -12756,6 +12756,16 @@
    (set_attr "predicable" "yes")
    (set_attr "predicable_short_it" "no")])
 
+;; ARMv8 CRC32 instructions.
+(define_insn "<crc_variant>"
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
+                    (match_operand:<crc_mode> 2 "s_register_operand" "r")]
+         CRC))]
+  "TARGET_CRC32"
+  "<crc_variant>\\t%0, %1, %2"
+  [(set_attr "type" "crc")]
+)
 
 ;; Load the load/store double peephole optimizations.
 (include "ldrdstrd.md")
diff --git a/gcc/config/arm/arm_acle.h b/gcc/config/arm/arm_acle.h
new file mode 100644
index 0000000..ac3a15c
--- /dev/null
+++ b/gcc/config/arm/arm_acle.h
@@ -0,0 +1,100 @@
+/* ARM Non-NEON ACLE intrinsics include file.
+
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   Contributed by ARM Ltd.
+
+   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.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GCC_ARM_ACLE_H
+#define _GCC_ARM_ACLE_H
+
+#include <stdint.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __ARM_FEATURE_CRC32
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32b (uint32_t __a, uint8_t __b)
+{
+  return __builtin_arm_crc32b (__a, __b);
+}
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32h (uint32_t __a, uint16_t __b)
+{
+  return __builtin_arm_crc32h (__a, __b);
+}
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32w (uint32_t __a, uint32_t __b)
+{
+  return __builtin_arm_crc32w (__a, __b);
+}
+
+#ifdef __ARM_32BIT_STATE
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32d (uint32_t __a, uint64_t __b)
+{
+  uint32_t __d;
+
+  __d = __crc32w (__crc32w (__a, __b & 0xffffffffULL), __b >> 32);
+  return __d;
+}
+#endif
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32cb (uint32_t __a, uint8_t __b)
+{
+  return __builtin_arm_crc32cb (__a, __b);
+}
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32ch (uint32_t __a, uint16_t __b)
+{
+  return __builtin_arm_crc32ch (__a, __b);
+}
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32cw (uint32_t __a, uint32_t __b)
+{
+  return __builtin_arm_crc32cw (__a, __b);
+}
+
+#ifdef __ARM_32BIT_STATE
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__crc32cd (uint32_t __a, uint64_t __b)
+{
+  uint32_t __d;
+
+  __d = __crc32cw (__crc32cw (__a, __b & 0xffffffffULL), __b >> 32);
+  return __d;
+}
+#endif
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index 38777b8..fcffc87 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -201,6 +201,9 @@
 (define_int_iterator NEON_VRINT [UNSPEC_NVRINTP UNSPEC_NVRINTZ UNSPEC_NVRINTM
                               UNSPEC_NVRINTX UNSPEC_NVRINTA UNSPEC_NVRINTN])
 
+(define_int_iterator CRC [UNSPEC_CRC32B UNSPEC_CRC32H UNSPEC_CRC32W
+                          UNSPEC_CRC32CB UNSPEC_CRC32CH UNSPEC_CRC32CW])
+
 ;;----------------------------------------------------------------------------
 ;; Mode attributes
 ;;----------------------------------------------------------------------------
@@ -514,6 +517,15 @@
 (define_int_attr nvrint_variant [(UNSPEC_NVRINTZ "z") (UNSPEC_NVRINTP "p")
                                 (UNSPEC_NVRINTA "a") (UNSPEC_NVRINTM "m")
                                 (UNSPEC_NVRINTX "x") (UNSPEC_NVRINTN "n")])
+
+(define_int_attr crc_variant [(UNSPEC_CRC32B "crc32b") (UNSPEC_CRC32H "crc32h")
+                        (UNSPEC_CRC32W "crc32w") (UNSPEC_CRC32CB "crc32cb")
+                        (UNSPEC_CRC32CH "crc32ch") (UNSPEC_CRC32CW "crc32cw")])
+
+(define_int_attr crc_mode [(UNSPEC_CRC32B "QI") (UNSPEC_CRC32H "HI")
+                        (UNSPEC_CRC32W "SI") (UNSPEC_CRC32CB "QI")
+                        (UNSPEC_CRC32CH "HI") (UNSPEC_CRC32CW "SI")])
+
 ;; Both kinds of return insn.
 (define_code_iterator returns [return simple_return])
 (define_code_attr return_str [(return "") (simple_return "simple_")])
diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md
index 1c4b9e3..b505be3 100644
--- a/gcc/config/arm/types.md
+++ b/gcc/config/arm/types.md
@@ -543,6 +543,7 @@
   clz,\
   no_insn,\
   csel,\
+  crc,\
   extend,\
   f_cvt,\
   f_cvtf2i,\
diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md
index 508603c..f8faba3 100644
--- a/gcc/config/arm/unspecs.md
+++ b/gcc/config/arm/unspecs.md
@@ -149,6 +149,12 @@
 (define_c_enum "unspec" [
   UNSPEC_ASHIFT_SIGNED
   UNSPEC_ASHIFT_UNSIGNED
+  UNSPEC_CRC32B
+  UNSPEC_CRC32H
+  UNSPEC_CRC32W
+  UNSPEC_CRC32CB
+  UNSPEC_CRC32CH
+  UNSPEC_CRC32CW
   UNSPEC_LOAD_COUNT
   UNSPEC_VABD
   UNSPEC_VABDL
diff --git a/gcc/doc/arm-acle-intrinsics.texi b/gcc/doc/arm-acle-intrinsics.texi
new file mode 100644
index 0000000..bb6290b
--- /dev/null
+++ b/gcc/doc/arm-acle-intrinsics.texi
@@ -0,0 +1,55 @@
+@c Copyright (C) 2013 Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+
+@subsubsection CRC32 intrinsics
+
+@itemize @bullet
+@item uint32_t __crc32b (uint32_t, uint8_t)
+@*@emph{Form of expected instruction(s):} @code{crc32b @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32h (uint32_t, uint16_t)
+@*@emph{Form of expected instruction(s):} @code{crc32h @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32w (uint32_t, uint32_t)
+@*@emph{Form of expected instruction(s):} @code{crc32w @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32d (uint32_t, uint64_t)
+@*@emph{Form of expected instruction(s):} Two @code{crc32w @var{r0}, @var{r0}, @var{r0}}
+instructions for AArch32. One @code{crc32w @var{w0}, @var{w0}, @var{x0}} instruction for
+AArch64.
+@end itemize
+
+@itemize @bullet
+@item uint32_t __crc32cb (uint32_t, uint8_t)
+@*@emph{Form of expected instruction(s):} @code{crc32cb @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32ch (uint32_t, uint16_t)
+@*@emph{Form of expected instruction(s):} @code{crc32ch @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32cw (uint32_t, uint32_t)
+@*@emph{Form of expected instruction(s):} @code{crc32cw @var{r0}, @var{r0}, @var{r0}}
+@end itemize
+
+
+@itemize @bullet
+@item uint32_t __crc32cd (uint32_t, uint64_t)
+@*@emph{Form of expected instruction(s):} Two @code{crc32cw @var{r0}, @var{r0}, @var{r0}}
+instructions for AArch32. One @code{crc32cw @var{w0}, @var{w0}, @var{x0}} instruction for
+AArch64.
+@end itemize
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 88eba80..2880953 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -9204,6 +9204,7 @@ instructions, but allow the compiler to schedule those calls.
 * ARC SIMD Built-in Functions::
 * ARM iWMMXt Built-in Functions::
 * ARM NEON Intrinsics::
+* ARM ACLE Intrinsics::
 * AVR Built-in Functions::
 * Blackfin Built-in Functions::
 * FR-V Built-in Functions::
@@ -9895,6 +9896,14 @@ when the @option{-mfpu=neon} switch is used:
 
 @include arm-neon-intrinsics.texi
 
+@node ARM ACLE Intrinsics
+@subsection ARM ACLE Intrinsics
+
+These built-in intrinsics for the ARMv8-A CRC32 extension are available when
+the @option{-march=armv8-a+crc} switch is used:
+
+@include arm-acle-intrinsics.texi
+
 @node AVR Built-in Functions
 @subsection AVR Built-in Functions
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index c250385..c38740c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -12093,9 +12093,12 @@ of the @option{-mcpu=} option.  Permissible names are: @samp{armv2},
 @samp{armv6}, @samp{armv6j},
 @samp{armv6t2}, @samp{armv6z}, @samp{armv6zk}, @samp{armv6-m},
 @samp{armv7}, @samp{armv7-a}, @samp{armv7-r}, @samp{armv7-m},
-@samp{armv8-a},
+@samp{armv8-a}, @samp{armv8-a+crc},
 @samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312}.
 
+@option{-march=armv8-a+crc} enables code generation for the ARMv8-A
+architecture together with the optional CRC32 extensions.
+
 @option{-march=native} causes the compiler to auto-detect the architecture
 of the build computer.  At present, this feature is only supported on
 Linux, and not all architectures are recognized.  If the auto-detect is
diff --git a/gcc/testsuite/gcc.target/arm/acle/acle.exp b/gcc/testsuite/gcc.target/arm/acle/acle.exp
new file mode 100644
index 0000000..a1822a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/acle.exp
@@ -0,0 +1,35 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an ARM target.
+if ![istarget arm*-*-*] then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+	"" ""
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32b.c b/gcc/testsuite/gcc.target/arm/acle/crc32b.c
new file mode 100644
index 0000000..d6f35e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32b.c
@@ -0,0 +1,20 @@
+/* Test the crc32b ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32b (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint8_t arg1_uint8_t;
+
+  out_uint32_t = __crc32b (arg0_uint32_t, arg1_uint8_t);
+}
+
+/* { dg-final { scan-assembler "crc32b\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32cb.c b/gcc/testsuite/gcc.target/arm/acle/crc32cb.c
new file mode 100644
index 0000000..44aea21
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32cb.c
@@ -0,0 +1,20 @@
+/* Test the crc32cb ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32cb (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint8_t arg1_uint8_t;
+
+  out_uint32_t = __crc32cb (arg0_uint32_t, arg1_uint8_t);
+}
+
+/* { dg-final { scan-assembler "crc32cb\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32cd.c b/gcc/testsuite/gcc.target/arm/acle/crc32cd.c
new file mode 100644
index 0000000..cb7ee0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32cd.c
@@ -0,0 +1,20 @@
+/* Test the crc32cd ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32cd (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint64_t arg1_uint64_t;
+
+  out_uint32_t = __crc32cd (arg0_uint32_t, arg1_uint64_t);
+}
+
+/* { dg-final { scan-assembler-times "crc32cw\t...?, ...?, ...?\n" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32ch.c b/gcc/testsuite/gcc.target/arm/acle/crc32ch.c
new file mode 100644
index 0000000..d8e7338
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32ch.c
@@ -0,0 +1,20 @@
+/* Test the crc32ch ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32ch (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint16_t arg1_uint16_t;
+
+  out_uint32_t = __crc32ch (arg0_uint32_t, arg1_uint16_t);
+}
+
+/* { dg-final { scan-assembler "crc32ch\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32cw.c b/gcc/testsuite/gcc.target/arm/acle/crc32cw.c
new file mode 100644
index 0000000..84384c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32cw.c
@@ -0,0 +1,20 @@
+/* Test the crc32cw ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32cw (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint32_t arg1_uint32_t;
+
+  out_uint32_t = __crc32cw (arg0_uint32_t, arg1_uint32_t);
+}
+
+/* { dg-final { scan-assembler "crc32cw\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32d.c b/gcc/testsuite/gcc.target/arm/acle/crc32d.c
new file mode 100644
index 0000000..c90fad9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32d.c
@@ -0,0 +1,20 @@
+/* Test the crc32d ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32d (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint64_t arg1_uint64_t;
+
+  out_uint32_t = __crc32d (arg0_uint32_t, arg1_uint64_t);
+}
+
+/* { dg-final { scan-assembler-times "crc32w\t...?, ...?, ...?\n" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32h.c b/gcc/testsuite/gcc.target/arm/acle/crc32h.c
new file mode 100644
index 0000000..c21a4ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32h.c
@@ -0,0 +1,20 @@
+/* Test the crc32h ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32h (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint16_t arg1_uint16_t;
+
+  out_uint32_t = __crc32h (arg0_uint32_t, arg1_uint16_t);
+}
+
+/* { dg-final { scan-assembler "crc32h\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/crc32w.c b/gcc/testsuite/gcc.target/arm/acle/crc32w.c
new file mode 100644
index 0000000..60cd09e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/crc32w.c
@@ -0,0 +1,20 @@
+/* Test the crc32w ACLE intrinsic.  */
+
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_crc_ok } */
+/* { dg-options "-save-temps -O0" } */
+/* { dg-add-options arm_crc } */
+
+#include "arm_acle.h"
+
+void test_crc32w (void)
+{
+  uint32_t out_uint32_t;
+  uint32_t arg0_uint32_t;
+  uint32_t arg1_uint32_t;
+
+  out_uint32_t = __crc32w (arg0_uint32_t, arg1_uint32_t);
+}
+
+/* { dg-final { scan-assembler "crc32w\t...?, ...?, ...?\n" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 104818d..a256b12 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2300,6 +2300,14 @@ proc add_options_for_arm_v8_neon { flags } {
     return "$flags $et_arm_v8_neon_flags -march=armv8-a"
 }
 
+proc add_options_for_arm_crc { flags } {
+    if { ! [check_effective_target_arm_crc_ok] } {
+        return "$flags"
+    }
+    global et_arm_crc_flags
+    return "$flags $et_arm_crc_flags"
+}
+
 # Add the options needed for NEON.  We need either -mfloat-abi=softfp
 # or -mfloat-abi=hard, but if one is already specified by the
 # multilib, use it.  Similarly, if a -mfpu option already enables
@@ -2341,6 +2349,21 @@ proc check_effective_target_arm_neon_ok { } {
 		check_effective_target_arm_neon_ok_nocache]
 }
 
+proc check_effective_target_arm_crc_ok_nocache { } {
+    global et_arm_crc_flags
+    set et_arm_crc_flags "-march=armv8-a+crc"
+    return [check_no_compiler_messages_nocache arm_crc_ok object {
+	#if !defined (__ARM_FEATURE_CRC32)
+	#error FOO
+	#endif
+    } "$et_arm_crc_flags"]
+}
+
+proc check_effective_target_arm_crc_ok { } {
+    return [check_cached_effective_target arm_crc_ok \
+		check_effective_target_arm_crc_ok_nocache]
+}
+
 # Return 1 if this is an ARM target supporting -mfpu=neon-fp16
 # -mfloat-abi=softfp or equivalent options.  Some multilibs may be
 # incompatible with these options.  Also set et_arm_neon_flags to the

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

* Re: [PATCH][ARM] Implement CRC32 intrinsics for AArch32 in ARMv8-A
  2013-11-19 17:36   ` Kyrill Tkachov
@ 2013-11-26 11:09     ` Kyrill Tkachov
  2013-12-03 13:46       ` Kyrill Tkachov
  0 siblings, 1 reply; 8+ messages in thread
From: Kyrill Tkachov @ 2013-11-26 11:09 UTC (permalink / raw)
  To: Kyrill Tkachov
  Cc: Joseph S. Myers, GCC Patches, Ramana Radhakrishnan, Richard Earnshaw

Ping?

Thanks,
Kyrill

On 19/11/13 17:04, Kyrill Tkachov wrote:
> On 19/11/13 16:26, Joseph S. Myers wrote:
>> In any target header installed for user use, such as arm_acle.h, you need
>> to be namespace-clean.  In this case, that means you need to use
>> implementation-namespace identifiers such as __a, __b and __d in case the
>> user has defined macros with names such as a, b and d (unless the ACLE
>> says that identifiers a, b and d are in the implementation's namespace
>> when this header is included, which would be a very odd thing for it to
>> do).
>>
> Hi Joseph,
>
> Thanks for the catch. ACLE doesn't expect a,b,d to be in the implementation
> namespace. I've added underscores before them.
>
> Made sure tests pass.
>
> Revised patch attached.
> How's this?
>
> Kyrill
>
> gcc/
> 2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>
>       * Makefile.in (TEXI_GCC_FILES): Add arm-acle-intrinsics.texi.
>       * config.gcc (extra_headers): Add arm_acle.h.
>       * config/arm/arm.c (FL_CRC32): Define.
>       (arm_have_crc): Likewise.
>       (arm_option_override): Set arm_have_crc.
>       (arm_builtins): Add CRC32 builtins.
>       (bdesc_2arg): Likewise.
>       (arm_init_crc32_builtins): New function.
>       (arm_init_builtins): Initialise CRC32 builtins.
>       (arm_file_start): Handle architecture extensions.
>       * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __ARM_FEATURE_CRC32.
>       Define __ARM_32BIT_STATE.
>       (TARGET_CRC32): Define.
>       * config/arm/arm-arches.def: Add armv8-a+crc.
>       * config/arm/arm-tables.opt: Regenerate.
>       * config/arm/arm.md (type): Add crc.
>       (<crc_variant>): New insn.
>       * config/arm/arm_acle.h: New file.
>       * config/arm/iterators.md (CRC): New int iterator.
>       (crc_variant, crc_mode): New int attributes.
>       * confg/arm/unspecs.md (UNSPEC_CRC32B, UNSPEC_CRC32H, UNSPEC_CRC32W,
>       UNSPEC_CRC32CB, UNSPEC_CRC32CH, UNSPEC_CRC32CW): New unspecs.
>       * doc/invoke.texi: Document -march=armv8-a+crc option.
>       * doc/extend.texi: Document ACLE intrinsics.
>       * doc/arm-acle-intrinsics.texi: New.
>
>
> gcc/testsuite
> 2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>
>       * lib/target-supports.exp (add_options_for_arm_crc): New procedure.
>       (check_effective_target_arm_crc_ok_nocache): Likewise.
>       (check_effective_target_arm_crc_ok): Likewise.
>       * gcc.target/arm/acle/: New directory.
>       * gcc.target/arm/acle/acle.exp: New.
>       * gcc.target/arm/acle/crc32b.c: New test.
>       * gcc.target/arm/acle/crc32h.c: Likewise.
>       * gcc.target/arm/acle/crc32w.c: Likewise.
>       * gcc.target/arm/acle/crc32d.c: Likewise.
>       * gcc.target/arm/acle/crc32cb.c: Likewise.
>       * gcc.target/arm/acle/crc32ch.c: Likewise.
>       * gcc.target/arm/acle/crc32cw.c: Likewise.
>       * gcc.target/arm/acle/crc32cd.c: Likewise.


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

* Re: [PATCH][ARM] Implement CRC32 intrinsics for AArch32 in ARMv8-A
  2013-11-26 11:09     ` Kyrill Tkachov
@ 2013-12-03 13:46       ` Kyrill Tkachov
  2013-12-18 15:32         ` Ramana Radhakrishnan
  0 siblings, 1 reply; 8+ messages in thread
From: Kyrill Tkachov @ 2013-12-03 13:46 UTC (permalink / raw)
  To: Kyrill Tkachov; +Cc: GCC Patches, Ramana Radhakrishnan, Richard Earnshaw

Ping?
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02351.html

Thanks,
Kyrill

On 26/11/13 09:44, Kyrill Tkachov wrote:
> Ping?
>
> Thanks,
> Kyrill
>
> On 19/11/13 17:04, Kyrill Tkachov wrote:
>> On 19/11/13 16:26, Joseph S. Myers wrote:
>>> In any target header installed for user use, such as arm_acle.h, you need
>>> to be namespace-clean.  In this case, that means you need to use
>>> implementation-namespace identifiers such as __a, __b and __d in case the
>>> user has defined macros with names such as a, b and d (unless the ACLE
>>> says that identifiers a, b and d are in the implementation's namespace
>>> when this header is included, which would be a very odd thing for it to
>>> do).
>>>
>> Hi Joseph,
>>
>> Thanks for the catch. ACLE doesn't expect a,b,d to be in the implementation
>> namespace. I've added underscores before them.
>>
>> Made sure tests pass.
>>
>> Revised patch attached.
>> How's this?
>>
>> Kyrill
>>
>> gcc/
>> 2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>
>>        * Makefile.in (TEXI_GCC_FILES): Add arm-acle-intrinsics.texi.
>>        * config.gcc (extra_headers): Add arm_acle.h.
>>        * config/arm/arm.c (FL_CRC32): Define.
>>        (arm_have_crc): Likewise.
>>        (arm_option_override): Set arm_have_crc.
>>        (arm_builtins): Add CRC32 builtins.
>>        (bdesc_2arg): Likewise.
>>        (arm_init_crc32_builtins): New function.
>>        (arm_init_builtins): Initialise CRC32 builtins.
>>        (arm_file_start): Handle architecture extensions.
>>        * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __ARM_FEATURE_CRC32.
>>        Define __ARM_32BIT_STATE.
>>        (TARGET_CRC32): Define.
>>        * config/arm/arm-arches.def: Add armv8-a+crc.
>>        * config/arm/arm-tables.opt: Regenerate.
>>        * config/arm/arm.md (type): Add crc.
>>        (<crc_variant>): New insn.
>>        * config/arm/arm_acle.h: New file.
>>        * config/arm/iterators.md (CRC): New int iterator.
>>        (crc_variant, crc_mode): New int attributes.
>>        * confg/arm/unspecs.md (UNSPEC_CRC32B, UNSPEC_CRC32H, UNSPEC_CRC32W,
>>        UNSPEC_CRC32CB, UNSPEC_CRC32CH, UNSPEC_CRC32CW): New unspecs.
>>        * doc/invoke.texi: Document -march=armv8-a+crc option.
>>        * doc/extend.texi: Document ACLE intrinsics.
>>        * doc/arm-acle-intrinsics.texi: New.
>>
>>
>> gcc/testsuite
>> 2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>
>>        * lib/target-supports.exp (add_options_for_arm_crc): New procedure.
>>        (check_effective_target_arm_crc_ok_nocache): Likewise.
>>        (check_effective_target_arm_crc_ok): Likewise.
>>        * gcc.target/arm/acle/: New directory.
>>        * gcc.target/arm/acle/acle.exp: New.
>>        * gcc.target/arm/acle/crc32b.c: New test.
>>        * gcc.target/arm/acle/crc32h.c: Likewise.
>>        * gcc.target/arm/acle/crc32w.c: Likewise.
>>        * gcc.target/arm/acle/crc32d.c: Likewise.
>>        * gcc.target/arm/acle/crc32cb.c: Likewise.
>>        * gcc.target/arm/acle/crc32ch.c: Likewise.
>>        * gcc.target/arm/acle/crc32cw.c: Likewise.
>>        * gcc.target/arm/acle/crc32cd.c: Likewise.


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

* Re: [PATCH][ARM] Implement CRC32 intrinsics for AArch32 in ARMv8-A
  2013-12-03 13:46       ` Kyrill Tkachov
@ 2013-12-18 15:32         ` Ramana Radhakrishnan
  2013-12-19 17:58           ` Kyrill Tkachov
  0 siblings, 1 reply; 8+ messages in thread
From: Ramana Radhakrishnan @ 2013-12-18 15:32 UTC (permalink / raw)
  To: Kyrill Tkachov; +Cc: GCC Patches, Ramana Radhakrishnan, Richard Earnshaw

On Tue, Dec 3, 2013 at 1:46 PM, Kyrill Tkachov <kyrylo.tkachov@arm.com> wrote:
> Ping?
> http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02351.html
>
> Thanks,
> Kyrill

Ok if no objections in 24 hours.

Ramana

>
>
> On 26/11/13 09:44, Kyrill Tkachov wrote:
>>
>> Ping?
>>
>> Thanks,
>> Kyrill
>>
>> On 19/11/13 17:04, Kyrill Tkachov wrote:
>>>
>>> On 19/11/13 16:26, Joseph S. Myers wrote:
>>>>
>>>> In any target header installed for user use, such as arm_acle.h, you
>>>> need
>>>> to be namespace-clean.  In this case, that means you need to use
>>>> implementation-namespace identifiers such as __a, __b and __d in case
>>>> the
>>>> user has defined macros with names such as a, b and d (unless the ACLE
>>>> says that identifiers a, b and d are in the implementation's namespace
>>>> when this header is included, which would be a very odd thing for it to
>>>> do).
>>>>
>>> Hi Joseph,
>>>
>>> Thanks for the catch. ACLE doesn't expect a,b,d to be in the
>>> implementation
>>> namespace. I've added underscores before them.
>>>
>>> Made sure tests pass.
>>>
>>> Revised patch attached.
>>> How's this?
>>>
>>> Kyrill
>>>
>>> gcc/
>>> 2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>>
>>>        * Makefile.in (TEXI_GCC_FILES): Add arm-acle-intrinsics.texi.
>>>        * config.gcc (extra_headers): Add arm_acle.h.
>>>        * config/arm/arm.c (FL_CRC32): Define.
>>>        (arm_have_crc): Likewise.
>>>        (arm_option_override): Set arm_have_crc.
>>>        (arm_builtins): Add CRC32 builtins.
>>>        (bdesc_2arg): Likewise.
>>>        (arm_init_crc32_builtins): New function.
>>>        (arm_init_builtins): Initialise CRC32 builtins.
>>>        (arm_file_start): Handle architecture extensions.
>>>        * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define
>>> __ARM_FEATURE_CRC32.
>>>        Define __ARM_32BIT_STATE.
>>>        (TARGET_CRC32): Define.
>>>        * config/arm/arm-arches.def: Add armv8-a+crc.
>>>        * config/arm/arm-tables.opt: Regenerate.
>>>        * config/arm/arm.md (type): Add crc.
>>>        (<crc_variant>): New insn.
>>>        * config/arm/arm_acle.h: New file.
>>>        * config/arm/iterators.md (CRC): New int iterator.
>>>        (crc_variant, crc_mode): New int attributes.
>>>        * confg/arm/unspecs.md (UNSPEC_CRC32B, UNSPEC_CRC32H,
>>> UNSPEC_CRC32W,
>>>        UNSPEC_CRC32CB, UNSPEC_CRC32CH, UNSPEC_CRC32CW): New unspecs.
>>>        * doc/invoke.texi: Document -march=armv8-a+crc option.
>>>        * doc/extend.texi: Document ACLE intrinsics.
>>>        * doc/arm-acle-intrinsics.texi: New.
>>>
>>>
>>> gcc/testsuite
>>> 2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>>
>>>        * lib/target-supports.exp (add_options_for_arm_crc): New
>>> procedure.
>>>        (check_effective_target_arm_crc_ok_nocache): Likewise.
>>>        (check_effective_target_arm_crc_ok): Likewise.
>>>        * gcc.target/arm/acle/: New directory.
>>>        * gcc.target/arm/acle/acle.exp: New.
>>>        * gcc.target/arm/acle/crc32b.c: New test.
>>>        * gcc.target/arm/acle/crc32h.c: Likewise.
>>>        * gcc.target/arm/acle/crc32w.c: Likewise.
>>>        * gcc.target/arm/acle/crc32d.c: Likewise.
>>>        * gcc.target/arm/acle/crc32cb.c: Likewise.
>>>        * gcc.target/arm/acle/crc32ch.c: Likewise.
>>>        * gcc.target/arm/acle/crc32cw.c: Likewise.
>>>        * gcc.target/arm/acle/crc32cd.c: Likewise.
>
>
>

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

* Re: [PATCH][ARM] Implement CRC32 intrinsics for AArch32 in ARMv8-A
  2013-12-18 15:32         ` Ramana Radhakrishnan
@ 2013-12-19 17:58           ` Kyrill Tkachov
  2013-12-20 13:56             ` Kyrill Tkachov
  0 siblings, 1 reply; 8+ messages in thread
From: Kyrill Tkachov @ 2013-12-19 17:58 UTC (permalink / raw)
  To: Ramana Radhakrishnan; +Cc: Ramana Radhakrishnan, GCC Patches, Richard Earnshaw

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

On 18/12/13 15:32, Ramana Radhakrishnan wrote:
> On Tue, Dec 3, 2013 at 1:46 PM, Kyrill Tkachov <kyrylo.tkachov@arm.com> wrote:
>> Ping?
>> http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02351.html
>>
>> Thanks,
>> Kyrill
> Ok if no objections in 24 hours.

Thanks Ramana, I've committed it as r206128 together with this obvious change 
that sets the conds attribute on the md pattern.

Kyrill


>
> Ramana
>
>>
>> On 26/11/13 09:44, Kyrill Tkachov wrote:
>>> Ping?
>>>
>>> Thanks,
>>> Kyrill
>>>
>>> On 19/11/13 17:04, Kyrill Tkachov wrote:
>>>> On 19/11/13 16:26, Joseph S. Myers wrote:
>>>>> In any target header installed for user use, such as arm_acle.h, you
>>>>> need
>>>>> to be namespace-clean.  In this case, that means you need to use
>>>>> implementation-namespace identifiers such as __a, __b and __d in case
>>>>> the
>>>>> user has defined macros with names such as a, b and d (unless the ACLE
>>>>> says that identifiers a, b and d are in the implementation's namespace
>>>>> when this header is included, which would be a very odd thing for it to
>>>>> do).
>>>>>
>>>> Hi Joseph,
>>>>
>>>> Thanks for the catch. ACLE doesn't expect a,b,d to be in the
>>>> implementation
>>>> namespace. I've added underscores before them.
>>>>
>>>> Made sure tests pass.
>>>>
>>>> Revised patch attached.
>>>> How's this?
>>>>
>>>> Kyrill
>>>>
>>>> gcc/
>>>> 2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>>>
>>>>         * Makefile.in (TEXI_GCC_FILES): Add arm-acle-intrinsics.texi.
>>>>         * config.gcc (extra_headers): Add arm_acle.h.
>>>>         * config/arm/arm.c (FL_CRC32): Define.
>>>>         (arm_have_crc): Likewise.
>>>>         (arm_option_override): Set arm_have_crc.
>>>>         (arm_builtins): Add CRC32 builtins.
>>>>         (bdesc_2arg): Likewise.
>>>>         (arm_init_crc32_builtins): New function.
>>>>         (arm_init_builtins): Initialise CRC32 builtins.
>>>>         (arm_file_start): Handle architecture extensions.
>>>>         * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define
>>>> __ARM_FEATURE_CRC32.
>>>>         Define __ARM_32BIT_STATE.
>>>>         (TARGET_CRC32): Define.
>>>>         * config/arm/arm-arches.def: Add armv8-a+crc.
>>>>         * config/arm/arm-tables.opt: Regenerate.
>>>>         * config/arm/arm.md (type): Add crc.
>>>>         (<crc_variant>): New insn.
>>>>         * config/arm/arm_acle.h: New file.
>>>>         * config/arm/iterators.md (CRC): New int iterator.
>>>>         (crc_variant, crc_mode): New int attributes.
>>>>         * confg/arm/unspecs.md (UNSPEC_CRC32B, UNSPEC_CRC32H,
>>>> UNSPEC_CRC32W,
>>>>         UNSPEC_CRC32CB, UNSPEC_CRC32CH, UNSPEC_CRC32CW): New unspecs.
>>>>         * doc/invoke.texi: Document -march=armv8-a+crc option.
>>>>         * doc/extend.texi: Document ACLE intrinsics.
>>>>         * doc/arm-acle-intrinsics.texi: New.
>>>>
>>>>
>>>> gcc/testsuite
>>>> 2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>>>
>>>>         * lib/target-supports.exp (add_options_for_arm_crc): New
>>>> procedure.
>>>>         (check_effective_target_arm_crc_ok_nocache): Likewise.
>>>>         (check_effective_target_arm_crc_ok): Likewise.
>>>>         * gcc.target/arm/acle/: New directory.
>>>>         * gcc.target/arm/acle/acle.exp: New.
>>>>         * gcc.target/arm/acle/crc32b.c: New test.
>>>>         * gcc.target/arm/acle/crc32h.c: Likewise.
>>>>         * gcc.target/arm/acle/crc32w.c: Likewise.
>>>>         * gcc.target/arm/acle/crc32d.c: Likewise.
>>>>         * gcc.target/arm/acle/crc32cb.c: Likewise.
>>>>         * gcc.target/arm/acle/crc32ch.c: Likewise.
>>>>         * gcc.target/arm/acle/crc32cw.c: Likewise.
>>>>         * gcc.target/arm/acle/crc32cd.c: Likewise.
>>
>>

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

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 397df01..e8b8125 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -12880,7 +12880,8 @@
          CRC))]
   "TARGET_CRC32"
   "<crc_variant>\\t%0, %1, %2"
-  [(set_attr "type" "crc")]
+  [(set_attr "type" "crc")
+   (set_attr "conds" "unconditional")]
 )
 
 ;; Load the load/store double peephole optimizations.

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

* Re: [PATCH][ARM] Implement CRC32 intrinsics for AArch32 in ARMv8-A
  2013-12-19 17:58           ` Kyrill Tkachov
@ 2013-12-20 13:56             ` Kyrill Tkachov
  0 siblings, 0 replies; 8+ messages in thread
From: Kyrill Tkachov @ 2013-12-20 13:56 UTC (permalink / raw)
  To: Kyrill Tkachov
  Cc: Ramana Radhakrishnan, Ramana Radhakrishnan, GCC Patches,
	Richard Earnshaw

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

On 19/12/13 17:58, Kyrill Tkachov wrote:
> On 18/12/13 15:32, Ramana Radhakrishnan wrote:
>> On Tue, Dec 3, 2013 at 1:46 PM, Kyrill Tkachov <kyrylo.tkachov@arm.com> wrote:
>>> Ping?
>>> http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02351.html
>>>
>>> Thanks,
>>> Kyrill
>> Ok if no objections in 24 hours.
> Thanks Ramana, I've committed it as r206128 together with this obvious change
> that sets the conds attribute on the md pattern.

I just noticed that I committed the first version of the patch posted at:
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02250.html

instead of the second version posted at:
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02351.html

that was approved. The difference is only that the second one has underscores 
under the variable names in arm_acle.h.

I've committed the attached patch to add them as obvious with r206149. Tested 
arm-none-eabi on a model.

Sorry for the noise,
Kyrill

2013-12-20  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     * config/arm/arm_acle.h: Add underscores before variables.

>
> Kyrill
>
>
>> Ramana
>>
>>> On 26/11/13 09:44, Kyrill Tkachov wrote:
>>>> Ping?
>>>>
>>>> Thanks,
>>>> Kyrill
>>>>
>>>> On 19/11/13 17:04, Kyrill Tkachov wrote:
>>>>> On 19/11/13 16:26, Joseph S. Myers wrote:
>>>>>> In any target header installed for user use, such as arm_acle.h, you
>>>>>> need
>>>>>> to be namespace-clean.  In this case, that means you need to use
>>>>>> implementation-namespace identifiers such as __a, __b and __d in case
>>>>>> the
>>>>>> user has defined macros with names such as a, b and d (unless the ACLE
>>>>>> says that identifiers a, b and d are in the implementation's namespace
>>>>>> when this header is included, which would be a very odd thing for it to
>>>>>> do).
>>>>>>
>>>>> Hi Joseph,
>>>>>
>>>>> Thanks for the catch. ACLE doesn't expect a,b,d to be in the
>>>>> implementation
>>>>> namespace. I've added underscores before them.
>>>>>
>>>>> Made sure tests pass.
>>>>>
>>>>> Revised patch attached.
>>>>> How's this?
>>>>>
>>>>> Kyrill
>>>>>
>>>>> gcc/
>>>>> 2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>>>>
>>>>>          * Makefile.in (TEXI_GCC_FILES): Add arm-acle-intrinsics.texi.
>>>>>          * config.gcc (extra_headers): Add arm_acle.h.
>>>>>          * config/arm/arm.c (FL_CRC32): Define.
>>>>>          (arm_have_crc): Likewise.
>>>>>          (arm_option_override): Set arm_have_crc.
>>>>>          (arm_builtins): Add CRC32 builtins.
>>>>>          (bdesc_2arg): Likewise.
>>>>>          (arm_init_crc32_builtins): New function.
>>>>>          (arm_init_builtins): Initialise CRC32 builtins.
>>>>>          (arm_file_start): Handle architecture extensions.
>>>>>          * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define
>>>>> __ARM_FEATURE_CRC32.
>>>>>          Define __ARM_32BIT_STATE.
>>>>>          (TARGET_CRC32): Define.
>>>>>          * config/arm/arm-arches.def: Add armv8-a+crc.
>>>>>          * config/arm/arm-tables.opt: Regenerate.
>>>>>          * config/arm/arm.md (type): Add crc.
>>>>>          (<crc_variant>): New insn.
>>>>>          * config/arm/arm_acle.h: New file.
>>>>>          * config/arm/iterators.md (CRC): New int iterator.
>>>>>          (crc_variant, crc_mode): New int attributes.
>>>>>          * confg/arm/unspecs.md (UNSPEC_CRC32B, UNSPEC_CRC32H,
>>>>> UNSPEC_CRC32W,
>>>>>          UNSPEC_CRC32CB, UNSPEC_CRC32CH, UNSPEC_CRC32CW): New unspecs.
>>>>>          * doc/invoke.texi: Document -march=armv8-a+crc option.
>>>>>          * doc/extend.texi: Document ACLE intrinsics.
>>>>>          * doc/arm-acle-intrinsics.texi: New.
>>>>>
>>>>>
>>>>> gcc/testsuite
>>>>> 2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
>>>>>
>>>>>          * lib/target-supports.exp (add_options_for_arm_crc): New
>>>>> procedure.
>>>>>          (check_effective_target_arm_crc_ok_nocache): Likewise.
>>>>>          (check_effective_target_arm_crc_ok): Likewise.
>>>>>          * gcc.target/arm/acle/: New directory.
>>>>>          * gcc.target/arm/acle/acle.exp: New.
>>>>>          * gcc.target/arm/acle/crc32b.c: New test.
>>>>>          * gcc.target/arm/acle/crc32h.c: Likewise.
>>>>>          * gcc.target/arm/acle/crc32w.c: Likewise.
>>>>>          * gcc.target/arm/acle/crc32d.c: Likewise.
>>>>>          * gcc.target/arm/acle/crc32cb.c: Likewise.
>>>>>          * gcc.target/arm/acle/crc32ch.c: Likewise.
>>>>>          * gcc.target/arm/acle/crc32cw.c: Likewise.
>>>>>          * gcc.target/arm/acle/crc32cd.c: Likewise.
>> >

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

Index: gcc/config/arm/arm_acle.h
===================================================================
--- gcc/config/arm/arm_acle.h	(revision 206132)
+++ gcc/config/arm/arm_acle.h	(working copy)
@@ -34,60 +34,60 @@
 
 #ifdef __ARM_FEATURE_CRC32
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
-__crc32b (uint32_t a, uint8_t b)
+__crc32b (uint32_t __a, uint8_t __b)
 {
-  return __builtin_arm_crc32b (a, b);
+  return __builtin_arm_crc32b (__a, __b);
 }
 
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
-__crc32h (uint32_t a, uint16_t b)
+__crc32h (uint32_t __a, uint16_t __b)
 {
-  return __builtin_arm_crc32h (a, b);
+  return __builtin_arm_crc32h (__a, __b);
 }
 
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
-__crc32w (uint32_t a, uint32_t b)
+__crc32w (uint32_t __a, uint32_t __b)
 {
-  return __builtin_arm_crc32w (a, b);
+  return __builtin_arm_crc32w (__a, __b);
 }
 
 #ifdef __ARM_32BIT_STATE
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
-__crc32d (uint32_t a, uint64_t b)
+__crc32d (uint32_t __a, uint64_t __b)
 {
-  uint32_t d;
+  uint32_t __d;
 
-  d = __crc32w (__crc32w (a, b & 0xffffffffULL), b >> 32);
-  return d;
+  __d = __crc32w (__crc32w (__a, __b & 0xffffffffULL), __b >> 32);
+  return __d;
 }
 #endif
 
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
-__crc32cb (uint32_t a, uint8_t b)
+__crc32cb (uint32_t __a, uint8_t __b)
 {
-  return __builtin_arm_crc32cb (a, b);
+  return __builtin_arm_crc32cb (__a, __b);
 }
 
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
-__crc32ch (uint32_t a, uint16_t b)
+__crc32ch (uint32_t __a, uint16_t __b)
 {
-  return __builtin_arm_crc32ch (a, b);
+  return __builtin_arm_crc32ch (__a, __b);
 }
 
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
-__crc32cw (uint32_t a, uint32_t b)
+__crc32cw (uint32_t __a, uint32_t __b)
 {
-  return __builtin_arm_crc32cw (a, b);
+  return __builtin_arm_crc32cw (__a, __b);
 }
 
 #ifdef __ARM_32BIT_STATE
 __extension__ static __inline uint32_t __attribute__ ((__always_inline__))
-__crc32cd (uint32_t a, uint64_t b)
+__crc32cd (uint32_t __a, uint64_t __b)
 {
-  uint32_t d;
+  uint32_t __d;
 
-  d = __crc32cw (__crc32cw (a, b & 0xffffffffULL), b >> 32);
-  return d;
+  __d = __crc32cw (__crc32cw (__a, __b & 0xffffffffULL), __b >> 32);
+  return __d;
 }
 #endif
 

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

end of thread, other threads:[~2013-12-20 13:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-19 12:22 [PATCH][ARM] Implement CRC32 intrinsics for AArch32 in ARMv8-A Kyrill Tkachov
2013-11-19 16:56 ` Joseph S. Myers
2013-11-19 17:36   ` Kyrill Tkachov
2013-11-26 11:09     ` Kyrill Tkachov
2013-12-03 13:46       ` Kyrill Tkachov
2013-12-18 15:32         ` Ramana Radhakrishnan
2013-12-19 17:58           ` Kyrill Tkachov
2013-12-20 13:56             ` Kyrill Tkachov

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).