forked from OSchip/llvm-project
parent
26d104a9ec
commit
a5548431a5
|
@ -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
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue