]> granicus.if.org Git - clang/commitdiff
AArch64: Prefetch intrinsic
authorYi Kong <Yi.Kong@arm.com>
Wed, 13 Aug 2014 19:18:20 +0000 (19:18 +0000)
committerYi Kong <Yi.Kong@arm.com>
Wed, 13 Aug 2014 19:18:20 +0000 (19:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@215569 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/BuiltinsAArch64.def
lib/CodeGen/CGBuiltin.cpp
lib/Sema/SemaChecking.cpp
test/CodeGen/builtins-arm64.c
test/Sema/builtins-arm64.c

index 695ecf9da5f8313e925c3690c92d2382a9455bd7..9d223c3e85163a9cc75c58a727d865166dbd8628 100644 (file)
@@ -50,4 +50,7 @@ BUILTIN(__builtin_arm_dmb, "vUi", "nc")
 BUILTIN(__builtin_arm_dsb, "vUi", "nc")
 BUILTIN(__builtin_arm_isb, "vUi", "nc")
 
+// Prefetch
+BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc")
+
 #undef BUILTIN
index 092c44f5c28e237f11c30035b595004b00193a70..99f4b21ff7e4ad192b98a49823533b596affed89 100644 (file)
@@ -3854,6 +3854,29 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
     return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
   }
 
+  if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
+    Value *Address         = EmitScalarExpr(E->getArg(0));
+    Value *RW              = EmitScalarExpr(E->getArg(1));
+    Value *CacheLevel      = EmitScalarExpr(E->getArg(2));
+    Value *RetentionPolicy = EmitScalarExpr(E->getArg(3));
+    Value *IsData          = EmitScalarExpr(E->getArg(4));
+
+    Value *Locality = nullptr;
+    if (cast<llvm::ConstantInt>(RetentionPolicy)->isZero()) {
+      // Temporal fetch, needs to convert cache level to locality.
+      Locality = llvm::ConstantInt::get(Int32Ty,
+        -cast<llvm::ConstantInt>(CacheLevel)->getValue() + 3);
+    } else {
+      // Streaming fetch.
+      Locality = llvm::ConstantInt::get(Int32Ty, 0);
+    }
+
+    // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify
+    // PLDL3STRM or PLDL2STRM.
+    Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
+    return Builder.CreateCall4(F, Address, RW, Locality, IsData);
+  }
+
   if (BuiltinID == AArch64::BI__builtin_arm_rbit) {
     assert((getContext().getTypeSize(E->getType()) == 32) &&
            "rbit of unusual size!");
index abda2d26649ae4ca7c890c951b280fadec12f204..95411f568818f9dda1d88595880581ddd1484f1b 100644 (file)
@@ -661,6 +661,13 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,
     return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128);
   }
 
+  if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
+    return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) ||
+      SemaBuiltinConstantArgRange(TheCall, 2, 0, 2) ||
+      SemaBuiltinConstantArgRange(TheCall, 3, 0, 1) ||
+      SemaBuiltinConstantArgRange(TheCall, 4, 0, 1);
+  }
+
   if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))
     return true;
 
index cfa11812279325393e68bcebb269bff87c1e3a7b..cc1f54732b30b94a99f09082a589f8984a1ba9d5 100644 (file)
@@ -29,3 +29,17 @@ void barriers() {
   __builtin_arm_dsb(2);  //CHECK: call {{.*}} @llvm.aarch64.dsb(i32 2)
   __builtin_arm_isb(3);  //CHECK: call {{.*}} @llvm.aarch64.isb(i32 3)
 }
+
+void prefetch() {
+  __builtin_arm_prefetch(0, 1, 2, 0, 1); // pstl3keep
+// CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 1, i32 1, i32 1)
+
+  __builtin_arm_prefetch(0, 0, 0, 1, 1); // pldl1keep
+// CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 0, i32 0, i32 1)
+
+  __builtin_arm_prefetch(0, 0, 0, 1, 1); // pldl1strm
+// CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 0, i32 0, i32 1)
+
+  __builtin_arm_prefetch(0, 0, 0, 0, 0); // plil1keep
+// CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 0, i32 3, i32 0)
+}
index 113f4fc302da324e2f702902ba007a72ded25f15..2779984680f4bf7742a7342ec55afb0e9141dff0 100644 (file)
@@ -22,3 +22,10 @@ void test_memory_barriers() {
   __builtin_arm_dsb(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}}
 }
+
+void test_prefetch() {
+  __builtin_arm_prefetch(0, 2, 0, 0, 0); // expected-error {{argument should be a value from 0 to 1}}
+  __builtin_arm_prefetch(0, 0, 3, 0, 0); // expected-error {{argument should be a value from 0 to 2}}
+  __builtin_arm_prefetch(0, 0, 0, 2, 0); // expected-error {{argument should be a value from 0 to 1}}
+  __builtin_arm_prefetch(0, 0, 0, 0, 2); // expected-error {{argument should be a value from 0 to 1}}
+}