From: Sudakshina Das Date: Wed, 31 Jul 2019 09:19:53 +0000 (+0000) Subject: [GCC, AArch64] Enable Transactional Memory Extension X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=89626179b6fe42cbd58c715808f7c6401879757f;p=gcc.git [GCC, AArch64] Enable Transactional Memory Extension This patch enables the new Transactional Memory Extension announced recently as part of Arm's new architecture technologies. We introduce a new optional extension "tme" to enable this. The following instructions are part of the extension: * tstart * ttest * tcommit * tcancel # We have also added ACLE intrinsics for the instructions. *** gcc/ChangeLog *** 2019-07-31 Sudakshina Das * config/aarch64/aarch64-builtins.c (enum aarch64_builtins): Add AARCH64_TME_BUILTIN_TSTART, AARCH64_TME_BUILTIN_TCOMMIT, AARCH64_TME_BUILTIN_TTEST and AARCH64_TME_BUILTIN_TCANCEL. (aarch64_init_tme_builtins): New. (aarch64_init_builtins): Call aarch64_init_tme_builtins. (aarch64_expand_builtin_tme): New. (aarch64_expand_builtin): Handle TME builtins. * config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Define __ARM_FEATURE_TME when enabled. * config/aarch64/aarch64-option-extensions.def: Add "tme". * config/aarch64/aarch64.h (AARCH64_FL_TME, AARCH64_ISA_TME): New. (TARGET_TME): New. * config/aarch64/aarch64.md (define_c_enum "unspec"): Add UNSPEC_TTEST. (define_c_enum "unspecv"): Add UNSPECV_TSTART, UNSPECV_TCOMMIT and UNSPECV_TCANCEL. (tstart, ttest, tcommit, tcancel): New instructions. * config/aarch64/arm_acle.h (__tstart, __tcommit): New. (__tcancel, __ttest): New. (_TMFAILURE_REASON, _TMFAILURE_RTRY, _TMFAILURE_CNCL): New macro. (_TMFAILURE_MEM, _TMFAILURE_IMP, _TMFAILURE_ERR): Likewise. (_TMFAILURE_SIZE, _TMFAILURE_NEST, _TMFAILURE_DBG): Likewise. (_TMFAILURE_INT, _TMFAILURE_TRIVIAL): Likewise. * config/arm/types.md: Add new tme type attr. * doc/invoke.texi: Document "tme". *** gcc/testsuite/ChangeLog *** 2019-07-31 Sudakshina Das * gcc.target/aarch64/acle/tme.c: New test. * gcc.target/aarch64/pragma_cpp_predefs_2.c: New test. From-SVN: r273926 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index af3089a8a55..3e166c3f3af 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2019-07-31 Sudakshina Das + + * config/aarch64/aarch64-builtins.c (enum aarch64_builtins): Add + AARCH64_TME_BUILTIN_TSTART, AARCH64_TME_BUILTIN_TCOMMIT, + AARCH64_TME_BUILTIN_TTEST and AARCH64_TME_BUILTIN_TCANCEL. + (aarch64_init_tme_builtins): New. + (aarch64_init_builtins): Call aarch64_init_tme_builtins. + (aarch64_expand_builtin_tme): New. + (aarch64_expand_builtin): Handle TME builtins. + * config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Define + __ARM_FEATURE_TME when enabled. + * config/aarch64/aarch64-option-extensions.def: Add "tme". + * config/aarch64/aarch64.h (AARCH64_FL_TME, AARCH64_ISA_TME): New. + (TARGET_TME): New. + * config/aarch64/aarch64.md (define_c_enum "unspec"): Add UNSPEC_TTEST. + (define_c_enum "unspecv"): Add UNSPECV_TSTART, UNSPECV_TCOMMIT and + UNSPECV_TCANCEL. + (tstart, ttest, tcommit, tcancel): New instructions. + * config/aarch64/arm_acle.h (__tstart, __tcommit): New. + (__tcancel, __ttest): New. + (_TMFAILURE_REASON, _TMFAILURE_RTRY, _TMFAILURE_CNCL): New macro. + (_TMFAILURE_MEM, _TMFAILURE_IMP, _TMFAILURE_ERR): Likewise. + (_TMFAILURE_SIZE, _TMFAILURE_NEST, _TMFAILURE_DBG): Likewise. + (_TMFAILURE_INT, _TMFAILURE_TRIVIAL): Likewise. + * config/arm/types.md: Add new tme type attr. + * doc/invoke.texi: Document "tme". + 2019-07-31 Joel Hutton * config/arm/arm_cmse.h (cmse_nonsecure_caller): Add diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index 549a6c24924..16c1d42ea2b 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -438,6 +438,11 @@ enum aarch64_builtins /* Special cased Armv8.3-A Complex FMA by Lane quad Builtins. */ AARCH64_SIMD_FCMLA_LANEQ_BUILTIN_BASE, AARCH64_SIMD_FCMLA_LANEQ_BUILTINS + /* TME builtins. */ + AARCH64_TME_BUILTIN_TSTART, + AARCH64_TME_BUILTIN_TCOMMIT, + AARCH64_TME_BUILTIN_TTEST, + AARCH64_TME_BUILTIN_TCANCEL, AARCH64_BUILTIN_MAX }; @@ -1067,6 +1072,35 @@ aarch64_init_pauth_hint_builtins (void) NULL_TREE); } +/* Initialize the transactional memory extension (TME) builtins. */ +static void +aarch64_init_tme_builtins (void) +{ + tree ftype_uint64_void + = build_function_type_list (uint64_type_node, NULL); + tree ftype_void_void + = build_function_type_list (void_type_node, NULL); + tree ftype_void_uint64 + = build_function_type_list (void_type_node, uint64_type_node, NULL); + + aarch64_builtin_decls[AARCH64_TME_BUILTIN_TSTART] + = add_builtin_function ("__builtin_aarch64_tstart", ftype_uint64_void, + AARCH64_TME_BUILTIN_TSTART, BUILT_IN_MD, + NULL, NULL_TREE); + aarch64_builtin_decls[AARCH64_TME_BUILTIN_TTEST] + = add_builtin_function ("__builtin_aarch64_ttest", ftype_uint64_void, + AARCH64_TME_BUILTIN_TTEST, BUILT_IN_MD, + NULL, NULL_TREE); + aarch64_builtin_decls[AARCH64_TME_BUILTIN_TCOMMIT] + = add_builtin_function ("__builtin_aarch64_tcommit", ftype_void_void, + AARCH64_TME_BUILTIN_TCOMMIT, BUILT_IN_MD, + NULL, NULL_TREE); + aarch64_builtin_decls[AARCH64_TME_BUILTIN_TCANCEL] + = add_builtin_function ("__builtin_aarch64_tcancel", ftype_void_uint64, + AARCH64_TME_BUILTIN_TCANCEL, BUILT_IN_MD, + NULL, NULL_TREE); +} + void aarch64_init_builtins (void) { @@ -1104,6 +1138,9 @@ aarch64_init_builtins (void) register them. */ if (!TARGET_ILP32) aarch64_init_pauth_hint_builtins (); + + if (TARGET_TME) + aarch64_init_tme_builtins (); } tree @@ -1507,6 +1544,47 @@ aarch64_expand_fcmla_builtin (tree exp, rtx target, int fcode) return target; } +/* Function to expand an expression EXP which calls one of the Transactional + Memory Extension (TME) builtins FCODE with the result going to TARGET. */ +static rtx +aarch64_expand_builtin_tme (int fcode, tree exp, rtx target) +{ + switch (fcode) + { + case AARCH64_TME_BUILTIN_TSTART: + target = gen_reg_rtx (DImode); + emit_insn (GEN_FCN (CODE_FOR_tstart) (target)); + break; + + case AARCH64_TME_BUILTIN_TTEST: + target = gen_reg_rtx (DImode); + emit_insn (GEN_FCN (CODE_FOR_ttest) (target)); + break; + + case AARCH64_TME_BUILTIN_TCOMMIT: + emit_insn (GEN_FCN (CODE_FOR_tcommit) ()); + break; + + case AARCH64_TME_BUILTIN_TCANCEL: + { + tree arg0 = CALL_EXPR_ARG (exp, 0); + rtx op0 = expand_normal (arg0); + if (CONST_INT_P (op0) && UINTVAL (op0) <= 65536) + emit_insn (GEN_FCN (CODE_FOR_tcancel) (op0)); + else + { + error ("%Kargument must be a 16-bit constant immediate", exp); + return const0_rtx; + } + } + break; + + default : + gcc_unreachable (); + } + return target; +} + /* Expand an expression EXP that calls a built-in function, with result going to TARGET if that's convenient. */ rtx @@ -1627,6 +1705,12 @@ aarch64_expand_builtin (tree exp, || fcode == AARCH64_BUILTIN_RSQRT_V4SF) return aarch64_expand_builtin_rsqrt (fcode, exp, target); + if (fcode == AARCH64_TME_BUILTIN_TSTART + || fcode == AARCH64_TME_BUILTIN_TCOMMIT + || fcode == AARCH64_TME_BUILTIN_TTEST + || fcode == AARCH64_TME_BUILTIN_TCANCEL) + return aarch64_expand_builtin_tme (fcode, exp, target); + gcc_unreachable (); } diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c index 5af65b1d2f3..e532c6cd142 100644 --- a/gcc/config/aarch64/aarch64-c.c +++ b/gcc/config/aarch64/aarch64-c.c @@ -157,6 +157,8 @@ aarch64_update_cpp_builtins (cpp_reader *pfile) aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM4", pfile); aarch64_def_or_undef (TARGET_F16FML, "__ARM_FEATURE_FP16_FML", pfile); + aarch64_def_or_undef (TARGET_TME, "__ARM_FEATURE_TME", pfile); + /* Not for ACLE, but required to keep "float.h" correct if we switch target between implementations that do or do not support ARMv8.2-A 16-bit floating-point extensions. */ diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def index d427de25046..9919edd43d0 100644 --- a/gcc/config/aarch64/aarch64-option-extensions.def +++ b/gcc/config/aarch64/aarch64-option-extensions.def @@ -195,4 +195,7 @@ AARCH64_OPT_EXTENSION("sve2-bitperm", AARCH64_FL_SVE2_BITPERM, AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | \ AARCH64_FL_SVE2, 0, false, "") +/* Enabling or disabling "tme" only changes "tme". */ +AARCH64_OPT_EXTENSION("tme", AARCH64_FL_TME, 0, 0, false, "") + #undef AARCH64_OPT_EXTENSION diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 92e38a87a76..34fca9003cc 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -199,6 +199,9 @@ extern unsigned aarch64_architecture_version; #define AARCH64_FL_SVE2_SHA3 (1ULL << 31) #define AARCH64_FL_SVE2_BITPERM (1ULL << 32) +/* Transactional Memory Extension. */ +#define AARCH64_FL_TME (1ULL << 33) /* Has TME instructions. */ + /* Has FP and SIMD. */ #define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD) @@ -243,6 +246,7 @@ extern unsigned aarch64_architecture_version; #define AARCH64_ISA_F16FML (aarch64_isa_flags & AARCH64_FL_F16FML) #define AARCH64_ISA_RCPC8_4 (aarch64_isa_flags & AARCH64_FL_RCPC8_4) #define AARCH64_ISA_V8_5 (aarch64_isa_flags & AARCH64_FL_V8_5) +#define AARCH64_ISA_TME (aarch64_isa_flags & AARCH64_FL_TME) /* Crypto is an optional extension to AdvSIMD. */ #define TARGET_CRYPTO (TARGET_SIMD && AARCH64_ISA_CRYPTO) @@ -287,6 +291,9 @@ extern unsigned aarch64_architecture_version; /* Armv8.3-a Complex number extension to AdvSIMD extensions. */ #define TARGET_COMPLEX (TARGET_SIMD && TARGET_ARMV8_3) +/* TME instructions are enabled. */ +#define TARGET_TME (AARCH64_ISA_TME) + /* Make sure this is always defined so we don't have to check for ifdefs but rather use normal ifs. */ #ifndef TARGET_FIX_ERR_A53_835769_DEFAULT diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index d1b2c20104d..873f2760cce 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -236,6 +236,7 @@ UNSPEC_REV_SUBREG UNSPEC_SPECULATION_TRACKER UNSPEC_COPYSIGN + UNSPEC_TTEST ; Represent transaction test. ]) (define_c_enum "unspecv" [ @@ -251,6 +252,9 @@ UNSPECV_BTI_C ; Represent BTI c. UNSPECV_BTI_J ; Represent BTI j. UNSPECV_BTI_JC ; Represent BTI jc. + UNSPECV_TSTART ; Represent transaction start. + UNSPECV_TCOMMIT ; Represent transaction commit. + UNSPECV_TCANCEL ; Represent transaction cancel. ] ) @@ -7242,6 +7246,43 @@ (set_attr "speculation_barrier" "true")] ) +;; Transactional Memory Extension (TME) instructions. + +(define_insn "tstart" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec_volatile:DI [(const_int 0)] UNSPECV_TSTART)) + (clobber (mem:BLK (scratch)))] + "TARGET_TME" + "tstart\\t%0" + [(set_attr "type" "tme")] +) + +(define_insn "ttest" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec_volatile:DI [(const_int 0)] UNSPEC_TTEST)) + (clobber (mem:BLK (scratch)))] + "TARGET_TME" + "ttest\\t%0" + [(set_attr "type" "tme")] +) + +(define_insn "tcommit" + [(unspec_volatile:BLK [(const_int 0)] UNSPECV_TCOMMIT) + (clobber (mem:BLK (scratch)))] + "TARGET_TME" + "tcommit" + [(set_attr "type" "tme")] +) + +(define_insn "tcancel" + [(unspec_volatile:BLK + [(match_operand 0 "const_int_operand" "n")] UNSPECV_TCANCEL) + (clobber (mem:BLK (scratch)))] + "TARGET_TME && (UINTVAL (operands[0]) <= 65535)" + "tcancel\\t#%0" + [(set_attr "type" "tme")] +) + ;; AdvSIMD Stuff (include "aarch64-simd.md") diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h index 534a989c39a..d4de691eec5 100644 --- a/gcc/config/aarch64/arm_acle.h +++ b/gcc/config/aarch64/arm_acle.h @@ -29,14 +29,14 @@ #include -#pragma GCC push_options - -#pragma GCC target ("+nothing+crc") - #ifdef __cplusplus extern "C" { #endif +#pragma GCC push_options + +#pragma GCC target ("+nothing+crc") + __extension__ static __inline uint32_t __attribute__ ((__always_inline__)) __crc32b (uint32_t __a, uint8_t __b) { @@ -85,10 +85,53 @@ __crc32d (uint32_t __a, uint64_t __b) return __builtin_aarch64_crc32x (__a, __b); } -#ifdef __cplusplus +#pragma GCC pop_options + +#ifdef __ARM_FEATURE_TME +#pragma GCC push_options +#pragma GCC target ("+nothing+tme") + +#define _TMFAILURE_REASON 0x00007fffu +#define _TMFAILURE_RTRY 0x00008000u +#define _TMFAILURE_CNCL 0x00010000u +#define _TMFAILURE_MEM 0x00020000u +#define _TMFAILURE_IMP 0x00040000u +#define _TMFAILURE_ERR 0x00080000u +#define _TMFAILURE_SIZE 0x00100000u +#define _TMFAILURE_NEST 0x00200000u +#define _TMFAILURE_DBG 0x00400000u +#define _TMFAILURE_INT 0x00800000u +#define _TMFAILURE_TRIVIAL 0x01000000u + +__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) +__tstart (void) +{ + return __builtin_aarch64_tstart (); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +__tcommit (void) +{ + __builtin_aarch64_tcommit (); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +__tcancel (const uint64_t __reason) +{ + __builtin_aarch64_tcancel (__reason); +} + +__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) +__ttest (void) +{ + return __builtin_aarch64_ttest (); } -#endif #pragma GCC pop_options +#endif + +#ifdef __cplusplus +} +#endif #endif diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md index f8f8dd09077..03d6b67c30d 100644 --- a/gcc/config/arm/types.md +++ b/gcc/config/arm/types.md @@ -546,6 +546,10 @@ ; The classification below is for coprocessor instructions ; ; coproc +; +; The classification below is for TME instructions +; +; tme (define_attr "type" "adc_imm,\ @@ -1091,7 +1095,8 @@ crypto_sha3,\ crypto_sm3,\ crypto_sm4,\ - coproc" + coproc,\ + tme" (const_string "untyped")) ; Is this an (integer side) multiply with a 32-bit (or smaller) result? diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index c27a40719bc..08e99564a70 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -16095,6 +16095,8 @@ Enable SVE2 aes instructions. This also enables SVE2 instructions. @item sve2-sha3 Enable SVE2 sha3 instructions. This also enables SVE2 instructions. @option{-march=armv8.5-a}. +@item tme +Enable the Transactional Memory Extension. @end table diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3d44853383c..632164ab330 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-07-31 Sudakshina Das + + * gcc.target/aarch64/acle/tme.c: New test. + * gcc.target/aarch64/pragma_cpp_predefs_2.c: New test. + 2019-07-31 Joel Hutton * gcc.target/arm/cmse/cmse-17.c: New test. diff --git a/gcc/testsuite/gcc.target/aarch64/acle/tme.c b/gcc/testsuite/gcc.target/aarch64/acle/tme.c new file mode 100644 index 00000000000..5df93b1dcb1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/tme.c @@ -0,0 +1,34 @@ +/* Test the TME intrinsics. */ + +/* { dg-do compile } */ +/* { dg-options "-save-temps -O2 -march=armv8-a+tme" } */ + +#include "arm_acle.h" + +#define tcancel_reason 0x234 + +unsigned +check_tme (void) +{ + unsigned status = __tstart (); + if (status == 0) + { + if (__ttest () == 2) + { + __tcancel (tcancel_reason & _TMFAILURE_REASON); + return tcancel_reason; + } + + __tcommit (); + return 0; + } + else if (status & _TMFAILURE_NEST) + return _TMFAILURE_NEST; + else if (status & _TMFAILURE_TRIVIAL) + return _TMFAILURE_TRIVIAL; +} + +/* { dg-final { scan-assembler "tstart\tx..?\n" } } */ +/* { dg-final { scan-assembler "tcancel\t#564\n" } } */ +/* { dg-final { scan-assembler "ttest\tx..?\n" } } */ +/* { dg-final { scan-assembler "tcommit\n" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_2.c b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_2.c new file mode 100644 index 00000000000..608b89d19ce --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-a+tme") +#ifndef __ARM_FEATURE_TME +#error "__ARM_FEATURE_TME is not defined but should be!" +#endif + +#pragma GCC pop_options + +#ifdef __ARM_FEATURE_TME +#error "__ARM_FEATURE_TME is defined but should not be!" +#endif + +int +foo (int a) +{ + return a; +}