mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-12-16 04:36:59 +00:00
Make codebase more CPU-agnostic + MacOS disclaimer (#559)
This commit is contained in:
parent
445b0afa95
commit
2c81d240a5
26 changed files with 416 additions and 272 deletions
|
|
@ -1,5 +1,7 @@
|
|||
add_library(CemuCommon
|
||||
betype.h
|
||||
cpu_features.cpp
|
||||
cpu_features.h
|
||||
enumFlags.h
|
||||
ExceptionHandler/ExceptionHandler.h
|
||||
FileStream.h
|
||||
|
|
|
|||
101
src/Common/cpu_features.cpp
Normal file
101
src/Common/cpu_features.cpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#include "cpu_features.h"
|
||||
|
||||
// wrappers with uniform prototype for implementation-specific x86 CPU id
|
||||
#if defined(ARCH_X86_64)
|
||||
#ifdef __GNUC__
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
inline void cpuid(int cpuInfo[4], int functionId) {
|
||||
#if defined(_MSC_VER)
|
||||
__cpuid(cpuInfo, functionId);
|
||||
#elif defined(__GNUC__)
|
||||
__cpuid(functionId, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]);
|
||||
#else
|
||||
#error No definition for cpuid
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void cpuidex(int cpuInfo[4], int functionId, int subFunctionId) {
|
||||
#if defined(_MSC_VER)
|
||||
__cpuidex(cpuInfo, functionId, subFunctionId);
|
||||
#elif defined(__GNUC__)
|
||||
__cpuid_count(functionId, subFunctionId, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]);
|
||||
#else
|
||||
#error No definition for cpuidex
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
CPUFeaturesImpl::CPUFeaturesImpl()
|
||||
{
|
||||
#if defined(ARCH_X86_64)
|
||||
int cpuInfo[4];
|
||||
cpuid(cpuInfo, 0x80000001);
|
||||
x86.lzcnt = ((cpuInfo[2] >> 5) & 1) != 0;
|
||||
cpuid(cpuInfo, 0x1);
|
||||
x86.movbe = ((cpuInfo[2] >> 22) & 1) != 0;
|
||||
x86.avx = ((cpuInfo[2] >> 28) & 1) != 0;
|
||||
x86.aesni = ((cpuInfo[2] >> 25) & 1) != 0;
|
||||
x86.ssse3 = ((cpuInfo[2] >> 9) & 1) != 0;
|
||||
x86.sse4_1 = ((cpuInfo[2] >> 19) & 1) != 0;
|
||||
cpuidex(cpuInfo, 0x7, 0);
|
||||
x86.avx2 = ((cpuInfo[1] >> 5) & 1) != 0;
|
||||
x86.bmi2 = ((cpuInfo[1] >> 8) & 1) != 0;
|
||||
cpuid(cpuInfo, 0x80000007);
|
||||
x86.invariant_tsc = ((cpuInfo[3] >> 8) & 1);
|
||||
// get CPU brand name
|
||||
uint32_t nExIds, i = 0;
|
||||
memset(m_cpuBrandName, 0, sizeof(m_cpuBrandName));
|
||||
cpuid(cpuInfo, 0x80000000);
|
||||
nExIds = (uint32_t)cpuInfo[0];
|
||||
for (uint32_t i = 0x80000000; i <= nExIds; ++i)
|
||||
{
|
||||
cpuid(cpuInfo, i);
|
||||
if (i == 0x80000002)
|
||||
memcpy(m_cpuBrandName, cpuInfo, sizeof(cpuInfo));
|
||||
else if (i == 0x80000003)
|
||||
memcpy(m_cpuBrandName + 16, cpuInfo, sizeof(cpuInfo));
|
||||
else if (i == 0x80000004)
|
||||
memcpy(m_cpuBrandName + 32, cpuInfo, sizeof(cpuInfo));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string CPUFeaturesImpl::GetCPUName()
|
||||
{
|
||||
return { m_cpuBrandName };
|
||||
}
|
||||
|
||||
std::string CPUFeaturesImpl::GetCommaSeparatedExtensionList()
|
||||
{
|
||||
std::string tmp;
|
||||
auto appendExt = [&tmp](const char* str)
|
||||
{
|
||||
if (!tmp.empty())
|
||||
tmp.append(", ");
|
||||
tmp.append(str);
|
||||
};
|
||||
if (x86.ssse3)
|
||||
appendExt("SSSE3");
|
||||
if (x86.sse4_1)
|
||||
appendExt("SSE4.1");
|
||||
if (x86.avx)
|
||||
appendExt("AVX");
|
||||
if (x86.avx2)
|
||||
appendExt("AVX2");
|
||||
if (x86.lzcnt)
|
||||
appendExt("LZCNT");
|
||||
if (x86.movbe)
|
||||
appendExt("MOVBE");
|
||||
if (x86.bmi2)
|
||||
appendExt("BMI2");
|
||||
if (x86.aesni)
|
||||
appendExt("AES-NI");
|
||||
if(x86.invariant_tsc)
|
||||
appendExt("INVARIANT-TSC");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
CPUFeaturesImpl g_CPUFeatures;
|
||||
26
src/Common/cpu_features.h
Normal file
26
src/Common/cpu_features.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
class CPUFeaturesImpl
|
||||
{
|
||||
public:
|
||||
CPUFeaturesImpl();
|
||||
|
||||
std::string GetCPUName(); // empty if not available
|
||||
std::string GetCommaSeparatedExtensionList();
|
||||
|
||||
struct
|
||||
{
|
||||
bool ssse3{ false };
|
||||
bool sse4_1{ false };
|
||||
bool avx{ false };
|
||||
bool avx2{ false };
|
||||
bool lzcnt{ false };
|
||||
bool movbe{ false };
|
||||
bool bmi2{ false };
|
||||
bool aesni{ false };
|
||||
bool invariant_tsc{ false };
|
||||
}x86;
|
||||
private:
|
||||
char m_cpuBrandName[0x40]{ 0 };
|
||||
};
|
||||
|
||||
extern CPUFeaturesImpl g_CPUFeatures;
|
||||
|
|
@ -24,13 +24,22 @@
|
|||
// }
|
||||
// #endif
|
||||
|
||||
// arch defines
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64)
|
||||
#define ARCH_X86_64
|
||||
#endif
|
||||
|
||||
// c includes
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <cassert>
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
// c++ includes
|
||||
#include <string>
|
||||
|
|
@ -106,11 +115,6 @@ using uint8le = uint8_t;
|
|||
#include "Cemu/Logging/CemuDebugLogging.h"
|
||||
#include "Cemu/Logging/CemuLogging.h"
|
||||
|
||||
// CPU extensions
|
||||
extern bool _cpuExtension_SSSE3;
|
||||
extern bool _cpuExtension_SSE4_1;
|
||||
extern bool _cpuExtension_AVX2;
|
||||
|
||||
// manual endian-swapping
|
||||
|
||||
#if _MSC_VER
|
||||
|
|
@ -251,30 +255,35 @@ inline uint64 _udiv128(uint64 highDividend, uint64 lowDividend, uint64 divisor,
|
|||
#define NOEXPORT __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
// On aarch64 we handle some of the x86 intrinsics by implementing them as wrappers
|
||||
#if defined(__aarch64__)
|
||||
|
||||
inline void cpuid(int cpuInfo[4], int functionId) {
|
||||
#if defined(_MSC_VER)
|
||||
__cpuid(cpuInfo, functionId);
|
||||
#elif defined(__GNUC__)
|
||||
__cpuid(functionId, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]);
|
||||
#else
|
||||
#error No definition for cpuid
|
||||
#endif
|
||||
inline void _mm_pause()
|
||||
{
|
||||
asm volatile("yield");
|
||||
}
|
||||
|
||||
inline void cpuidex(int cpuInfo[4], int functionId, int subFunctionId) {
|
||||
#if defined(_MSC_VER)
|
||||
__cpuidex(cpuInfo, functionId, subFunctionId);
|
||||
#elif defined(__GNUC__)
|
||||
__cpuid_count(functionId, subFunctionId, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]);
|
||||
#else
|
||||
#error No definition for cpuidex
|
||||
#endif
|
||||
inline uint64 __rdtsc()
|
||||
{
|
||||
uint64 t;
|
||||
asm volatile("mrs %0, cntvct_el0" : "=r" (t));
|
||||
return t;
|
||||
}
|
||||
|
||||
inline void _mm_mfence()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline unsigned char _addcarry_u64(unsigned char carry, unsigned long long a, unsigned long long b, unsigned long long *result)
|
||||
{
|
||||
*result = a + b + (unsigned long long)carry;
|
||||
if (*result < a)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// MEMPTR
|
||||
#include "Common/MemPtr.h"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue