Update to use new @llvm.arm.hint intrinsic as per the suggestion of Tim.

Depends on http://reviews.llvm.org/D3492.

http://reviews.llvm.org/D3489

Files:
  include/clang/Basic/BuiltinsARM.def
  lib/CodeGen/CGBuiltin.cpp
  test/CodeGen/builtins-arm-microsoft.c
Index: include/clang/Basic/BuiltinsARM.def
===================================================================
--- include/clang/Basic/BuiltinsARM.def
+++ include/clang/Basic/BuiltinsARM.def
@@ -65,4 +65,8 @@
 BUILTIN(__builtin_arm_dmb, "vUi", "nc")
 BUILTIN(__builtin_arm_dsb, "vUi", "nc")
 
+// MSVC
+BUILTIN(__emit, "vUiC", "")
+BUILTIN(__yield, "v", "")
+
 #undef BUILTIN
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;
@@ -4326,6 +4328,37 @@
 
 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
                                            const CallExpr *E) {
+  if (BuiltinID == ARM::BI__emit) {
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(VoidTy, /*Variadic=*/false);
+
+    llvm::APSInt Value;
+    if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext()))
+      report_fatal_error("constant value required!");
+    uint64_t ZExtValue = Builder.getInt(Value)->getZExtValue();
+
+    std::string inst;
+    switch (getTarget().getTriple().getArch()) {
+    default: llvm_unreachable("invalid architecture");
+    case llvm::Triple::arm:
+      inst = ".inst";
+      break;
+    case llvm::Triple::thumb:
+      inst = ".inst.n";
+      break;
+    }
+
+    llvm::InlineAsm *Emit =
+      llvm::InlineAsm::get(FTy, inst + " 0x" + llvm::utohexstr(ZExtValue),
+                           "", /*SideEffects=*/true);
+    return Builder.CreateCall(Emit);
+  }
+
+  if (BuiltinID == ARM::BI__yield) {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_hint);
+    return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, 1));
+  }
+
   if (BuiltinID == ARM::BI__clear_cache) {
     assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
     const FunctionDecl *FD = E->getDirectCallee();
Index: test/CodeGen/builtins-arm-microsoft.c
===================================================================
--- /dev/null
+++ test/CodeGen/builtins-arm-microsoft.c
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -emit-llvm -o - %s \
+// RUN:   | FileCheck %s -check-prefix CHECK-THUMB
+
+// RUN: %clang_cc1 -triple armv7-eabi -emit-llvm -o - %s \
+// RUN:   | FileCheck %s -check-prefix CHECK-ARM
+
+// REQUIRES: arm-registered-target
+
+void test_emit_intrinsic() {
+  __emit(0xdefe);
+}
+
+// CHECK-THUMB: define arm_aapcscc void @test_emit_intrinsic() {{.*}} {
+// CHECK-THUMB: entry:
+// CHECK-THUMB:   call void asm sideeffect ".inst.n 0xDEFE", ""()
+// CHECK-THUMB:   ret void
+// CHECK-THUMB: }
+
+void test_yield_intrinsic() {
+  __yield();
+}
+
+// CHECK-ARM: define void @test_yield_intrinsic() {{.*}} {
+// CHECK-ARM: entry:
+// CHECK-ARM:   call void @llvm.arm.hint(i32 1)
+// CHECK-ARM:   ret void
+// CHECK-ARM: }
+
+// CHECK-THUMB: define arm_aapcscc void @test_yield_intrinsic() {{.*}} {
+// CHECK-THUMB: entry:
+// CHECK-THUMB:   call void @llvm.arm.hint(i32 1)
+// CHECK-THUMB:   ret void
+// CHECK-THUMB: }
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to