From: Kyrylo Tkachov Date: Thu, 19 Dec 2013 17:55:38 +0000 (+0000) Subject: Makefile.in (TEXI_GCC_FILES): Add arm-acle-intrinsics.texi. X-Git-Tag: upstream/12.2.0~65786 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=582e2e430089a54069f3e38eb8a2bacd36c42af5;p=platform%2Fupstream%2Fgcc.git Makefile.in (TEXI_GCC_FILES): Add arm-acle-intrinsics.texi. [gcc/] 2013-12-19 Kyrylo Tkachov * 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. (): 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. [gcc/testsuite/] 2013-12-19 Kyrylo Tkachov * 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. From-SVN: r206128 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7786c66..5729893 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2013-12-19 Kyrylo Tkachov + + * 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. + (): 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. + 2013-12-19 Charles Baylis PR target/59142 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 0d09ba9..b79bb0c 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2794,7 +2794,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 8464d8f..fbfc121 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 702338c..3a17c2c 100644 --- a/gcc/config/arm/arm-tables.opt +++ b/gcc/config/arm/arm-tables.opt @@ -371,10 +371,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 8fea2a6..be9044e 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". */ @@ -901,6 +902,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[] = { @@ -2480,6 +2484,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; @@ -23139,6 +23144,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 @@ -23718,7 +23730,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) \ @@ -23824,6 +23836,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[] = @@ -24243,6 +24266,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) @@ -24253,6 +24312,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. */ @@ -27526,7 +27588,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 7b5a7f9..e02b2ad 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 @@ -561,6 +567,9 @@ extern int prefer_neon_for_64bits; extern bool arm_disable_literal_pool; #endif +/* 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 6e1b47d..0440ce6 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -12870,6 +12870,17 @@ (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")]) +;; ARMv8 CRC32 instructions. +(define_insn "" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "s_register_operand" "r") + (match_operand: 2 "s_register_operand" "r")] + CRC))] + "TARGET_CRC32" + "\\t%0, %1, %2" + [(set_attr "type" "crc") + (set_attr "conds" "unconditional")] +) ;; 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 + . */ + +#ifndef _GCC_ARM_ACLE_H +#define _GCC_ARM_ACLE_H + +#include +#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 66779a7..ff5462c 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 ;;---------------------------------------------------------------------------- @@ -518,6 +521,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 0ff9b08f..40c4a78 100644 --- a/gcc/config/arm/types.md +++ b/gcc/config/arm/types.md @@ -554,6 +554,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 2ce0098..d539bd1 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -9016,6 +9016,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:: @@ -9708,6 +9709,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 6e888bd..689b3ab 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -12228,9 +12228,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/ChangeLog b/gcc/testsuite/ChangeLog index 8d61415..318550a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,21 @@ 2013-12-19 Kyrylo Tkachov + * 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. + +2013-12-19 Kyrylo Tkachov + * c-c++-common/cilk-plus/SE/ef_error.c: Use -fopen-simd. 2013-12-19 Oleg Endo 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 +# . + +# 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..60cd09e --- /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 642c344..0f9ef4c 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -2327,6 +2327,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 @@ -2368,6 +2376,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