"Fix" debug console, we were checking the cvar before any cvars were loaded, and the condition it checks in AttachConsole is somehow always false

Remove dead #if 0'd code in math.h

On amd64, page_size == 4096 constant, on amd64 w/ win32, allocation_granularity == 65536. These values for x86 windows havent changed over the last 20 years so this is probably safe
and gives a modest code size reduction

Enable XE_USE_KUSER_SHARED. This sources host time from KUSER_SHARED instead of from QueryPerformanceCounter, which is far faster, but only has a granularity of 100 nanoseconds.

In some games seemingly random crashes were happening that were hard to trace because
the faulting thread was actually not the one that was misbehaving, another threads stack was underflowing into the faulting thread.

Added a bunch of code to synchronize the guest stack and host stack so that if a guest longjmps the host's stack will be adjusted.
Changes were also made to allow the guest to call into a piece of an existing x64 function.

This synchronization might have a slight performance impact on lower end cpus, to disable it set enable_host_guest_stack_synchronization to false.
It is possible it may have introduced regressions, but i dont know of any yet

So far, i know the synchronization change fixes the "hub crash" in super sonic and allows the game "london 2012" to go ingame.

Removed emit_useless_fpscr_updates, not emitting these updates breaks the raiden game

MapGuestAddressToMachineCode now returns nullptr if no address was found, instead of the start of the function

add Processor::LookupModule

Add Backend::DeinitializeBackendContext
Use WriteRegisterRangeFromRing_WithKnownBound<0, 0xFFFF> in WriteRegisterRangeFromRing for inlining (previously regressed on performance of ExecutePacketType0)

add notes about flags that trap in XamInputGetCapabilities

0 == 3 in XamInputGetCapabilities

Name arg 2 of XamInputSetState

PrefetchW in critical section kernel funcs if available & doing cmpxchg

Add terminated field to X_KTHREAD, set it on termination

Expanded the logic of NtResumeThread/NtSuspendThread to include checking the type of the handle (in release, LookupObject doesnt seem to do anything with the type)
and returning X_STATUS_OBJECT_TYPE_MISMATCH if invalid. Do termination check in NtSuspendThread.

Add basic host exception messagebox, need to flesh it out more (maybe use the new stack tracking stuff if on guest thrd?)

Add rdrand patching hack, mostly affects users with nvidia cards who have many threads on zen

Use page_size_shift in more places

Once again disable precompilation! Raiden is mostly weird ppc asm which probably breaks the precompilation. The code is still useful for running the compiler over the whole of an xex in debug to test for issues
"Fix" debug console, we were checking the cvar before any cvars were loaded, and the condition it checks in AttachConsole is somehow always false

Remove dead #if 0'd code in math.h

On amd64, page_size == 4096 constant, on amd64 w/ win32, allocation_granularity == 65536. These values for x86 windows havent changed over the last 20 years so this is probably safe
and gives a modest code size reduction

Enable XE_USE_KUSER_SHARED. This sources host time from KUSER_SHARED instead of from QueryPerformanceCounter, which is far faster, but only has a granularity of 100 nanoseconds.

In some games seemingly random crashes were happening that were hard to trace because
the faulting thread was actually not the one that was misbehaving, another threads stack was underflowing into the faulting thread.

Added a bunch of code to synchronize the guest stack and host stack so that if a guest longjmps the host's stack will be adjusted.
Changes were also made to allow the guest to call into a piece of an existing x64 function.

This synchronization might have a slight performance impact on lower end cpus, to disable it set enable_host_guest_stack_synchronization to false.
It is possible it may have introduced regressions, but i dont know of any yet

So far, i know the synchronization change fixes the "hub crash" in super sonic and allows the game "london 2012" to go ingame.

Removed emit_useless_fpscr_updates, not emitting these updates breaks the raiden game

MapGuestAddressToMachineCode now returns nullptr if no address was found, instead of the start of the function

add Processor::LookupModule

Add Backend::DeinitializeBackendContext
Use WriteRegisterRangeFromRing_WithKnownBound<0, 0xFFFF> in WriteRegisterRangeFromRing for inlining (previously regressed on performance of ExecutePacketType0)

add notes about flags that trap in XamInputGetCapabilities

0 == 3 in XamInputGetCapabilities

Name arg 2 of XamInputSetState

PrefetchW in critical section kernel funcs if available & doing cmpxchg

Add terminated field to X_KTHREAD, set it on termination

Expanded the logic of NtResumeThread/NtSuspendThread to include checking the type of the handle (in release, LookupObject doesnt seem to do anything with the type)
and returning X_STATUS_OBJECT_TYPE_MISMATCH if invalid. Do termination check in NtSuspendThread.

Add basic host exception messagebox, need to flesh it out more (maybe use the new stack tracking stuff if on guest thrd?)

Add rdrand patching hack, mostly affects users with nvidia cards who have many threads on zen

Use page_size_shift in more places

Once again disable precompilation! Raiden is mostly weird ppc asm which probably breaks the precompilation. The code is still useful for running the compiler over the whole of an xex in debug to test for issues
This commit is contained in:
chss95cs@gmail.com
2022-11-27 09:37:06 -08:00
parent 7a17fad88a
commit 90c771526d
28 changed files with 950 additions and 244 deletions

View File

@@ -35,13 +35,15 @@ static bool has_shell_environment_variable() {
}
void AttachConsole() {
bool has_console = ::AttachConsole(ATTACH_PARENT_PROCESS) == TRUE;
bool has_console = ::AttachConsole(ATTACH_PARENT_PROCESS) == TRUE;
#if 0
if (!has_console || !has_shell_environment_variable()) {
// We weren't launched from a console, so just return.
has_console_attached_ = false;
return;
}
#endif
AllocConsole();
has_console_attached_ = true;

View File

@@ -410,34 +410,7 @@ static float ArchReciprocal(float den) {
return _mm_cvtss_f32(_mm_rcp_ss(_mm_set_ss(den)));
}
#if 0
using ArchFloatMask = float;
XE_FORCEINLINE
static ArchFloatMask ArchCmpneqFloatMask(float x, float y) {
return _mm_cvtss_f32(_mm_cmpneq_ss(_mm_set_ss(x), _mm_set_ss(y)));
}
XE_FORCEINLINE
static ArchFloatMask ArchORFloatMask(ArchFloatMask x, ArchFloatMask y) {
return _mm_cvtss_f32(_mm_or_ps(_mm_set_ss(x), _mm_set_ss(y)));
}
XE_FORCEINLINE
static ArchFloatMask ArchXORFloatMask(ArchFloatMask x, ArchFloatMask y) {
return _mm_cvtss_f32(_mm_xor_ps(_mm_set_ss(x), _mm_set_ss(y)));
}
XE_FORCEINLINE
static ArchFloatMask ArchANDFloatMask(ArchFloatMask x, ArchFloatMask y) {
return _mm_cvtss_f32(_mm_and_ps(_mm_set_ss(x), _mm_set_ss(y)));
}
XE_FORCEINLINE
static uint32_t ArchFloatMaskSignbit(ArchFloatMask x) {
return static_cast<uint32_t>(_mm_movemask_ps(_mm_set_ss(x)));
}
constexpr ArchFloatMask floatmask_zero = .0f;
#else
using ArchFloatMask = __m128;
XE_FORCEINLINE
@@ -464,7 +437,7 @@ static uint32_t ArchFloatMaskSignbit(ArchFloatMask x) {
}
constexpr ArchFloatMask floatmask_zero{.0f};
#endif
#else
static float ArchMin(float x, float y) { return std::min<float>(x, y); }
static float ArchMax(float x, float y) { return std::max<float>(x, y); }
@@ -610,17 +583,17 @@ union IDivExtraInfo {
} info;
};
// returns magicnum multiplier
static uint32_t PregenerateUint32Div(uint32_t _denom, uint32_t& out_extra) {
IDivExtraInfo extra;
static constexpr uint32_t PregenerateUint32Div(uint32_t _denom, uint32_t& out_extra) {
IDivExtraInfo extra{};
uint32_t d = _denom;
int p;
uint32_t nc, delta, q1, r1, q2, r2;
int p=0;
uint32_t nc=0, delta=0, q1=0, r1=0, q2=0, r2=0;
struct {
unsigned M;
int a;
int s;
} magu;
} magu{};
magu.a = 0;
nc = -1 - ((uint32_t) - (int32_t)d) % d;
p = 31;
@@ -660,13 +633,13 @@ static uint32_t PregenerateUint32Div(uint32_t _denom, uint32_t& out_extra) {
return static_cast<uint64_t>(q2 + 1);
}
static inline uint32_t ApplyUint32Div(uint32_t num, uint32_t mul,
static constexpr uint32_t ApplyUint32Div(uint32_t num, uint32_t mul,
uint32_t extradata) {
IDivExtraInfo extra;
IDivExtraInfo extra{};
extra.value_ = extradata;
uint32_t result = ((uint64_t)(num) * (uint64_t)mul) >> 32;
uint32_t result = static_cast<uint32_t>((static_cast<uint64_t>(num) * static_cast<uint64_t>(mul)) >> 32);
if (extra.info.add_) {
uint32_t addend = result + num;
addend = ((addend < result ? 0x80000000 : 0) | addend);
@@ -675,7 +648,7 @@ static inline uint32_t ApplyUint32Div(uint32_t num, uint32_t mul,
return result >> extra.info.shift_;
}
static inline uint32_t ApplyUint32UMod(uint32_t num, uint32_t mul,
static constexpr uint32_t ApplyUint32UMod(uint32_t num, uint32_t mul,
uint32_t extradata, uint32_t original) {
uint32_t dived = ApplyUint32Div(num, mul, extradata);
unsigned result = num - (dived * original);
@@ -686,12 +659,12 @@ static inline uint32_t ApplyUint32UMod(uint32_t num, uint32_t mul,
struct MagicDiv {
uint32_t multiplier_;
uint32_t extradata_;
MagicDiv() : multiplier_(0), extradata_(0) {}
MagicDiv(uint32_t original) {
constexpr MagicDiv() : multiplier_(0), extradata_(0) {}
constexpr MagicDiv(uint32_t original) : MagicDiv() {
multiplier_ = PregenerateUint32Div(original, extradata_);
}
uint32_t Apply(uint32_t numerator) const {
constexpr uint32_t Apply(uint32_t numerator) const {
return ApplyUint32Div(numerator, multiplier_, extradata_);
}
};

View File

@@ -28,6 +28,9 @@ namespace xe {
namespace memory {
size_t page_size() {
#if XE_ARCH_AMD64 == 1
return 4096;
#else
static size_t value = 0;
if (!value) {
SYSTEM_INFO si;
@@ -35,9 +38,13 @@ size_t page_size() {
value = si.dwPageSize;
}
return value;
#endif
}
size_t allocation_granularity() {
#if XE_ARCH_AMD64 == 1 && XE_PLATFORM_WIN32 == 1
return 65536;
#else
static size_t value = 0;
if (!value) {
SYSTEM_INFO si;
@@ -45,6 +52,7 @@ size_t allocation_granularity() {
value = si.dwAllocationGranularity;
}
return value;
#endif
}
DWORD ToWin32ProtectFlags(PageAccess access) {

View File

@@ -37,7 +37,7 @@
#define XE_USE_NTDLL_FUNCTIONS 1
//chrispy: disabling this for now, more research needs to be done imo, although it does work very well on my machine
//
#define XE_USE_KUSER_SHARED 0
#define XE_USE_KUSER_SHARED 1
#if XE_USE_NTDLL_FUNCTIONS == 1
/*
ntdll versions of functions often skip through a lot of extra garbage in