From 9e821b96a74cc668d0e0cea2dd86e5f8c1452831 Mon Sep 17 00:00:00 2001 From: "balhau@balhau.net" Date: Sun, 26 Dec 2021 13:55:10 +0000 Subject: [PATCH] Refactor on premake5 more on types * Refactor platform/types.hpp, added some support for x86 32bit types * Refactor platform/platform.hpp, add #ifdef conditionals to detect x86, 32bit and 64bit arch * Implement 32bit and 64bit getTimestamp based in assembly rdtsc. For 32bit a struct composed by two 32bit numbers was devised to represent a ULong data type of 64bits --- app/clock.cpp | 13 ++++++++++++ app/volatile.cpp | 22 -------------------- premake/clock.lua | 22 ++++++++++++++++++++ premake5.lua | 3 ++- src/cpu/x86/clock.cpp | 44 +++++++++++++++++++++++++++++++++++++++ src/cpu/x86/clock.hpp | 9 ++++++-- src/platform/platform.hpp | 16 +++++++++----- src/platform/types.hpp | 29 +++++++++++++++++++++++++- 8 files changed, 127 insertions(+), 31 deletions(-) create mode 100644 app/clock.cpp delete mode 100644 app/volatile.cpp create mode 100644 premake/clock.lua create mode 100644 src/cpu/x86/clock.cpp 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 +