Address review comments from majnemer

http://reviews.llvm.org/D3489

Files:
  include/clang/Basic/Builtins.h
  include/clang/Basic/BuiltinsARM.def
  lib/Basic/Builtins.cpp
  lib/CodeGen/CGBuiltin.cpp
  test/CodeGen/builtins-arm-msvc-compat-error.c
  test/CodeGen/builtins-arm-msvc-compat-only.c
Index: include/clang/Basic/Builtins.h
===================================================================
--- include/clang/Basic/Builtins.h
+++ include/clang/Basic/Builtins.h
@@ -29,18 +29,19 @@
   class ASTContext;
   class QualType;
   class LangOptions;
-  
+
   enum LanguageID {
-    GNU_LANG = 0x1,  // builtin requires GNU mode.
-    C_LANG = 0x2,    // builtin for c only.
-    CXX_LANG = 0x4,  // builtin for cplusplus only.
-    OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
-    MS_LANG = 0x10,  // builtin requires MS mode.
+    GNU_LANG = 0x1,   // builtin requires GNU mode.
+    C_LANG = 0x2,     // builtin for c only.
+    CXX_LANG = 0x4,   // builtin for cplusplus only.
+    OBJC_LANG = 0x8,  // builtin for objective-c and objective-c++
+    MS_LANG = 0x10,   // builtin requires MS extensions.
+    MS_COMPAT = 0x20, // builtin requires MS compatibility mode.
     ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
     ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG,  // builtin requires GNU mode.
     ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG     // builtin requires MS mode.
   };
-  
+
 namespace Builtin {
 enum ID {
   NotBuiltin  = 0,      // This is not a builtin function.
Index: include/clang/Basic/BuiltinsARM.def
===================================================================
--- include/clang/Basic/BuiltinsARM.def
+++ include/clang/Basic/BuiltinsARM.def
@@ -85,6 +85,8 @@
 BUILTIN(__builtin_arm_prefetch, "vvC*UiUi", "nc")
 
 // MSVC
+LANGBUILTIN(__emit, "vUiC", "", MS_COMPAT)
+
 LANGBUILTIN(__yield, "v", "", ALL_MS_LANGUAGES)
 LANGBUILTIN(__wfe, "v", "", ALL_MS_LANGUAGES)
 LANGBUILTIN(__wfi, "v", "", ALL_MS_LANGUAGES)
Index: lib/Basic/Builtins.cpp
===================================================================
--- lib/Basic/Builtins.cpp
+++ lib/Basic/Builtins.cpp
@@ -57,10 +57,13 @@
                             (BuiltinInfo.builtin_lang & GNU_LANG);
   bool MSModeUnsupported = !LangOpts.MicrosoftExt &&
                            (BuiltinInfo.builtin_lang & MS_LANG);
+  bool MSCompatUnsupported = !LangOpts.MSVCCompat &&
+                             (BuiltinInfo.builtin_lang & MS_COMPAT);
   bool ObjCUnsupported = !LangOpts.ObjC1 &&
                          BuiltinInfo.builtin_lang == OBJC_LANG;
   return !BuiltinsUnsupported && !MathBuiltinsUnsupported &&
-         !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported;
+         !GnuModeUnsupported && !MSModeUnsupported && !MSCompatUnsupported &&
+         !ObjCUnsupported;
 }
 
 /// InitializeBuiltins - Mark the identifiers for all the builtins with their
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ 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;
@@ -3157,6 +3159,26 @@
   if (auto Hint = GetValueForARMHint(BuiltinID))
     return Hint;
 
+  if (BuiltinID == ARM::BI__emit) {
+    assert(getTarget().getTriple().isOSWindows() &&
+           "__emit is only supported on Windows on ARM");
+    assert(getTarget().getTriple().getArch() == llvm::Triple::thumb &&
+           "Windows on ARM only supports thumb");
+
+    llvm::FunctionType *FTy =
+        llvm::FunctionType::get(VoidTy, /*Variadic=*/false);
+
+    APSInt Value;
+    if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext()))
+      report_fatal_error("constant value required!");
+    uint64_t ZExtValue = Builder.getInt(Value)->getZExtValue();
+
+    llvm::InlineAsm *Emit =
+        InlineAsm::get(FTy, ".inst.n 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);
Index: test/CodeGen/builtins-arm-msvc-compat-error.c
===================================================================
--- /dev/null
+++ test/CodeGen/builtins-arm-msvc-compat-error.c
@@ -0,0 +1,9 @@
+// RUN: not %clang_cc1 -triple thumbv7-windows -fms-compatibility -emit-llvm -o /dev/null %s 2>&1 \
+// RUN:     | FileCheck %s -check-prefix CHECK
+
+void emit_error(unsigned int opcode) {
+  __emit(opcode);
+}
+
+// CHECK: fatal error: error in backend: constant value required!
+
Index: test/CodeGen/builtins-arm-msvc-compat-only.c
===================================================================
--- /dev/null
+++ test/CodeGen/builtins-arm-msvc-compat-only.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -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
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to