summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMandeep Singh Grang <mgrang@codeaurora.org>2018-10-04 22:32:42 +0000
committerMandeep Singh Grang <mgrang@codeaurora.org>2018-10-04 22:32:42 +0000
commit38729b562817425c16e4b20db0062d79df020bcc (patch)
tree654ef3270267260cfc08ee9dd1b5735bcd8d73f4
parent9a326caa769b314f17bdc6cd1f24f796868b4b21 (diff)
[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
-rw-r--r--clang/include/clang/Basic/BuiltinsAArch64.def1
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp17
-rw-r--r--clang/lib/Headers/intrin.h7
-rw-r--r--clang/lib/Sema/SemaChecking.cpp3
-rw-r--r--clang/test/CodeGen/arm64-microsoft-intrinsics.c12
-rw-r--r--clang/test/Sema/builtins-microsoft-arm64.c9
6 files changed, 49 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def
index 4c46f50a8dc..2b6fcdabdcc 100644
--- a/clang/include/clang/Basic/BuiltinsAArch64.def
+++ b/clang/include/clang/Basic/BuiltinsAArch64.def
@@ -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(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
#undef BUILTIN
#undef LANGBUILTIN
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 49c2b126dd8..b59fa379d84 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -6576,6 +6576,23 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
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) {
Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex);
return Builder.CreateCall(F);
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index edb947eef65..c5b4ff4d7d8 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -865,6 +865,13 @@ __nop(void) {
#endif
/*----------------------------------------------------------------------------*\
+|* MS AArch64 specific
+\*----------------------------------------------------------------------------*/
+#if defined(__aarch64__)
+unsigned __int64 __getReg(int);
+#endif
+
+/*----------------------------------------------------------------------------*\
|* Privileged intrinsics
\*----------------------------------------------------------------------------*/
#if defined(__i386__) || defined(__x86_64__)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index d6183dde95f..113626374c4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -1749,6 +1749,9 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,
BuiltinID == AArch64::BI__builtin_arm_wsrp)
return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true);
+ if (BuiltinID == AArch64::BI__getReg)
+ return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31);
+
if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))
return true;
diff --git a/clang/test/CodeGen/arm64-microsoft-intrinsics.c b/clang/test/CodeGen/arm64-microsoft-intrinsics.c
index d29e9305ccd..89e6c369f4d 100644
--- a/clang/test/CodeGen/arm64-microsoft-intrinsics.c
+++ b/clang/test/CodeGen/arm64-microsoft-intrinsics.c
@@ -66,3 +66,15 @@ void check_ReadWriteBarrier() {
// CHECK-MSVC: fence syncscope("singlethread")
// 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"}
diff --git a/clang/test/Sema/builtins-microsoft-arm64.c b/clang/test/Sema/builtins-microsoft-arm64.c
new file mode 100644
index 00000000000..34f9834dba1
--- /dev/null
+++ b/clang/test/Sema/builtins-microsoft-arm64.c
@@ -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}}
+}