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
This commit is contained in:
balhau@balhau.net 2021-12-26 13:55:10 +00:00
parent d70ab1deda
commit 9e821b96a7
No known key found for this signature in database
GPG key ID: 1E666F326A121830
8 changed files with 127 additions and 31 deletions

13
app/clock.cpp Normal file
View file

@ -0,0 +1,13 @@
#include <iostream>
#include "../src/cpu/x86/clock.hpp"
int main(void){
cpu::Clock *clock = new cpu::X86Clock();
std::cout << "Hello 1 -- " << clock->getTimestamp() <<std::endl;
std::cout << "Hello 2 -- " << clock->getTimestamp() <<std::endl;
delete clock;
//std::cout << "Hello 3 -- " << getTimestamp() <<std::endl;
//std::cout << "Hello 4 -- " << getTimestamp() <<std::endl;
}

View file

@ -1,22 +0,0 @@
#include <iostream>
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 <<std::endl;
std::cout << "Hello 2 -- " << t2 <<std::endl;
//std::cout << "Hello 3 -- " << getTimestamp() <<std::endl;
//std::cout << "Hello 4 -- " << getTimestamp() <<std::endl;
}

22
premake/clock.lua Normal file
View file

@ -0,0 +1,22 @@
project "clock"
kind "ConsoleApp"
language "c++"
targetdir "../bin/%{cfg.buildcfg}"
objdir "../obj"
--files {"**.hpp","**.cpp"}
files {
"../app/clock.cpp",
"../src/cpu/**.hpp",
"../src/cpu/**.cpp"
}
filter "configurations:Debug"
defines { "DEBUG" }
symbols "On"
filter "configurations:Release"
defines { "NDEBUG" }
optimize "On"
filter { "system:linux" }

View file

@ -4,4 +4,5 @@ workspace "CppLib"
include("premake/sse.lua")
include("premake/libbmath.lua")
include("premake/maths.lua")
include("premake/maths.lua")
include("premake/clock.lua")

44
src/cpu/x86/clock.cpp Normal file
View file

@ -0,0 +1,44 @@
#include "clock.hpp"
#ifdef ARCH_X86 // IF is x86 architecture
cpu::X86Clock::X86Clock(){
}
cpu::X86Clock::~X86Clock(){
}
#ifdef ARCH_X86_64 // If its 64bit
/**
* @brief Uses [RDTSC](https://www.felixcloutier.com/x86/rdtsc) assembly instruction to fetch
* the Time-Stamp Counter
* rdtsc -> 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

View file

@ -4,5 +4,10 @@
namespace cpu
{
}
class X86Clock: public Clock{
public:
X86Clock();
~X86Clock();
ULong getTimestamp();
};
};

View file

@ -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

View file

@ -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