diff --git a/app/clock.cpp b/app/clock.cpp new file mode 100644 index 0000000..fef4a38 --- /dev/null +++ b/app/clock.cpp @@ -0,0 +1,13 @@ +#include +#include "../src/cpu/x86/clock.hpp" + +int main(void){ + cpu::Clock *clock = new cpu::X86Clock(); + std::cout << "Hello 1 -- " << clock->getTimestamp() <getTimestamp() < - -inline unsigned long getTimestamp(){ - unsigned long hi,lo; - asm ("rdtsc": "=a" (lo), "=d" (hi) ); - return ((unsigned long) lo ) | ((unsigned long) hi << 32); -} - -inline unsigned long getTimestampVolatile(){ - unsigned hi,lo; - asm volatile("rdtsc": "=a" (lo), "=d" (hi) ); - return ((unsigned long) lo )| ((unsigned long) hi << 32); -} - -int main(void){ - unsigned long t1=getTimestamp(); - unsigned long t2=getTimestamp(); - std::cout << "Hello 1 -- " << t1 < will set edx and eax (32bit) registers with high + * and low order of a 64bit number. For 64bit arch the + * high order 32 bits of rax and rdx will be cleared + * this is why we need to recompose the 64bit number from + * the two 32bit numbers + * + * @return ULong + */ + ULong cpu::X86Clock::getTimestamp() + { + UInt hi, lo; + asmv("rdtsc" + : "=a"(lo), "=d"(hi)); + return ((unsigned long)lo) | ((unsigned long)hi << 32); + } + #endif + + #ifdef ARCH_X86_32 + ULong cpu::X86Clock::getTimestamp() + { + UInt hi, lo; + asmv("rdtsc" + : "=a"(lo), "=d"(hi)); + return ULong{ + high : hi, + low : lo + }; + } + #endif + +#endif \ No newline at end of file diff --git a/src/cpu/x86/clock.hpp b/src/cpu/x86/clock.hpp index c2fcec9..096617c 100644 --- a/src/cpu/x86/clock.hpp +++ b/src/cpu/x86/clock.hpp @@ -4,5 +4,10 @@ namespace cpu { - -} \ No newline at end of file + class X86Clock: public Clock{ + public: + X86Clock(); + ~X86Clock(); + ULong getTimestamp(); + }; +}; \ No newline at end of file diff --git a/src/platform/platform.hpp b/src/platform/platform.hpp index c3a7a38..0d0b084 100644 --- a/src/platform/platform.hpp +++ b/src/platform/platform.hpp @@ -9,13 +9,19 @@ #define ARCH_X86 #endif -#ifdef __x64__ -#define ARCH_X86 -#endif - #ifdef __x86_64__ #define ARCH_X86 #endif -//Redefine asm volatile as asmv to make inline assembly less verbose +#if defined(__x86_64__) || defined(__i386) || defined(__x64__) +#define ARCH_X86 +#endif + +#if defined(__x86_64__) || defined(__x64__) +#define ARCH_X86_64 +#elif defined(__i386) || defined(_M_IX86) +#define ARCH_X86_32 +#endif + +// Redefine asm volatile as asmv to make inline assembly less verbose #define asmv asm volatile \ No newline at end of file diff --git a/src/platform/types.hpp b/src/platform/types.hpp index 4d8ca14..5aa6d99 100644 --- a/src/platform/types.hpp +++ b/src/platform/types.hpp @@ -4,7 +4,7 @@ /* * Types for x86 architectures */ -#ifdef ARCH_X86 +#ifdef ARCH_X86_64 // Signed type alias typedef int Int; typedef long Long; @@ -65,3 +65,30 @@ #define SHIFT_8 8 #endif +#ifdef ARCH_X86_32 + typedef int Int; + typedef char Char; + typedef short Short; + + //64bit Long do not exist at cpu level + //emulate this via struct + typedef struct Long + { + Int high; + Int lo; + } Long; + + // Unsigned type alias + typedef unsigned char UChar; + typedef unsigned short UShort; + typedef unsigned int UInt; + + //64bit unsigned long do not exist at cpu level + //emulate this via struct + typedef struct ULong { + UInt high; + UInt low; + } ULong; + +#endif +