diff --git a/single_include/compass.hpp b/single_include/compass.hpp index 7b79dd1..1b91f5f 100644 --- a/single_include/compass.hpp +++ b/single_include/compass.hpp @@ -360,6 +360,74 @@ namespace compass { #endif #ifndef COMPASS_RT_X86_IMPL_H_ #define COMPASS_RT_X86_IMPL_H_ +#ifndef COMPASS_BIT_VIEW_H +#define COMPASS_BIT_VIEW_H + +#include +#include + +namespace compass { + + namespace utility + { + + template + struct bit_view{ + + T& value_; + + static const int width = sizeof(T)*CHAR_BIT; + static_assert(std::is_integral::value, "compass bitview used with non-integral type (not supported)"); + + bit_view(T& _val): + value_(_val){} + + + bool test(int offset) const { + + bool value = false; + if(offset>(width-1)) + return value; + + const int mask = 1 << offset; + value = value_ & mask; + + return value; + } + + void set(int offset) { + + if(offset>(width-1)) + return ; + + const int mask = 1 << offset; + value_ = value_ | mask; + + return; + } + + T range(std::uint32_t _begin, std::uint32_t _end) const { + + T value = 0; + if(_begin >= width || _end <= _begin) + return value; + + const T mask = ~(~0 << (_end - _begin)); + value = (value_ >> _begin) & mask; + return value; + + + } + + + }; + + } + + +} + +#endif #ifndef COMPASS_RT_X86_CPUID_H @@ -622,73 +690,133 @@ namespace compass { #endif #endif -#ifndef COMPASS_BIT_VIEW_H -#define COMPASS_BIT_VIEW_H +#ifndef COMPASS_RT_X86_META_H_ +#define COMPASS_RT_X86_META_H_ -#include -#include + + + + + + +#include +#include +#include +#include namespace compass { - namespace utility - { + namespace runtime { - template - struct bit_view{ + namespace detail { - T& value_; + static std::string vendor(ct::x86_tag) { - static const int width = sizeof(T)*CHAR_BIT; - static_assert(std::is_integral::value, "compass bitview used with non-integral type (not supported)"); - bit_view(T& _val): - value_(_val){} + std::array regs = rt::cpuid(0); + std::string vendor_name = ""; - bool test(int offset) const { + if(!regs.empty()){ + vendor_name.resize(3*4); - bool value = false; - if(offset>(width-1)) - return value; + std::copy(reinterpret_cast(®s[ct::ebx]),reinterpret_cast(®s[ct::ebx])+4, + vendor_name.begin()); + std::copy(reinterpret_cast(®s[ct::edx]),reinterpret_cast(®s[ct::edx])+4, + vendor_name.begin()+4); + std::copy(reinterpret_cast(®s[ct::ecx]),reinterpret_cast(®s[ct::ecx])+4, + vendor_name.begin()+8); + } - const int mask = 1 << offset; - value = value_ & mask; + return vendor_name; - return value; - } - void set(int offset) { + } - if(offset>(width-1)) - return ; - const int mask = 1 << offset; - value_ = value_ | mask; + static std::string brand(ct::x86_tag) { - return; - } + std::string value = ""; + auto regs = rt::cpuid(0x80000000); + if(regs[ct::eax] < 0x80000004) + return value; - T range(std::uint32_t _begin, std::uint32_t _end) const { + value.resize(48); + char* value_begin = &value[0]; + for(std::uint32_t i = 2; i<5;++i){ + auto ret = rt::cpuid(0x80000000 + i); - T value = 0; - if(_begin >= width || _end <= _begin) - return value; + for(std::uint32_t r = 0; r<4;++r){ + std::uint32_t* tgt = reinterpret_cast(value_begin + (i-2)*16u + r*4u); + *tgt = ret[r]; + } - const T mask = ~(~0 << (_end - _begin)); - value = (value_ >> _begin) & mask; - return value; + } + + return value; + + } + static std::string device_name(ct::x86_tag) { + + std::string brand_str = compass::runtime::detail::brand(ct::x86_tag()); + std::string vendor = compass::runtime::detail::vendor(ct::x86_tag()); + std::size_t find_pos = 0; + + bool is_intel = false; + bool is_amd = false; + + + if((find_pos = vendor.find("Genuine"))!=std::string::npos){ + vendor.erase(find_pos,7); + is_intel = true; + } + + + if((find_pos = vendor.find("Authentic"))!=std::string::npos){ + vendor.erase(find_pos,9); + is_amd = true; + } + + std::string value = ""; + + if((find_pos = brand_str.find(vendor)) != std::string::npos){ + + if(is_intel){ + + auto second_bracket_itr = brand_str.rfind(")"); + auto last_at_itr = brand_str.rfind("@"); + value = brand_str.substr(second_bracket_itr+1,last_at_itr-(second_bracket_itr+1)); + + if((find_pos = value.find(" CPU "))!=std::string::npos){ + value.erase(find_pos,5); } - }; + if((find_pos = value.find(" CPU "))!=std::string::npos){ + value.erase(find_pos,5); + } - } + value.erase(std::remove_if(value.begin(), value.end(), isspace), value.end()); + } + if(is_amd){ -} + auto end_itr = brand_str.rfind("Processor"); + value = brand_str.substr(find_pos+4,end_itr-4); + } + } + return value; + + } + + }; + + }; + +}; #endif #ifndef COMPASS_RT_X86_SIZES_H_ #define COMPASS_RT_X86_SIZES_H_ @@ -702,6 +830,7 @@ namespace compass { + #include #include #include @@ -714,6 +843,7 @@ namespace compass { namespace detail { using bitview = compass::utility::bit_view; + using current_arch_t = ct::arch::type; namespace size{ @@ -721,31 +851,77 @@ namespace compass { class cacheline { - std::vector ebx_data_; + std::vector sizes_in_bytes_; - cacheline(): - ebx_data_() + void on_intel(){ + + std::uint32_t maxlevel = 8; + std::uint32_t eax = 0; + sizes_in_bytes_.reserve(maxlevel); + + for(std::uint32_t l = 0;l ebx_data_; - std::vector ecx_data_; + std::vector sizes_in_bytes_; - cache(): - ebx_data_(), - ecx_data_() + + void on_intel() { + + std::uint32_t eax = 0; + std::uint32_t maxlevel = 8; + sizes_in_bytes_.reserve(8); + + for(std::uint32_t l = 0;l regs = rt::cpuid(0); - - std::string vendor_name = ""; - - if(!regs.empty()){ - vendor_name.resize(3*4); - - std::copy(reinterpret_cast(®s[ct::ebx]),reinterpret_cast(®s[ct::ebx])+4, - vendor_name.begin()); - std::copy(reinterpret_cast(®s[ct::edx]),reinterpret_cast(®s[ct::edx])+4, - vendor_name.begin()+4); - std::copy(reinterpret_cast(®s[ct::ecx]),reinterpret_cast(®s[ct::ecx])+4, - vendor_name.begin()+8); - } - - return vendor_name; - - - } - - - static std::string brand(ct::x86_tag) { - - std::string value = ""; - auto regs = rt::cpuid(0x80000000); - if(regs[ct::eax] < 0x80000004) - return value; - - value.resize(48); - char* value_begin = &value[0]; - for(std::uint32_t i = 2; i<5;++i){ - auto ret = rt::cpuid(0x80000000 + i); - - for(std::uint32_t r = 0; r<4;++r){ - std::uint32_t* tgt = reinterpret_cast(value_begin + (i-2)*16u + r*4u); - *tgt = ret[r]; - } - - } - - return value; - - } - - - static std::string device_name(ct::x86_tag) { - - std::string brand_str = compass::runtime::detail::brand(ct::x86_tag()); - std::string vendor = compass::runtime::detail::vendor(ct::x86_tag()); - std::size_t find_pos = 0; - - bool is_intel = false; - bool is_amd = false; - - - if((find_pos = vendor.find("Genuine"))!=std::string::npos){ - vendor.erase(find_pos,7); - is_intel = true; - } - - - if((find_pos = vendor.find("Authentic"))!=std::string::npos){ - vendor.erase(find_pos,9); - is_amd = true; - } - - std::string value = ""; - - if((find_pos = brand_str.find(vendor)) != std::string::npos){ - - if(is_intel){ - - auto second_bracket_itr = brand_str.rfind(")"); - auto last_at_itr = brand_str.rfind("@"); - value = brand_str.substr(second_bracket_itr+1,last_at_itr-(second_bracket_itr+1)); - - if((find_pos = value.find(" CPU "))!=std::string::npos){ - value.erase(find_pos,5); - } - - - if((find_pos = value.find(" CPU "))!=std::string::npos){ - value.erase(find_pos,5); - } - - value.erase(std::remove_if(value.begin(), value.end(), isspace), value.end()); - } - - if(is_amd){ - - auto end_itr = brand_str.rfind("Processor"); - value = brand_str.substr(find_pos+4,end_itr-4); - - } - } - return value; - - } -