I am trying to call cpuid before my rdtsc function to prevent out of order. I initially used this rdtsc function to get 2 timestamps and often I get negative numbers, which is undesirable. This is the rdtsc function, how should I implement cpuid? Or is it called int the main function?
inline uint64_t rdtsc() {
unsigned long a, d;
asm volatile ("rdtsc":"=a" (a), "=d" (d));
return a | ((uint16_t)d << 32);
}
The behavior of
(uint16_t) d << 32is not defined by the C standard.The left operand of
<<is(uint16_t) d. After the cast, the integer promotions are performed, so theuint16_tvalue is converted to anint.1 This is likely 32 bits in your C implementation. The C standard does not define the behavior of<<when the shift amount equals or exceeds with left operand width.To fix this code, use
return a | (uint64_t) d << 32;.Most compilers warn about this. Pay attention to compiler warning messages. Preferably, elevate them to errors. (With GCC or Clang, use
-Werror. With MSVC, use/WX.)Footnote
1 This assumes
intis wider than 16 bits. Ifintis only 16 bits,(uint16_t) d << 32is still undefined because 32 is wider than the left operand type, 16.