[ARM] Implement ISB memory barrier intrinsic
authorYi Kong <Yi.Kong@arm.com>
Thu, 3 Jul 2014 16:01:25 +0000 (16:01 +0000)
committerYi Kong <Yi.Kong@arm.com>
Thu, 3 Jul 2014 16:01:25 +0000 (16:01 +0000)
Adds support for __builtin_arm_isb. Also corrects DSB and ISB instructions
modelling by adding has-side-effects property.

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

include/clang/Basic/BuiltinsARM.def
lib/Sema/SemaChecking.cpp
test/CodeGen/builtins-arm.c
test/Sema/builtins-arm.c

index 7f32e873ed8f97a2247f0b2f7965e98539e9394b..a423b75393ce5d668e89c9336af6ac95ef449331 100644 (file)
@@ -77,6 +77,7 @@ BUILTIN(__builtin_arm_sevl, "v", "")
 // Data barrier
 BUILTIN(__builtin_arm_dmb, "vUi", "nc")
 BUILTIN(__builtin_arm_dsb, "vUi", "nc")
+BUILTIN(__builtin_arm_isb, "vUi", "nc")
 
 // MSVC
 LANGBUILTIN(__yield, "v", "", ALL_MS_LANGUAGES)
index 9fa8fd1e41b7b5acc0c92787e064f96838a6a967..f7d562318850230a8db6214e53c47777eb407882 100644 (file)
@@ -613,8 +613,8 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
   if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))
     return true;
 
-  // For NEON intrinsics which take an immediate value as part of the
-  // instruction, range check them here.
+  // For intrinsics which take an immediate value as part of the instruction,
+  // range check them here.
   unsigned i = 0, l = 0, u = 0;
   switch (BuiltinID) {
   default: return false;
@@ -623,7 +623,8 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
   case ARM::BI__builtin_arm_vcvtr_f:
   case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break;
   case ARM::BI__builtin_arm_dmb:
-  case ARM::BI__builtin_arm_dsb: l = 0; u = 15; break;
+  case ARM::BI__builtin_arm_dsb:
+  case ARM::BI__builtin_arm_isb: l = 0; u = 15; break;
   }
 
   // FIXME: VFP Intrinsics should error if VFP not present.
index 7b7207299e32327fff5f619de4bed8fc9cdbe1ee..e55183c7f6ae7db6957b62ecf67f5f2b156ccc36 100644 (file)
@@ -52,6 +52,7 @@ void sevl() {
 void test_barrier() {
   __builtin_arm_dmb(1); //CHECK: call {{.*}} @llvm.arm.dmb(i32 1)
   __builtin_arm_dsb(2); //CHECK: call {{.*}} @llvm.arm.dsb(i32 2)
+  __builtin_arm_isb(3); //CHECK: call {{.*}} @llvm.arm.isb(i32 3)
 }
 
 // CHECK: call {{.*}} @llvm.arm.rbit(i32 %a)
index 3ac1da0aa93d6c7c4a84e4d0db6e3a526bc63e17..6c367d35a5f55cbdb2aeda032858aeae59354530 100644 (file)
@@ -31,4 +31,10 @@ void test2() {
   *ptr = '0'; // expected-error {{incomplete type 'void' is not assignable}}
 }
 
+void test3() {
+  __builtin_arm_dsb(16); // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_arm_dmb(17); // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_arm_isb(18); // expected-error {{argument should be a value from 0 to 15}}
+}
+
 #endif