初始化内容

This commit is contained in:
2026-09-16 14:07:40 +08:00
parent 6934b390bf
commit 4f643c1e7c
18350 changed files with 6088489 additions and 305 deletions
@@ -0,0 +1,136 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#include "infoware/cpu.hpp"
#include "infoware/detail/cpuid.hpp"
#if defined(_WIN32) && defined(_MSC_VER)
#include <intrin.h>
#define INFOWARE_XCR_XFEATURE_ENABLED_MASK _XCR_XFEATURE_ENABLED_MASK
#else
#define INFOWARE_XCR_XFEATURE_ENABLED_MASK 0
#endif // Is MSVC
static bool has_os_avx() {
bool avxsupport = false;
std::int32_t cpuinfo[4];
iware::detail::cpuid(cpuinfo, 1);
bool osusesxsave_restore = (cpuinfo[2] & (1 << 27)) != 0;
bool cpusupportsavx = (cpuinfo[2] & (1 << 28)) != 0;
if(osusesxsave_restore && cpusupportsavx) {
const auto xcrFeatureMask = iware::detail::xgetbv(INFOWARE_XCR_XFEATURE_ENABLED_MASK);
avxsupport = (xcrFeatureMask & 0x06) == 0x06;
}
return avxsupport;
}
static bool has_os_avx_512() {
if(!has_os_avx())
return false;
const auto xcrFeatureMask = iware::detail::xgetbv(INFOWARE_XCR_XFEATURE_ENABLED_MASK);
return (xcrFeatureMask & 0xE6) == 0xE6;
}
std::vector<iware::cpu::instruction_set_t> iware::cpu::supported_instruction_sets() {
std::int32_t info[4];
iware::detail::cpuid(info, 0);
const auto idinfo = info[0];
iware::detail::cpuid(info, 0x80000000);
const std::uint32_t extendedidinfo = info[0];
std::vector<iware::cpu::instruction_set_t> supported;
supported.reserve(64);
#define ADD_SET_IF(infoindex, bitindex, name) \
if((info[(infoindex)] & (1 << (bitindex))) != 0) \
supported.push_back(iware::cpu::instruction_set_t::name);
if(idinfo >= 0x00000001) {
iware::detail::cpuid(info, 0x00000001);
ADD_SET_IF(3, 22, mmx_extended);
ADD_SET_IF(3, 23, mmx);
ADD_SET_IF(3, 25, sse);
ADD_SET_IF(3, 26, sse2);
ADD_SET_IF(2, 0, sse3);
ADD_SET_IF(2, 9, ssse3);
ADD_SET_IF(2, 19, sse41);
ADD_SET_IF(2, 20, sse42);
ADD_SET_IF(2, 25, aes);
ADD_SET_IF(2, 28, fma3);
ADD_SET_IF(2, 12, rd_rand);
}
if(idinfo >= 0x00000007) {
iware::detail::cpuid(info, 0x00000007);
if(has_os_avx()) {
// Both must be present to have AVX
ADD_SET_IF(1, 5, avx2);
}
ADD_SET_IF(1, 4, hle);
ADD_SET_IF(1, 3, bmi1);
ADD_SET_IF(1, 8, bmi2);
ADD_SET_IF(1, 19, adx);
ADD_SET_IF(1, 14, mpx);
ADD_SET_IF(1, 29, sha);
if(has_os_avx_512()) {
supported.push_back(iware::cpu::instruction_set_t::avx_512);
ADD_SET_IF(1, 16, avx_512_f);
ADD_SET_IF(1, 28, avx_512_cd);
ADD_SET_IF(1, 26, avx_512_pf);
ADD_SET_IF(1, 27, avx_512_er);
ADD_SET_IF(1, 31, avx_512_vl);
ADD_SET_IF(1, 30, avx_512_bw);
ADD_SET_IF(1, 17, avx_512_dq);
ADD_SET_IF(1, 21, avx_512_ifma);
ADD_SET_IF(2, 1, avx_512_vbmi);
}
ADD_SET_IF(2, 0, prefetch_wt1);
}
if(extendedidinfo >= 0x80000001) {
iware::detail::cpuid(info, 0x80000001);
ADD_SET_IF(3, 29, x64);
ADD_SET_IF(3, 0, x87_fpu);
ADD_SET_IF(3, 30, s3d_now);
ADD_SET_IF(3, 31, s3d_now_extended);
ADD_SET_IF(3, 29, x64);
ADD_SET_IF(2, 5, bmi1);
ADD_SET_IF(2, 6, bmi2);
ADD_SET_IF(2, 16, adx);
ADD_SET_IF(2, 11, mpx);
}
#undef ADD_SET_IF
return supported;
}
@@ -0,0 +1,73 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef __APPLE__
#include "infoware/cpu.hpp"
#include "infoware/detail/sysctl.hpp"
#include <algorithm>
#include <cstring>
#include <utility>
static std::pair<const char* const*, const char* const*> instruction_set_to_names(iware::cpu::instruction_set_t set) {
static const char* mmx[] = {"MMX"};
static const char* threednow[] = {"3DNOW", "3DNOWEXT"};
static const char* sse[] = {"SSE"};
static const char* sse2[] = {"SSE2"};
static const char* sse3[] = {"SSSE3", "SSE3"};
static const char* avx[] = {"AVX"};
#define HANDLED_CASE(iset, variable) \
case iware::cpu::instruction_set_t::iset: \
return {variable, variable + (sizeof(variable) / sizeof(*variable))};
switch(set) {
HANDLED_CASE(s3d_now, threednow)
HANDLED_CASE(mmx, mmx)
HANDLED_CASE(sse, sse)
HANDLED_CASE(sse2, sse2)
HANDLED_CASE(sse3, sse3)
HANDLED_CASE(avx, avx)
default:
return {nullptr, nullptr};
}
#undef HANDLED_CASE
}
bool iware::cpu::instruction_set_supported(iware::cpu::instruction_set_t set) {
const auto ises = supported_instruction_sets();
if(std::find(ises.begin(), ises.end(), set) != ises.cend())
return true;
const auto set_names = instruction_set_to_names(set);
if(!set_names.first)
return false;
auto ctl_data = iware::detail::sysctl("machdep.cpu.features");
if(ctl_data.empty())
return 0;
for(auto cur_name = std::strtok(ctl_data.data(), " \t\n"); cur_name; cur_name = std::strtok(nullptr, " \t\n"))
if(std::any_of(set_names.first, set_names.second, [&](auto name) { return name == cur_name; }))
return true;
return false;
}
#endif
@@ -0,0 +1,82 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#ifndef __APPLE__
#include "infoware/cpu.hpp"
#include <algorithm>
#include <fstream>
#include <sstream>
#include <string>
#include <utility>
static std::pair<const char* const*, const char* const*> instruction_set_to_names(iware::cpu::instruction_set_t set) {
static const char* mmx[] = {"mmx"};
static const char* threednow[] = {"3dnow", "3dnowext"};
static const char* sse[] = {"sse"};
static const char* sse2[] = {"sse2"};
static const char* sse3[] = {"ssse3", "sse3"};
static const char* avx[] = {"avx"};
#define HANDLED_CASE(iset, variable) \
case iware::cpu::instruction_set_t::iset: \
return {variable, variable + (sizeof(variable) / sizeof(*variable))};
switch(set) {
HANDLED_CASE(s3d_now, threednow)
HANDLED_CASE(mmx, mmx)
HANDLED_CASE(sse, sse)
HANDLED_CASE(sse2, sse2)
HANDLED_CASE(sse3, sse3)
HANDLED_CASE(avx, avx)
default:
return {nullptr, nullptr};
}
#undef HANDLED_CASE
}
bool iware::cpu::instruction_set_supported(iware::cpu::instruction_set_t set) {
const auto ises = supported_instruction_sets();
if(std::find(ises.begin(), ises.end(), set) != ises.cend())
return true;
const auto set_names = instruction_set_to_names(set);
if(!set_names.first)
return false;
std::ifstream cpuinfo("/proc/cpuinfo");
if(!cpuinfo.is_open() || !cpuinfo)
return false;
for(std::string tmp; std::getline(cpuinfo, tmp);)
if(tmp.find("flags") == 0) {
const auto colon_id = tmp.find_first_of(':');
std::istringstream is(tmp.c_str() + colon_id + 1);
while(is >> tmp)
if(std::any_of(set_names.first, set_names.second, [&](auto name) { return tmp == name; }))
return true;
}
return false;
}
#endif
#endif
@@ -0,0 +1,57 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/cpu.hpp"
#include <algorithm>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
bool iware::cpu::instruction_set_supported(iware::cpu::instruction_set_t set) {
std::vector<iware::cpu::instruction_set_t> ises = supported_instruction_sets();
if(std::find(ises.cbegin(), ises.cend(), set) != ises.cend())
return true;
// TODO: is this necessary if we detect things with xgetbv and cpuid?
// That is, AVX usually needs to have both OS support alongside
DWORD feature;
switch(set) {
case iware::cpu::instruction_set_t::s3d_now:
feature = PF_3DNOW_INSTRUCTIONS_AVAILABLE;
break;
case iware::cpu::instruction_set_t::mmx:
feature = PF_MMX_INSTRUCTIONS_AVAILABLE;
break;
case iware::cpu::instruction_set_t::sse:
feature = PF_XMMI_INSTRUCTIONS_AVAILABLE;
break;
case iware::cpu::instruction_set_t::sse2:
feature = PF_XMMI64_INSTRUCTIONS_AVAILABLE;
break;
case iware::cpu::instruction_set_t::sse3:
feature = PF_SSE3_INSTRUCTIONS_AVAILABLE;
break;
case iware::cpu::instruction_set_t::avx:
feature = PF_XMMI64_INSTRUCTIONS_AVAILABLE;
break;
default:
return false;
}
return IsProcessorFeaturePresent(feature) != 0;
}
#endif