AArch64: Prefetch intrinsic

llvm-svn: 215569
This commit is contained in:
Yi Kong 2014-08-13 19:18:20 +00:00
parent 26d104a9ec
commit a5548431a5
5 changed files with 54 additions and 0 deletions

View 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

View 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!");

View 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;

View 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)
}

View 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}}
}