From ecc82ef0c22ea69d667cafb52f144ca5b32fad87 Mon Sep 17 00:00:00 2001 From: Mandeep Singh Grang Date: Thu, 4 Oct 2018 22:32:42 +0000 Subject: [PATCH] [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 --- clang/include/clang/Basic/BuiltinsAArch64.def | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 17 +++++++++++++++++ clang/lib/Headers/intrin.h | 7 +++++++ clang/lib/Sema/SemaChecking.cpp | 3 +++ clang/test/CodeGen/arm64-microsoft-intrinsics.c | 12 ++++++++++++ clang/test/Sema/builtins-microsoft-arm64.c | 9 +++++++++ 6 files changed, 49 insertions(+) create mode 100644 clang/test/Sema/builtins-microsoft-arm64.c diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index 4c46f50..2b6fcda 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 49c2b12..b59fa37 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 edb947e..c5b4ff4 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 d6183dd..1136263 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 d29e930..89e6c36 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 0000000..34f9834 --- /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 + +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}} +} -- 2.7.4