[PATCH] CodeGen: implement __emit and __yield intrinsics

Saleem Abdulrasool abdulras at fb.com
Thu Apr 24 11:41:20 PDT 2014


Hi rnk,

This adds the __emit and __yield ARM intrinsics.  This is mostly for MSVC
compatibility, although the ARM toolchain also supports this intrinsics.

The __emit intrinsic provides a mechanism to emit a 32-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.  If emitting code in ARM mode, the instruction is 32-bits wide, and
16-bits wide in thumb mode.

The __yield intrinsic provides a mechanism to hint the processor that the thread
is not performing any useful work.
---
 include/clang/Basic/BuiltinsARM.def   |  3 +++
 lib/CodeGen/CGBuiltin.cpp             | 26 ++++++++++++++++++++++++++
 test/CodeGen/builtins-arm-microsoft.c | 11 +++++++++++
 3 files changed, 40 insertions(+)
 create mode 100644 test/CodeGen/builtins-arm-microsoft.c

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,7 @@
 BUILTIN(__builtin_arm_dmb, "vUi", "nc")
 BUILTIN(__builtin_arm_dsb, "vUi", "nc")
 
+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,30 @@
 
 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();
+
+    llvm::InlineAsm *Emit =
+      llvm::InlineAsm::get(FTy, ".long 0x" + llvm::utohexstr(ZExtValue),
+                           "", /*SideEffects=*/true);
+    return Builder.CreateCall(Emit);
+  }
+
+  if (BuiltinID == ARM::BI__yield) {
+    llvm::FunctionType *FTy =
+      llvm::FunctionType::get(VoidTy, /*Variadic=*/false);
+
+    llvm::InlineAsm *Yield =
+      llvm::InlineAsm::get(FTy, "yield", "", /*SideEffect=*/true);
+    return Builder.CreateCall(Yield);
+  }
+
   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,11 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -emit-llvm -o - %s | FileCheck %s
+// REQUIRES: arm-registered-target
+
+void test_emit_intrinsic() {
+  __emit(0xdefe); // CHECK: call void asm sideeffect ".long 0xDEFE", ""()
+}
+
+void test_yield_intrinsic() {
+  __yield(); // CHECK: call void asm sideeffect "yield", ""()
+}
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3489.8814.patch
Type: text/x-patch
Size: 2479 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140424/8627ccc0/attachment.bin>


More information about the cfe-commits mailing list