+2019-07-31 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".
+
2019-07-31 Joel Hutton <Joel.Hutton@arm.com>
* config/arm/arm_cmse.h (cmse_nonsecure_caller): Add
/* 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
};
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)
{
register them. */
if (!TARGET_ILP32)
aarch64_init_pauth_hint_builtins ();
+
+ if (TARGET_TME)
+ aarch64_init_tme_builtins ();
}
tree
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
|| 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 ();
}
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. */
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
#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)
#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)
/* 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
UNSPEC_REV_SUBREG
UNSPEC_SPECULATION_TRACKER
UNSPEC_COPYSIGN
+ UNSPEC_TTEST ; Represent transaction test.
])
(define_c_enum "unspecv" [
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.
]
)
(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")
#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)
{
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
; The classification below is for coprocessor instructions
;
; coproc
+;
+; The classification below is for TME instructions
+;
+; tme
(define_attr "type"
"adc_imm,\
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?
@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
+2019-07-31 Sudakshina Das <sudi.das@arm.com>
+
+ * gcc.target/aarch64/acle/tme.c: New test.
+ * gcc.target/aarch64/pragma_cpp_predefs_2.c: New test.
+
2019-07-31 Joel Hutton <Joel.Hutton@arm.com>
* gcc.target/arm/cmse/cmse-17.c: New test.
--- /dev/null
+/* 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" } } */
--- /dev/null
+/* { 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;
+}