summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-12-17 17:52:30 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-12-17 17:52:30 +0000
commit86b881c63e489256e779ad7d72aa8aac17fa3d06 (patch)
treee940cba666eeb5c7303f949f30492b9c971bb42a /clang/lib/CodeGen
parent44ee1c0e91baeae6ea240c3224698b59174b3aee (diff)
downloadbcm5719-llvm-86b881c63e489256e779ad7d72aa8aac17fa3d06.tar.gz
bcm5719-llvm-86b881c63e489256e779ad7d72aa8aac17fa3d06.zip
CodeGen: implement __emit intrinsic
For MSVC compatibility, add the `__emit' builtin. This is used in the Windows SDK headers, and must therefore be implemented as a builtin rather than an intrinsic. The `__emit' builtin provides a mechanism to emit a 16-bit opcode instruction into the stream. The value must be a compile time constant expression. No guarantees are made about the CPU and memory states after the execution of the instruction. Due to the unchecked nature of the builtin, only support this on Windows on ARM. llvm-svn: 224438
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 155545d4c94..fca60d50c56 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -20,7 +20,9 @@
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Intrinsics.h"
using namespace clang;
@@ -3165,6 +3167,26 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
if (auto Hint = GetValueForARMHint(BuiltinID))
return Hint;
+ if (BuiltinID == ARM::BI__emit) {
+ bool IsThumb = getTarget().getTriple().getArch() == llvm::Triple::thumb;
+ llvm::FunctionType *FTy =
+ llvm::FunctionType::get(VoidTy, /*Variadic=*/false);
+
+ APSInt Value;
+ if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext()))
+ llvm_unreachable("Sema will ensure that the parameter is constant");
+
+ uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue();
+
+ llvm::InlineAsm *Emit =
+ IsThumb ? InlineAsm::get(FTy, ".inst.n 0x" + utohexstr(ZExtValue), "",
+ /*SideEffects=*/true)
+ : InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "",
+ /*SideEffects=*/true);
+
+ return Builder.CreateCall(Emit);
+ }
+
if (BuiltinID == ARM::BI__builtin_arm_dbg) {
Value *Option = EmitScalarExpr(E->getArg(0));
return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_dbg), Option);
OpenPOWER on IntegriCloud