[PATCH 5/6] include: Add __rdtsc and __rdtscp intrinsics.

Rémi Bernon rbernon at codeweavers.com
Wed Mar 10 10:13:01 CST 2021


On 3/10/21 4:40 PM, Rémi Bernon wrote:
> On 3/10/21 4:00 PM, Rémi Bernon wrote:
>> On 3/10/21 3:57 PM, Jacek Caban wrote:
>>> Hi Rémi,
>>>
>>> On 10.03.2021 12:22, Rémi Bernon wrote:
>>>> Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
>>>> ---
>>>>   include/msvcrt/intrin.h | 30 ++++++++++++++++++++++++++++++
>>>>   1 file changed, 30 insertions(+)
>>>>
>>>> diff --git a/include/msvcrt/intrin.h b/include/msvcrt/intrin.h
>>>> index 781c6fac823..061866fe63b 100644
>>>> --- a/include/msvcrt/intrin.h
>>>> +++ b/include/msvcrt/intrin.h
>>>> @@ -20,6 +20,36 @@ static inline void __cpuid(int info[4], int ax)
>>>>   {
>>>>       return __cpuidex(info, ax, 0);
>>>>   }
>>>> +
>>>> +#ifdef __i386
>>>> +static inline unsigned __int64 __rdtsc(void)
>>>> +{
>>>> +    unsigned __int64 a;
>>>> +    __asm__ ("rdtsc" : "=A" (a));
>>>> +    return a;
>>>> +}
>>>> +
>>>> +static inline unsigned __int64 __rdtscp(unsigned int *aux)
>>>> +{
>>>> +    unsigned __int64 a;
>>>> +    __asm__ ("rdtscp" : "=A" (a), "=c" (*aux));
>>>> +    return a;
>>>> +}
>>>> +#elif defined __amd64
>>>> +static inline unsigned __int64 __rdtsc(void)
>>>> +{
>>>> +    unsigned __int64 a, d;
>>>> +    __asm__ ("rdtsc" : "=a" (a), "=d" (d));
>>>> +    return (d << 32) | a;
>>>> +}
>>>> +
>>>> +static inline unsigned __int64 __rdtscp(unsigned int *aux)
>>>> +{
>>>> +    unsigned __int64 a, d;
>>>> +    __asm__ ("rdtscp" : "=a" (a), "=d" (d), "=c" (*aux));
>>>> +    return (d << 32) | a;
>>>> +}
>>>> +#endif
>>>>   #endif
>>>
>>>
>>> I think you meant __i386__ and __x86_64__ for guards. If guards were 
>>> right, you'd get a redefinition because __rdtsc is a compiler 
>>> builtin. It seems to me that all we need for __rdtsc is to provide 
>>> MSVC-style declaration in winnt.h, like it's done in WinSDK.
>>>
>>>
>>> Thanks,
>>>
>>> Jacek
>>>
>>
>> Yeah I'm not sure where I got these guards from, but I think the test 
>> failed to compile, so I assumed MinGW missed these intrinsics? I'll 
>> double check.
> 
> So I can confirm that although the guard aren't the usual ones there's 
> no __rdtsc(p) intrinsics on MinGW and the test fails to compile without 
> these (and I don't get redefinition errors with them).
> 
> Then I agree that these are probably MSVC intrinsics and may need to be 
> guarded for that case, but they are still needed for GCC (and possibly 
> clang?).

Apparently clang >= 4.0.0 has __rdtsc (but not __rdtscp). Can we just 
assume clang >= 4.0.0 is used and something like that would be 
acceptable instead?

     #ifndef _MSC_VER
     # ifndef __clang__ /* clang >= 4.0.0 has __rdtsc intrinsic */
     #  if defined(__i386__)
     static inline unsigned __int64 __rdtsc(void)
     {
         unsigned __int64 a;
         __asm__ ("rdtsc" : "=A" (a));
         return a;
     }
     #  elif defined(__x86_64__)
     static inline unsigned __int64 __rdtsc(void)
     {
         unsigned __int64 a, d;
         __asm__ ("rdtsc" : "=a" (a), "=d" (d));
         return (d << 32) | a;
     }
     #  endif
     # endif /* __clang__ */

     # if defined(__i386__)
     static inline unsigned __int64 __rdtscp(unsigned int *aux)
     {
         unsigned __int64 a;
         __asm__ ("rdtscp" : "=A" (a), "=c" (*aux));
         return a;
     }
     # elif defined(__x86_64__)
     static inline unsigned __int64 __rdtscp(unsigned int *aux)
     {
         unsigned __int64 a, d;
         __asm__ ("rdtscp" : "=a" (a), "=d" (d), "=c" (*aux));
         return (d << 32) | a;
     }
     # endif
     #endif /* _MSC_VER */

Cheers,
-- 
Rémi Bernon <rbernon at codeweavers.com>



More information about the wine-devel mailing list