-rw-r--r-- 1885 libcpucycles-20251226/cpucycles/cpuid_intel.h raw
#ifndef amd64_cpuid_h
#define amd64_cpuid_h
#ifdef __FILC__
#include <cpuid.h>
static void cpuid_0(unsigned int leaf,unsigned int *a,unsigned int *b,unsigned int *c,unsigned int *d)
{
__get_cpuid(leaf,a,b,c,d);
}
#elif defined(_MSC_VER)
static void cpuid_0(unsigned int leaf,unsigned int *a,unsigned int *b,unsigned int *c,unsigned int *d)
{
int abcd[4];
__cpuidex(abcd,leaf,0);
*a = abcd[0];
*b = abcd[1];
*c = abcd[2];
*d = abcd[3];
}
#else
static void cpuid_0(unsigned int op,unsigned int *a,unsigned int *b,unsigned int *c,unsigned int *d)
{
asm volatile("cpuid" : "=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d) : "a"(op) : "memory");
}
#endif
// 0 if not clear that tsc is invariant
static long long cpuid_tsc_invariant_frequency(void)
{
unsigned int a,b,c,d,top,bot;
cpuid_0(0x80000000,&a,&b,&c,&d);
if (a < 0x80000007) return 0;
cpuid_0(0x80000007,&a,&b,&c,&d);
if (!(d & 0x100)) return 0;
cpuid_0(0,&a,&b,&c,&d);
if (a < 0x15) return 0;
cpuid_0(0x15,&bot,&top,&c,&d);
if (!c) {
// see "Nominal Core Crystal Clock Frequency" exception table in intel manual
cpuid_0(0x1,&a,&b,&c,&d);
switch(a & 0x0fff0ff0) {
case 0x000406e0: // skylake
case 0x000506e0: // skylake
case 0x000806e0: // kaby lake (or comet lake)
case 0x000906e0: // kaby lake (or coffee lake)
case 0x000a0650: // comet lake
case 0x000a0660: // comet lake
c = 24000000; break; // "6th and 7th generation Intel Core processors and Intel Xeon W Processor Family"
case 0x00050650: // cascade lake
c = 25000000; break; // "Intel Xeon Scalable Processor Family with CPUID signature 06_55H"
case 0x000506c0: // goldmont
c = 19200000; break; // "Next Generation Intel Atom processors based on Goldmont Microarchitecture with CPUID signature 06_5CH"
}
}
return (top * (long long) c) / bot;
}
#endif