Files
Xenia-Canary/src/xenia/cpu/ppc/ppc_hir_builder.h
chss95cs@gmail.com 90c771526d "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
2022-11-27 09:39:33 -08:00

117 lines
3.3 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_CPU_PPC_PPC_HIR_BUILDER_H_
#define XENIA_CPU_PPC_PPC_HIR_BUILDER_H_
#include "xenia/base/string_buffer.h"
#include "xenia/cpu/function.h"
#include "xenia/cpu/hir/hir_builder.h"
namespace xe {
namespace cpu {
namespace ppc {
struct PPCBuiltins;
class PPCFrontend;
class PPCHIRBuilder : public hir::HIRBuilder {
using Instr = xe::cpu::hir::Instr;
using Label = xe::cpu::hir::Label;
using Value = xe::cpu::hir::Value;
public:
explicit PPCHIRBuilder(PPCFrontend* frontend);
~PPCHIRBuilder() override;
PPCBuiltins* builtins() const;
void Reset() override;
enum EmitFlags {
// Emit comment nodes.
EMIT_DEBUG_COMMENTS = 1 << 0,
};
bool Emit(GuestFunction* function, uint32_t flags);
GuestFunction* function() const { return function_; }
Function* LookupFunction(uint32_t address);
Label* LookupLabel(uint32_t address);
Value* LoadLR();
void StoreLR(Value* value);
Value* LoadCTR();
void StoreCTR(Value* value);
Value* LoadCR();
Value* LoadCR(uint32_t n);
Value* LoadCRField(uint32_t n, uint32_t bit);
void StoreCR(Value* value);
void StoreCR(uint32_t n, Value* value);
void StoreCRField(uint32_t n, uint32_t bit, Value* value);
void UpdateCR(uint32_t n, Value* lhs, bool is_signed = true);
void UpdateCR(uint32_t n, Value* lhs, Value* rhs, bool is_signed = true);
void UpdateCR6(Value* src_value);
Value* LoadFPSCR();
void StoreFPSCR(Value* value);
void UpdateFPSCR(Value* result, bool update_cr1);
void CopyFPSCRToCR1();
Value* LoadXER();
void StoreXER(Value* value);
// void UpdateXERWithOverflow();
// void UpdateXERWithOverflowAndCarry();
// void StoreOV(Value* value);
Value* LoadCA();
void StoreCA(Value* value);
Value* LoadSAT();
void StoreSAT(Value* value);
Value* LoadGPR(uint32_t reg);
void StoreGPR(uint32_t reg, Value* value);
Value* LoadFPR(uint32_t reg);
void StoreFPR(uint32_t reg, Value* value);
Value* LoadVR(uint32_t reg);
void StoreVR(uint32_t reg, Value* value);
void StoreReserved(Value* val);
Value* LoadReserved();
//calls original impl in hirbuilder, but also records the is_return_site bit into flags in the guestmodule
void SetReturnAddress(Value* value);
private:
void MaybeBreakOnInstruction(uint32_t address);
void AnnotateLabel(uint32_t address, Label* label);
PPCFrontend* frontend_;
// Reset whenever needed:
StringBuffer comment_buffer_;
// Reset each Emit:
bool with_debug_info_;
GuestFunction* function_;
uint64_t start_address_;
uint64_t instr_count_;
Instr** instr_offset_list_;
Label** label_list_;
// Reset each instruction.
struct {
uint32_t dest_count;
struct {
uint8_t reg;
Value* value;
} dests[4];
} trace_info_;
};
} // namespace ppc
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_PPC_PPC_HIR_BUILDER_H_