From: James Greenhalgh <james.greenhalgh@arm.com>
To: Sudakshina Das <Sudi.Das@arm.com>
Cc: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
nd <nd@arm.com>, Richard Earnshaw <Richard.Earnshaw@arm.com>,
Marcus Shawcroft <Marcus.Shawcroft@arm.com>
Subject: Re: [PATCH, GCC, AArch64] Enable Transactional Memory Extension
Date: Mon, 22 Jul 2019 17:22:00 -0000 [thread overview]
Message-ID: <20190722172003.GB11269@arm.com> (raw)
In-Reply-To: <220d05bf-eccc-e12e-91c0-192accd72bf9@arm.com>
On Wed, Jul 10, 2019 at 07:55:42PM +0100, Sudakshina Das wrote:
> Hi
>
> 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 <Xt>
> * ttest <Xt>
> * tcommit
> * tcancel #<imm>
> The documentation for the above can be found here:
> https://developer.arm.com/docs/ddi0602/latest/base-instructions-alphabetic-order
>
> We have also added ACLE intrinsics for the instructions above according to:
> https://developer.arm.com/docs/101028/latest/transactional-memory-extension-tme-intrinsics
>
> Builds and regression tested on aarch64-none-linux-gnu and added new
> tests for the new instructions.
>
> Is this okay for trunk?
This looks good to me.
OK for trunk.
Thanks,
James
>
> Thanks
> Sudi
>
> *** gcc/ChangeLog ***
>
> 2019-xx-xx Sudakshina Das <sudi.das@arm.com>
>
> * 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-xx-xx Sudakshina Das <sudi.das@arm.com>
>
> * gcc.target/aarch64/acle/tme.c: New test.
> * gcc.target/aarch64/pragma_cpp_predefs_2.c: New test.
> diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
> index 549a6c249243372eacb5d29923b5d1abce4ac79a..16c1d42ea2be0f477692be592e30ba8ce27f05a7 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 5af65b1d2f344842564b227a12f24ad04edd7271..e532c6cd142f64f050d7b5da8ab01e1f5ac3b909 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 4b10c62d20401a66374eb68e36531d73df300af1..27ace6abe7b197b9c42b955a0eef439aae145728 100644
> --- a/gcc/config/aarch64/aarch64-option-extensions.def
> +++ b/gcc/config/aarch64/aarch64-option-extensions.def
> @@ -158,4 +158,7 @@ AARCH64_OPT_EXTENSION("sve2-sha3", AARCH64_FL_SVE2_SHA3, AARCH64_FL_SHA3 | AARCH
> Disabling "bitperm" just disables "bitperm". */
> AARCH64_OPT_EXTENSION("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 92e38a87a768fe54d3f02beecb919d97223474d9..34fca9003ccba20f1cb11e35ca2676f81a7251db 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 7026b3a3b92be94cb916dfcc1d45930dff93177b..7baa662c69cc48b4750867799e1249af43790b18 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -235,6 +235,7 @@
> UNSPEC_REV_SUBREG
> UNSPEC_SPECULATION_TRACKER
> UNSPEC_COPYSIGN
> + UNSPEC_TTEST ; Represent transaction test.
> ])
>
> (define_c_enum "unspecv" [
> @@ -250,6 +251,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.
> ]
> )
>
> @@ -7237,6 +7241,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 534a989c39af1db6ada37a703e8b98300941e094..d4de691eec5e45d7aa6b1f904ec0765916015c6f 100644
> --- a/gcc/config/aarch64/arm_acle.h
> +++ b/gcc/config/aarch64/arm_acle.h
> @@ -29,14 +29,14 @@
>
> #include <stdint.h>
>
> -#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 f8f8dd09077a5c9d3691c95c6676ee36114786e4..03d6b67c30d514b0ba09554d52fed24b9bd91e88 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 6382a840281ff3cbc7e45016b2e4f7a38b265068..9458ad10f2e0e73a54c146dc678f3dd84fd96a67 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -16075,6 +16075,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/gcc.target/aarch64/acle/tme.c b/gcc/testsuite/gcc.target/aarch64/acle/tme.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..5df93b1dcb101a01a864b6b81ed9ed7ee297dd69
> --- /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 0000000000000000000000000000000000000000..608b89d19ce54851cb6abad227c32b081ca03dab
> --- /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;
> +}
prev parent reply other threads:[~2019-07-22 17:20 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-10 19:11 Sudakshina Das
2019-07-22 17:22 ` James Greenhalgh [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190722172003.GB11269@arm.com \
--to=james.greenhalgh@arm.com \
--cc=Marcus.Shawcroft@arm.com \
--cc=Richard.Earnshaw@arm.com \
--cc=Sudi.Das@arm.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=nd@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).