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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits