summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-04-08 00:28:22 +0000
committerReid Kleckner <reid@kleckner.net>2014-04-08 00:28:22 +0000
commit592dc61acf552e4069750a1e6dd80f83b15f8664 (patch)
tree8c62680c567ba9b4abe6a936de869ccc14e4aba0 /clang
parent86e70cb3ac53478a8bdf7b7e42d19066fe35be4a (diff)
downloadbcm5719-llvm-592dc61acf552e4069750a1e6dd80f83b15f8664.tar.gz
bcm5719-llvm-592dc61acf552e4069750a1e6dd80f83b15f8664.zip
intrin.h: Implement __readmsr, __readcr3, and __writecr3
Fixes PR19301. Based on a patch from Steven Graf! llvm-svn: 205751
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Headers/Intrin.h35
1 files changed, 35 insertions, 0 deletions
diff --git a/clang/lib/Headers/Intrin.h b/clang/lib/Headers/Intrin.h
index e365abe9a72..e18b1a65881 100644
--- a/clang/lib/Headers/Intrin.h
+++ b/clang/lib/Headers/Intrin.h
@@ -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
OpenPOWER on IntegriCloud