forked from OSchip/llvm-project
[COFF, ARM64] Add __getReg intrinsic
Reviewers: rnk, mstorsjo, compnerd, TomTan, haripul, javed.absar, efriedma Reviewed By: efriedma Subscribers: peter.smith, efriedma, kristof.beyls, chrib, cfe-commits Differential Revision: https://reviews.llvm.org/D52838 llvm-svn: 343824
This commit is contained in:
parent
acd3e09231
commit
ecc82ef0c2
|
@ -104,6 +104,7 @@ TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h"
|
||||||
TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||||
|
|
||||||
TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||||
|
TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||||
|
|
||||||
#undef BUILTIN
|
#undef BUILTIN
|
||||||
#undef LANGBUILTIN
|
#undef LANGBUILTIN
|
||||||
|
|
|
@ -6576,6 +6576,23 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||||
return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr");
|
return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BuiltinID == AArch64::BI__getReg) {
|
||||||
|
APSInt Value;
|
||||||
|
if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext()))
|
||||||
|
llvm_unreachable("Sema will ensure that the parameter is constant");
|
||||||
|
|
||||||
|
LLVMContext &Context = CGM.getLLVMContext();
|
||||||
|
std::string Reg = Value == 31 ? "sp" : "x" + Value.toString(10);
|
||||||
|
|
||||||
|
llvm::Metadata *Ops[] = {llvm::MDString::get(Context, Reg)};
|
||||||
|
llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
|
||||||
|
llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
|
||||||
|
|
||||||
|
llvm::Value *F =
|
||||||
|
CGM.getIntrinsic(llvm::Intrinsic::read_register, {Int64Ty});
|
||||||
|
return Builder.CreateCall(F, Metadata);
|
||||||
|
}
|
||||||
|
|
||||||
if (BuiltinID == AArch64::BI__builtin_arm_clrex) {
|
if (BuiltinID == AArch64::BI__builtin_arm_clrex) {
|
||||||
Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex);
|
Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex);
|
||||||
return Builder.CreateCall(F);
|
return Builder.CreateCall(F);
|
||||||
|
|
|
@ -864,6 +864,13 @@ __nop(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*\
|
||||||
|
|* MS AArch64 specific
|
||||||
|
\*----------------------------------------------------------------------------*/
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
unsigned __int64 __getReg(int);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*\
|
/*----------------------------------------------------------------------------*\
|
||||||
|* Privileged intrinsics
|
|* Privileged intrinsics
|
||||||
\*----------------------------------------------------------------------------*/
|
\*----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -1749,6 +1749,9 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,
|
||||||
BuiltinID == AArch64::BI__builtin_arm_wsrp)
|
BuiltinID == AArch64::BI__builtin_arm_wsrp)
|
||||||
return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true);
|
return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true);
|
||||||
|
|
||||||
|
if (BuiltinID == AArch64::BI__getReg)
|
||||||
|
return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31);
|
||||||
|
|
||||||
if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))
|
if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -66,3 +66,15 @@ void check_ReadWriteBarrier() {
|
||||||
|
|
||||||
// CHECK-MSVC: fence syncscope("singlethread")
|
// CHECK-MSVC: fence syncscope("singlethread")
|
||||||
// CHECK-LINUX: error: implicit declaration of function '_ReadWriteBarrier'
|
// CHECK-LINUX: error: implicit declaration of function '_ReadWriteBarrier'
|
||||||
|
|
||||||
|
unsigned __int64 check__getReg() {
|
||||||
|
unsigned volatile __int64 reg;
|
||||||
|
reg = __getReg(18);
|
||||||
|
reg = __getReg(31);
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-MSVC: call i64 @llvm.read_register.i64(metadata !2)
|
||||||
|
// CHECK-MSVC: call i64 @llvm.read_register.i64(metadata !3)
|
||||||
|
// CHECK-MSVC: !2 = !{!"x18"}
|
||||||
|
// CHECK-MSVC: !3 = !{!"sp"}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
// RUN: %clang_cc1 -triple arm64-windows -fsyntax-only -verify \
|
||||||
|
// RUN: -fms-compatibility -ffreestanding -fms-compatibility-version=17.00 %s
|
||||||
|
|
||||||
|
#include <intrin.h>
|
||||||
|
|
||||||
|
void check__getReg() {
|
||||||
|
__getReg(-1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
|
||||||
|
__getReg(32); // expected-error-re {{argument value {{.*}} is outside the valid range}}
|
||||||
|
}
|
Loading…
Reference in New Issue