[PATCH] Implement MSVC __cpuid intrinsic.

Peter Collingbourne peter at pcc.me.uk
Wed Apr 17 23:40:22 PDT 2013


Hi rnk,

http://llvm-reviews.chandlerc.com/D686

Files:
  include/clang/Basic/Builtins.def
  lib/CodeGen/CGBuiltin.cpp
  test/CodeGen/builtin-ms-cpuid.c

Index: include/clang/Basic/Builtins.def
===================================================================
--- include/clang/Basic/Builtins.def
+++ include/clang/Basic/Builtins.def
@@ -668,6 +668,7 @@
 
 // Microsoft builtins.
 BUILTIN(__assume, "vb", "n")
+BUILTIN(__cpuid, "vi*i", "n")
 BUILTIN(__noop, "v.", "n")
 BUILTIN(__debugbreak, "v", "n")
 
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -20,6 +20,7 @@
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Intrinsics.h"
 
 using namespace clang;
@@ -1412,6 +1413,30 @@
   }
   case Builtin::BI__noop:
     return RValue::get(0);
+
+  case Builtin::BI__cpuid: {
+    llvm::Type *Int32 = Builder.getInt32Ty();
+    llvm::Type *Int32x4Elems[] = { Int32, Int32, Int32, Int32 };
+    llvm::StructType *Int32x4 =
+      llvm::StructType::get(getLLVMContext(),
+                            llvm::ArrayRef<llvm::Type *>(Int32x4Elems));
+    llvm::FunctionType *CPUIDFunctionTy =
+      llvm::FunctionType::get(Int32x4, Int32, false);
+    llvm::InlineAsm *CPUIDAsm =
+      llvm::InlineAsm::get(CPUIDFunctionTy,
+                           "cpuid", "={ax},={bx},={cx},={dx},{ax}",
+                           /*hasSideEffects=*/false);
+
+    llvm::Value *ResultPtr = EmitScalarExpr(E->getArg(0));
+    llvm::Value *Result =
+      Builder.CreateCall(CPUIDAsm, EmitScalarExpr(E->getArg(1)));
+    for (unsigned i = 0; i != 4; ++i) {
+      llvm::Value *ResultElem = Builder.CreateExtractValue(Result, i);
+      llvm::Value *ResultElemPtr = Builder.CreateConstGEP1_32(ResultPtr, i);
+      Builder.CreateStore(ResultElem, ResultElemPtr);
+    }
+    return RValue::get(0);
+  }
   }
 
   // If this is an alias for a lib function (e.g. __builtin_sin), emit
Index: test/CodeGen/builtin-ms-cpuid.c
===================================================================
--- /dev/null
+++ test/CodeGen/builtin-ms-cpuid.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -emit-llvm %s -o - -O | FileCheck %s
+
+int cid0(int eax) {
+  // CHECK: @cid0
+  // CHECK: asm "cpuid"
+  // CHECK-NEXT: extractvalue
+  // CHECK-NEXT: ret
+  int r[4];
+  __cpuid(r, eax);
+  return r[0];
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D686.1.patch
Type: text/x-patch
Size: 2361 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130417/5225f116/attachment.bin>


More information about the cfe-commits mailing list