[clang] 3cec2a1 - [X86] Fix the implementation of __readcr3/__writecr3 to work in 64-bit mode

Craig Topper via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 14 13:23:35 PST 2019


Author: Craig Topper
Date: 2019-11-14T13:21:36-08:00
New Revision: 3cec2a17de744900401c83aedb442e2acc1f23f8

URL: https://github.com/llvm/llvm-project/commit/3cec2a17de744900401c83aedb442e2acc1f23f8
DIFF: https://github.com/llvm/llvm-project/commit/3cec2a17de744900401c83aedb442e2acc1f23f8.diff

LOG: [X86] Fix the implementation of __readcr3/__writecr3 to work in 64-bit mode

We need to use a 64-bit type in 64-bit mode so a 64-bit register
will get used in the generated assembly. I've also changed the
constraints to just use "r" intead of "q". "q" forces to a only
an a/b/c/d register in 32-bit mode, but I see no reason that
would matter here.

Fixes Nico's note in PR19301 over 4 years ago.

Differential Revision: https://reviews.llvm.org/D70101

Added: 
    

Modified: 
    clang/lib/Headers/intrin.h
    clang/test/Headers/ms-intrin.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index 9786ba147fca..a73a576bc7a3 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -36,6 +36,12 @@
 /* Define the default attributes for the functions in this file. */
 #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
 
+#if __x86_64__
+#define __LPTRINT_TYPE__ __int64
+#else
+#define __LPTRINT_TYPE__ long
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -94,8 +100,7 @@ void __outword(unsigned short, unsigned short);
 void __outwordstring(unsigned short, unsigned short *, unsigned long);
 unsigned long __readcr0(void);
 unsigned long __readcr2(void);
-static __inline__
-unsigned long __readcr3(void);
+unsigned __LPTRINT_TYPE__ __readcr3(void);
 unsigned long __readcr4(void);
 unsigned long __readcr8(void);
 unsigned int __readdr(unsigned int);
@@ -132,7 +137,7 @@ void __vmx_vmptrst(unsigned __int64 *);
 void __wbinvd(void);
 void __writecr0(unsigned int);
 static __inline__
-void __writecr3(unsigned int);
+void __writecr3(unsigned __INTPTR_TYPE__);
 void __writecr4(unsigned int);
 void __writecr8(unsigned int);
 void __writedr(unsigned int, unsigned int);
@@ -565,24 +570,26 @@ __readmsr(unsigned long __register) {
   __asm__ ("rdmsr" : "=d"(__edx), "=a"(__eax) : "c"(__register));
   return (((unsigned __int64)__edx) << 32) | (unsigned __int64)__eax;
 }
+#endif
 
-static __inline__ unsigned long __DEFAULT_FN_ATTRS
+static __inline__ unsigned __LPTRINT_TYPE__ __DEFAULT_FN_ATTRS
 __readcr3(void) {
-  unsigned long __cr3_val;
-  __asm__ __volatile__ ("mov %%cr3, %0" : "=q"(__cr3_val) : : "memory");
+  unsigned __LPTRINT_TYPE__ __cr3_val;
+  __asm__ __volatile__ ("mov %%cr3, %0" : "=r"(__cr3_val) : : "memory");
   return __cr3_val;
 }
 
 static __inline__ void __DEFAULT_FN_ATTRS
-__writecr3(unsigned int __cr3_val) {
-  __asm__ ("mov %0, %%cr3" : : "q"(__cr3_val) : "memory");
+__writecr3(unsigned __INTPTR_TYPE__ __cr3_val) {
+  __asm__ ("mov %0, %%cr3" : : "r"(__cr3_val) : "memory");
 }
-#endif
 
 #ifdef __cplusplus
 }
 #endif
 
+#undef __LPTRINT_TYPE__
+
 #undef __DEFAULT_FN_ATTRS
 
 #endif /* __INTRIN_H */

diff  --git a/clang/test/Headers/ms-intrin.cpp b/clang/test/Headers/ms-intrin.cpp
index 18bb79820378..d3b6a1a278da 100644
--- a/clang/test/Headers/ms-intrin.cpp
+++ b/clang/test/Headers/ms-intrin.cpp
@@ -56,12 +56,8 @@ void f() {
   __nop();
   __readmsr(0);
 
-  // FIXME: Call these in 64-bit too once the intrinsics have been fixed to
-  // work there, PR19301
-#ifndef _M_X64
   __readcr3();
   __writecr3(0);
-#endif
 
 #ifdef _M_ARM
   __dmb(_ARM_BARRIER_ISHST);


        


More information about the cfe-commits mailing list