[VCRUNTIME] Fix some intrinsics with clang-cl 17

For some unknow reason some intrinsics fail to get inlined. Using extern inline results in a linker error. Change it to static inline, so that there is a static implementation in case it doesn't get inlined
This commit is contained in:
Timo Kreuzer 2024-11-27 16:26:17 +02:00
parent 78417c5532
commit 12139bcde7
2 changed files with 34 additions and 11 deletions

View file

@ -95,14 +95,14 @@ __INTRIN_INLINE void _ReadWriteBarrier(void)
#define _ReadBarrier _ReadWriteBarrier #define _ReadBarrier _ReadWriteBarrier
#define _WriteBarrier _ReadWriteBarrier #define _WriteBarrier _ReadWriteBarrier
#if !HAS_BUILTIN(_mm_mfence) #if !HAS_BUILTIN(_mm_mfence) && !defined(__clang__)
__INTRIN_INLINE void _mm_mfence(void) __INTRIN_INLINE void _mm_mfence(void)
{ {
__asm__ __volatile__("mfence" : : : "memory"); __asm__ __volatile__("mfence" : : : "memory");
} }
#endif #endif
#if !HAS_BUILTIN(_mm_lfence) #if !HAS_BUILTIN(_mm_lfence)&& !defined(__clang__)
__INTRIN_INLINE void _mm_lfence(void) __INTRIN_INLINE void _mm_lfence(void)
{ {
_ReadBarrier(); _ReadBarrier();
@ -1301,8 +1301,13 @@ __INTRIN_INLINE unsigned long __cdecl _lrotr(unsigned long value, int shift)
} }
#endif #endif
#ifdef __x86_64__ #if defined __x86_64__
__INTRIN_INLINE unsigned long long __ll_lshift(unsigned long long Mask, int Bit) #if defined(__clang__) && defined(_MSC_VER) // stupid hack because clang is broken
static inline __attribute__((__always_inline__))
#else
__INTRIN_INLINE
#endif
unsigned long long __ll_lshift(unsigned long long Mask, int Bit)
{ {
unsigned long long retval; unsigned long long retval;
unsigned char shift = Bit & 0x3F; unsigned char shift = Bit & 0x3F;
@ -1348,7 +1353,12 @@ __INTRIN_INLINE unsigned long long __ull_rshift(unsigned long long Mask, int Bit
just confuses it. Also we declare Bit as an int and then truncate it to just confuses it. Also we declare Bit as an int and then truncate it to
match Visual C++ behavior match Visual C++ behavior
*/ */
__INTRIN_INLINE unsigned long long __ll_lshift(unsigned long long Mask, int Bit) #if defined(__clang__) && defined(_MSC_VER) // stupid hack because clang is broken
static inline __attribute__((__always_inline__))
#else
__INTRIN_INLINE
#endif
unsigned long long __ll_lshift(unsigned long long Mask, int Bit)
{ {
unsigned long long retval = Mask; unsigned long long retval = Mask;
@ -1641,15 +1651,19 @@ __INTRIN_INLINE unsigned long __cdecl _outpd(unsigned short Port, unsigned long
/*** System information ***/ /*** System information ***/
#if !HAS_BUILTIN(__cpuid)
__INTRIN_INLINE void __cpuid(int CPUInfo[4], int InfoType) __INTRIN_INLINE void __cpuid(int CPUInfo[4], int InfoType)
{ {
__asm__ __volatile__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType)); __asm__ __volatile__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType));
} }
#endif
#if !HAS_BUILTIN(__cpuidex)
__INTRIN_INLINE void __cpuidex(int CPUInfo[4], int InfoType, int ECXValue) __INTRIN_INLINE void __cpuidex(int CPUInfo[4], int InfoType, int ECXValue)
{ {
__asm__ __volatile__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType), "c" (ECXValue)); __asm__ __volatile__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType), "c" (ECXValue));
} }
#endif
#if !HAS_BUILTIN(__rdtsc) #if !HAS_BUILTIN(__rdtsc)
__INTRIN_INLINE unsigned long long __rdtsc(void) __INTRIN_INLINE unsigned long long __rdtsc(void)
@ -1972,8 +1986,12 @@ __INTRIN_INLINE void __invlpg(void *Address)
/*** System operations ***/ /*** System operations ***/
#if defined(__clang__) && defined(_MSC_VER) // stupid hack because clang is broken
__INTRIN_INLINE unsigned long long __readmsr(unsigned long reg) static inline __attribute__((__always_inline__))
#else
__INTRIN_INLINE
#endif
unsigned long long __readmsr(unsigned long reg)
{ {
#ifdef __x86_64__ #ifdef __x86_64__
unsigned long low, high; unsigned long low, high;
@ -1986,7 +2004,12 @@ __INTRIN_INLINE unsigned long long __readmsr(unsigned long reg)
#endif #endif
} }
__INTRIN_INLINE void __writemsr(unsigned long Register, unsigned long long Value) #if defined(__clang__) && defined(_MSC_VER) // stupid hack because clang is broken
static inline __attribute__((__always_inline__))
#else
__INTRIN_INLINE
#endif
void __writemsr(unsigned long Register, unsigned long long Value)
{ {
#ifdef __x86_64__ #ifdef __x86_64__
__asm__ __volatile__("wrmsr" : : "a" (Value), "d" (Value >> 32), "c" (Register)); __asm__ __volatile__("wrmsr" : : "a" (Value), "d" (Value >> 32), "c" (Register));

View file

@ -531,14 +531,14 @@ do { \
/* Use inline functions on GCC/Clang */ /* Use inline functions on GCC/Clang */
#if !HAS_BUILTIN(_mm_getcsr) #if !HAS_BUILTIN(_mm_getcsr) && !defined(_MSC_VER)
__INTRIN_INLINE_SSE unsigned int _mm_getcsr(void) __INTRIN_INLINE_SSE unsigned int _mm_getcsr(void)
{ {
return __builtin_ia32_stmxcsr(); return __builtin_ia32_stmxcsr();
} }
#endif #endif
#if !HAS_BUILTIN(_mm_setcsr) #if !HAS_BUILTIN(_mm_setcsr) && !defined(_MSC_VER)
__INTRIN_INLINE_SSE void _mm_setcsr(unsigned int a) __INTRIN_INLINE_SSE void _mm_setcsr(unsigned int a)
{ {
__builtin_ia32_ldmxcsr(a); __builtin_ia32_ldmxcsr(a);
@ -1136,7 +1136,7 @@ __INTRIN_INLINE_SSE void _mm_stream_ps(float *__p, __m128 __a)
#endif #endif
} }
#if !HAS_BUILTIN(_mm_sfence) #if !HAS_BUILTIN(_mm_sfence) && !defined(_MSC_VER)
__INTRIN_INLINE_SSE void _mm_sfence(void) __INTRIN_INLINE_SSE void _mm_sfence(void)
{ {
__builtin_ia32_sfence(); __builtin_ia32_sfence();