]> granicus.if.org Git - clang/commitdiff
[AArch64] Add support for Transactional Memory Extension (TME)
authorMomchil Velikov <momchil.velikov@arm.com>
Wed, 31 Jul 2019 12:52:17 +0000 (12:52 +0000)
committerMomchil Velikov <momchil.velikov@arm.com>
Wed, 31 Jul 2019 12:52:17 +0000 (12:52 +0000)
Re-commit r366322 after some fixes

TME is a future architecture technology, documented in

  https://developer.arm.com/architectures/cpu-architecture/a-profile/exploration-tools
  https://developer.arm.com/docs/ddi0601/a

More about the future architectures:

  https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/new-technologies-for-the-arm-a-profile-architecture

This patch adds support for the TME instructions TSTART, TTEST, TCOMMIT, and
TCANCEL and the target feature/arch extension "tme".

It also implements TME builtin functions, defined in ACLE Q2 2019
(https://developer.arm.com/docs/101028/latest)

Differential Revision: https://reviews.llvm.org/D64416

Patch by Javed Absar and Momchil Velikov

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@367428 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/BuiltinsAArch64.def
lib/Basic/Targets/AArch64.cpp
lib/Basic/Targets/AArch64.h
lib/Headers/arm_acle.h
lib/Sema/SemaChecking.cpp
test/CodeGen/aarch64-tme.cpp [new file with mode: 0644]
test/Sema/aarch64-tme-errors.c [new file with mode: 0644]
test/Sema/aarch64-tme-tcancel-errors.c [new file with mode: 0644]

index 7701ad98f4832cd3edc3c265a96a01403a62e284..fc9a1457bc43afadbdb4795755d2760f7c78efb2 100644 (file)
@@ -91,6 +91,12 @@ LANGBUILTIN(__sevl,  "v", "",   ALL_MS_LANGUAGES)
 // Misc
 BUILTIN(__builtin_sponentry, "v*", "c")
 
+// Transactional Memory Extension
+BUILTIN(__builtin_arm_tstart, "WUi", "nj")
+BUILTIN(__builtin_arm_tcommit, "v", "n")
+BUILTIN(__builtin_arm_tcancel, "vWUIi", "n")
+BUILTIN(__builtin_arm_ttest, "WUi", "nc")
+
 TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
index 25f2b7b35f41fe3f2da1c931a017dabf034badec..93a525b09d8d44e3fd89211d66ef5800045c7145 100644 (file)
@@ -216,6 +216,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
   if (HasMTE)
     Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
 
+  if (HasTME)
+    Builder.defineMacro("__ARM_FEATURE_TME", "1");
+
   if ((FPU & NeonMode) && HasFP16FML)
     Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
 
@@ -267,6 +270,7 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
   HasDotProd = false;
   HasFP16FML = false;
   HasMTE = false;
+  HasTME = false;
   ArchKind = llvm::AArch64::ArchKind::ARMV8A;
 
   for (const auto &Feature : Features) {
@@ -298,6 +302,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       HasFP16FML = true;
     if (Feature == "+mte")
       HasMTE = true;
+    if (Feature == "+tme")
+      HasTME = true;
   }
 
   setDataLayout();
index 5833c146003b0b2ea352b0a58bd4bd4e0be2381d..b6aa07780edda018c927873c7bfcd66c6a6af359 100644 (file)
@@ -35,6 +35,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
   bool HasDotProd;
   bool HasFP16FML;
   bool HasMTE;
+  bool HasTME;
 
   llvm::AArch64::ArchKind ArchKind;
 
index 096cc261af2c62a51f92d820c040363830f63c3d..0510e6fd809f2fe054e601a2674ac0779c7b8730 100644 (file)
@@ -613,7 +613,7 @@ __jcvt(double __a) {
 #define __arm_wsr64(sysreg, v) __builtin_arm_wsr64(sysreg, v)
 #define __arm_wsrp(sysreg, v) __builtin_arm_wsrp(sysreg, v)
 
-// Memory Tagging Extensions (MTE) Intrinsics
+/* Memory Tagging Extensions (MTE) Intrinsics */
 #if __ARM_FEATURE_MEMORY_TAGGING
 #define __arm_mte_create_random_tag(__ptr, __mask)  __builtin_arm_irg(__ptr, __mask)
 #define __arm_mte_increment_tag(__ptr, __tag_offset)  __builtin_arm_addg(__ptr, __tag_offset)
@@ -623,6 +623,28 @@ __jcvt(double __a) {
 #define __arm_mte_ptrdiff(__ptra, __ptrb) __builtin_arm_subp(__ptra, __ptrb)
 #endif
 
+/* Transactional Memory Extension (TME) Intrinsics */
+#if __ARM_FEATURE_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
+
+#define __tstart()        __builtin_arm_tstart()
+#define __tcommit()       __builtin_arm_tcommit()
+#define __tcancel(__arg)  __builtin_arm_tcancel(__arg)
+#define __ttest()         __builtin_arm_ttest()
+
+#endif /* __ARM_FEATURE_TME */
+
 #if defined(__cplusplus)
 }
 #endif
index 436e17a0e3942b42cf08af097dde668aa999ffa3..1fd22d35609c763465843d2538d7ae4dc9214dcd 100644 (file)
@@ -1932,6 +1932,7 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,
   case AArch64::BI__builtin_arm_dmb:
   case AArch64::BI__builtin_arm_dsb:
   case AArch64::BI__builtin_arm_isb: l = 0; u = 15; break;
+  case AArch64::BI__builtin_arm_tcancel: l = 0; u = 65535; break;
   }
 
   return SemaBuiltinConstantArgRange(TheCall, i, l, u + l);
diff --git a/test/CodeGen/aarch64-tme.cpp b/test/CodeGen/aarch64-tme.cpp
new file mode 100644 (file)
index 0000000..0462631
--- /dev/null
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1             -triple aarch64-eabi -target-feature +tme -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -DUSE_ACLE  -triple aarch64-eabi -target-feature +tme -S -emit-llvm %s -o - | FileCheck %s
+
+#define A -1
+constexpr int f() { return 65536; }
+
+#ifdef USE_ACLE
+#include "arm_acle.h"
+void test_tme_funcs() {
+  __tstart();
+  (void)__ttest();
+  __tcommit();
+  __tcancel(0x789a);
+       __tcancel(f() + A);
+}
+#else
+void test_tme_funcs() {
+  __builtin_arm_tstart();
+  (void)__builtin_arm_ttest();
+  __builtin_arm_tcommit();
+  __builtin_arm_tcancel(0x789a);
+       __builtin_arm_tcancel(f() + A);
+}
+#endif
+// CHECK: call i64 @llvm.aarch64.tstart()
+// CHECK: call i64 @llvm.aarch64.ttest()
+// CHECK: call void @llvm.aarch64.tcommit()
+// CHECK: call void @llvm.aarch64.tcancel(i64 30874)
+// CHECK: call void @llvm.aarch64.tcancel(i64 65535)
+
+// CHECK: declare i64 @llvm.aarch64.tstart() #1
+// CHECK: declare i64 @llvm.aarch64.ttest() #1
+// CHECK: declare void @llvm.aarch64.tcommit() #1
+// CHECK: declare void @llvm.aarch64.tcancel(i64 immarg) #1
+
+#ifdef __ARM_FEATURE_TME
+extern "C" void arm_feature_tme_defined() {}
+#endif
+// CHECK: define void @arm_feature_tme_defined()
+
+// CHECK: attributes #1 = { nounwind }
+
diff --git a/test/Sema/aarch64-tme-errors.c b/test/Sema/aarch64-tme-errors.c
new file mode 100644 (file)
index 0000000..0e9c2a6
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple aarch64-eabi -verify %s
+
+#include "arm_acle.h"
+
+void test_no_tme_funcs() {
+  __tstart();         // expected-warning{{implicit declaration of function '__tstart'}}
+  __builtin_tstart(); // expected-error{{use of unknown builtin '__builtin_tstart'}}
+}
diff --git a/test/Sema/aarch64-tme-tcancel-errors.c b/test/Sema/aarch64-tme-tcancel-errors.c
new file mode 100644 (file)
index 0000000..bd5b717
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple aarch64-eabi -target-feature +tme -verify %s
+void t_cancel_const(unsigned short u) {
+  __builtin_arm_tcancel(u); // expected-error{{argument to '__builtin_arm_tcancel' must be a constant integer}}
+}
+
+// RUN: %clang_cc1 -triple aarch64-eabi -target-feature +tme -verify %s
+void t_cancel_range() {
+  __builtin_arm_tcancel(0x12345u); // expected-error{{argument value 74565 is outside the valid range [0, 65535]}}
+}