summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/BuiltinsARM.def2
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp22
-rw-r--r--clang/test/CodeGen/builtins-arm-msvc-compat-error.c6
-rw-r--r--clang/test/CodeGen/builtins-arm-msvc-compat-only.c19
4 files changed, 49 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/BuiltinsARM.def b/clang/include/clang/Basic/BuiltinsARM.def
index 1f2f9a3840c..9091ad4d758 100644
--- a/clang/include/clang/Basic/BuiltinsARM.def
+++ b/clang/include/clang/Basic/BuiltinsARM.def
@@ -85,6 +85,8 @@ BUILTIN(__builtin_arm_isb, "vUi", "nc")
BUILTIN(__builtin_arm_prefetch, "vvC*UiUi", "nc")
// MSVC
+LANGBUILTIN(__emit, "vIUiC", "", ALL_MS_LANGUAGES)
+
LANGBUILTIN(__yield, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__wfe, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__wfi, "v", "", ALL_MS_LANGUAGES)
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);
diff --git a/clang/test/CodeGen/builtins-arm-msvc-compat-error.c b/clang/test/CodeGen/builtins-arm-msvc-compat-error.c
new file mode 100644
index 00000000000..29469deb6a7
--- /dev/null
+++ b/clang/test/CodeGen/builtins-arm-msvc-compat-error.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-extensions -verify %s
+
+void emit_error(unsigned int opcode) {
+ __emit(opcode); // expected-error {{argument to '__emit' must be a constant integer}}
+}
+
diff --git a/clang/test/CodeGen/builtins-arm-msvc-compat-only.c b/clang/test/CodeGen/builtins-arm-msvc-compat-only.c
new file mode 100644
index 00000000000..db82ca40665
--- /dev/null
+++ b/clang/test/CodeGen/builtins-arm-msvc-compat-only.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-extensions -emit-llvm -o - %s \
+// RUN: | FileCheck %s -check-prefix CHECK-MSVC
+// RUN: %clang_cc1 -triple armv7-eabi -emit-llvm %s -o /dev/null 2>&1 \
+// RUN: | FileCheck %s -check-prefix CHECK-EABI
+// REQUIRES: arm-registered-target
+
+void emit() {
+ __emit(0xdefe);
+}
+
+// CHECK-MSVC: call void asm sideeffect ".inst.n 0xDEFE", ""()
+// CHECK-EABI: warning: implicit declaration of function '__emit' is invalid in C99
+
+void emit_truncated() {
+ __emit(0x11110000); // movs r0, r0
+}
+
+// CHECK-MSVC: call void asm sideeffect ".inst.n 0x0", ""()
+
OpenPOWER on IntegriCloud