JIT optimizations and refactoring (#675)
* CPU/Recompiler: Use rel32 call where possible for no-args * JitCodeBuffer: Support using preallocated buffer * CPU/Recompiler/AArch64: Use bl instead of blr for short branches * CPU/CodeCache: Allocate recompiler buffer in program space This means we don't need 64-bit moves for every call out of the recompiler. * GTE: Don't store as u16 and load as u32 * CPU/Recompiler: Add methods to emit global load/stores * GTE: Convert class to namespace * CPU/Recompiler: Call GTE functions directly * Settings: Turn into a global variable * GPU: Replace local pointers with global * InterruptController: Turn into a global pointer * System: Replace local pointers with global * Timers: Turn into a global instance * DMA: Turn into a global instance * SPU: Turn into a global instance * CDROM: Turn into a global instance * MDEC: Turn into a global instance * Pad: Turn into a global instance * SIO: Turn into a global instance * CDROM: Move audio FIFO to the heap * CPU/Recompiler: Drop ASMFunctions No longer needed since we have code in the same 4GB window. * CPUCodeCache: Turn class into namespace * Bus: Local pointer -> global pointers * CPU: Turn class into namespace * Bus: Turn into namespace * GTE: Store registers in CPU state struct Allows relative addressing on ARM. * CPU/Recompiler: Align code storage to page size * CPU/Recompiler: Fix relative branches on A64 * HostInterface: Local references to global * System: Turn into a namespace, move events out * Add guard pages * Android: Fix build
This commit is contained in:
committed by
GitHub
parent
1f9fc6ab74
commit
b6f871d2b9
@ -1,22 +1,13 @@
|
||||
#pragma once
|
||||
#include "common/bitfield.h"
|
||||
#include "common/jit_code_buffer.h"
|
||||
#include "cpu_types.h"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
class JitCodeBuffer;
|
||||
|
||||
class Bus;
|
||||
class System;
|
||||
|
||||
namespace CPU {
|
||||
class Core;
|
||||
|
||||
namespace Recompiler {
|
||||
class ASMFunctions;
|
||||
}
|
||||
|
||||
union CodeBlockKey
|
||||
{
|
||||
@ -58,7 +49,7 @@ struct CodeBlockInstruction
|
||||
|
||||
struct CodeBlock
|
||||
{
|
||||
using HostCodePointer = void (*)(Core*);
|
||||
using HostCodePointer = void (*)();
|
||||
|
||||
CodeBlock(const CodeBlockKey key_) : key(key_) {}
|
||||
|
||||
@ -86,67 +77,24 @@ struct CodeBlock
|
||||
}
|
||||
};
|
||||
|
||||
class CodeCache
|
||||
{
|
||||
public:
|
||||
CodeCache();
|
||||
~CodeCache();
|
||||
namespace CodeCache {
|
||||
|
||||
void Initialize(System* system, Core* core, Bus* bus, bool use_recompiler);
|
||||
void Execute();
|
||||
void Initialize(bool use_recompiler);
|
||||
void Shutdown();
|
||||
void Execute();
|
||||
|
||||
/// Flushes the code cache, forcing all blocks to be recompiled.
|
||||
void Flush();
|
||||
/// Flushes the code cache, forcing all blocks to be recompiled.
|
||||
void Flush();
|
||||
|
||||
/// Changes whether the recompiler is enabled.
|
||||
void SetUseRecompiler(bool enable);
|
||||
/// Changes whether the recompiler is enabled.
|
||||
void SetUseRecompiler(bool enable);
|
||||
|
||||
/// Invalidates all blocks which are in the range of the specified code page.
|
||||
void InvalidateBlocksWithPageIndex(u32 page_index);
|
||||
/// Invalidates all blocks which are in the range of the specified code page.
|
||||
void InvalidateBlocksWithPageIndex(u32 page_index);
|
||||
|
||||
private:
|
||||
using BlockMap = std::unordered_map<u32, CodeBlock*>;
|
||||
void InterpretCachedBlock(const CodeBlock& block);
|
||||
void InterpretUncachedBlock();
|
||||
|
||||
void LogCurrentState();
|
||||
}; // namespace CodeCache
|
||||
|
||||
/// Returns the block key for the current execution state.
|
||||
CodeBlockKey GetNextBlockKey() const;
|
||||
|
||||
/// Looks up the block in the cache if it's already been compiled.
|
||||
CodeBlock* LookupBlock(CodeBlockKey key);
|
||||
|
||||
/// Can the current block execute? This will re-validate the block if necessary.
|
||||
/// The block can also be flushed if recompilation failed, so ignore the pointer if false is returned.
|
||||
bool RevalidateBlock(CodeBlock* block);
|
||||
|
||||
bool CompileBlock(CodeBlock* block);
|
||||
void FlushBlock(CodeBlock* block);
|
||||
void AddBlockToPageMap(CodeBlock* block);
|
||||
void RemoveBlockFromPageMap(CodeBlock* block);
|
||||
|
||||
/// Link block from to to.
|
||||
void LinkBlock(CodeBlock* from, CodeBlock* to);
|
||||
|
||||
/// Unlink all blocks which point to this block, and any that this block links to.
|
||||
void UnlinkBlock(CodeBlock* block);
|
||||
|
||||
void InterpretCachedBlock(const CodeBlock& block);
|
||||
void InterpretUncachedBlock();
|
||||
|
||||
System* m_system = nullptr;
|
||||
Core* m_core = nullptr;
|
||||
Bus* m_bus = nullptr;
|
||||
|
||||
#ifdef WITH_RECOMPILER
|
||||
std::unique_ptr<JitCodeBuffer> m_code_buffer;
|
||||
std::unique_ptr<Recompiler::ASMFunctions> m_asm_functions;
|
||||
#endif
|
||||
|
||||
BlockMap m_blocks;
|
||||
|
||||
bool m_use_recompiler = false;
|
||||
|
||||
std::array<std::vector<CodeBlock*>, CPU_CODE_CACHE_PAGE_COUNT> m_ram_block_map;
|
||||
};
|
||||
|
||||
} // namespace CPU
|
||||
} // namespace CPU
|
||||
|
||||
Reference in New Issue
Block a user