]> granicus.if.org Git - clang/commitdiff
intrin.h: Implement __readmsr, __readcr3, and __writecr3
authorReid Kleckner <reid@kleckner.net>
Tue, 8 Apr 2014 00:28:22 +0000 (00:28 +0000)
committerReid Kleckner <reid@kleckner.net>
Tue, 8 Apr 2014 00:28:22 +0000 (00:28 +0000)
Fixes PR19301.

Based on a patch from Steven Graf!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205751 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Headers/Intrin.h

index e365abe9a72e5b529a4a79ed7021f3f043927c91..e18b1a658816b6f0be6f525940f98ae8532b3261 100644 (file)
@@ -105,6 +105,7 @@ unsigned __int64 __rdtsc(void);
 unsigned __int64 __rdtscp(unsigned int *);
 unsigned long __readcr0(void);
 unsigned long __readcr2(void);
+static __inline__
 unsigned long __readcr3(void);
 unsigned long __readcr4(void);
 unsigned long __readcr8(void);
@@ -119,6 +120,7 @@ unsigned __int64 __readfsqword(unsigned long);
 static __inline__
 unsigned short __readfsword(unsigned long);
 #endif
+static __inline__
 unsigned __int64 __readmsr(unsigned long);
 unsigned __int64 __readpmc(unsigned long);
 unsigned long __segmentlimit(unsigned long);
@@ -143,6 +145,7 @@ void __vmx_off(void);
 void __vmx_vmptrst(unsigned __int64 *);
 void __wbinvd(void);
 void __writecr0(unsigned int);
+static __inline__
 void __writecr3(unsigned int);
 void __writecr4(unsigned int);
 void __writecr8(unsigned int);
@@ -981,6 +984,38 @@ __halt(void) {
   __asm__ volatile ("hlt");
 }
 
+/*----------------------------------------------------------------------------*\
+|* Privileged intrinsics
+\*----------------------------------------------------------------------------*/
+static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+__readmsr(unsigned long __register) {
+  // Loads the contents of a 64-bit model specific register (MSR) specified in
+  // the ECX register into registers EDX:EAX. The EDX register is loaded with
+  // the high-order 32 bits of the MSR and the EAX register is loaded with the
+  // low-order 32 bits. If less than 64 bits are implemented in the MSR being
+  // read, the values returned to EDX:EAX in unimplemented bit locations are
+  // undefined.
+  unsigned long __edx;
+  unsigned long __eax;
+  __asm__ ("rdmsr"
+          : "=d"(__edx), "=a"(__eax)
+          : "c"(__register)
+          : "%ecx", "%edx", "%eax");
+  return (((unsigned __int64)__edx) << 32) | (unsigned __int64)__eax;
+}
+
+static __inline__ unsigned long __attribute__((always_inline, __nodebug__))
+__readcr3(void) {
+  unsigned long value;
+  __asm__ __volatile__("mov %%cr3, %0" : "=q"(value));
+  return value;
+}
+
+static __inline__ void __attribute__((always_inline, __nodebug__))
+__writecr3(unsigned int Data) {
+  __asm__("mov %0, %%cr3" : : "q"(Data) : "memory");
+}
+
 #ifdef __cplusplus
 }
 #endif