mirror of https://github.com/inolen/redream.git
factor out CheckPendingCacheReset
This commit is contained in:
parent
4d811ae557
commit
86f77ba905
|
@ -36,7 +36,6 @@ SH4::SH4(Dreamcast *dc)
|
||||||
MemoryInterface(this),
|
MemoryInterface(this),
|
||||||
dc_(dc),
|
dc_(dc),
|
||||||
code_cache_(nullptr),
|
code_cache_(nullptr),
|
||||||
pending_cache_reset_(false),
|
|
||||||
requested_interrupts_(0),
|
requested_interrupts_(0),
|
||||||
pending_interrupts_(0),
|
pending_interrupts_(0),
|
||||||
tmu_timers_{INVALID_TIMER, INVALID_TIMER, INVALID_TIMER},
|
tmu_timers_{INVALID_TIMER, INVALID_TIMER, INVALID_TIMER},
|
||||||
|
@ -100,7 +99,6 @@ void SH4::Run(const std::chrono::nanoseconds &delta) {
|
||||||
SH4BlockEntry *block = code_cache_->GetBlock(ctx_.pc);
|
SH4BlockEntry *block = code_cache_->GetBlock(ctx_.pc);
|
||||||
ctx_.pc = block->run();
|
ctx_.pc = block->run();
|
||||||
|
|
||||||
CheckPendingCacheReset();
|
|
||||||
CheckPendingInterrupts();
|
CheckPendingInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +145,7 @@ int SH4::NumRegisters() { return 59; }
|
||||||
|
|
||||||
void SH4::Step() {
|
void SH4::Step() {
|
||||||
// invalidate the block for the current pc
|
// invalidate the block for the current pc
|
||||||
code_cache_->InvalidateBlocks(ctx_.pc);
|
code_cache_->RemoveBlocks(ctx_.pc);
|
||||||
|
|
||||||
// recompile it with only one instruction and run it
|
// recompile it with only one instruction and run it
|
||||||
SH4BlockEntry *block = code_cache_->CompileBlock(ctx_.pc, 1);
|
SH4BlockEntry *block = code_cache_->CompileBlock(ctx_.pc, 1);
|
||||||
|
@ -165,7 +163,7 @@ void SH4::AddBreakpoint(int type, uint32_t addr) {
|
||||||
// write out an invalid instruction
|
// write out an invalid instruction
|
||||||
memory_->W16(addr, 0);
|
memory_->W16(addr, 0);
|
||||||
|
|
||||||
code_cache_->InvalidateBlocks(addr);
|
code_cache_->RemoveBlocks(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SH4::RemoveBreakpoint(int type, uint32_t addr) {
|
void SH4::RemoveBreakpoint(int type, uint32_t addr) {
|
||||||
|
@ -178,7 +176,7 @@ void SH4::RemoveBreakpoint(int type, uint32_t addr) {
|
||||||
// overwrite the invalid instruction with the original
|
// overwrite the invalid instruction with the original
|
||||||
memory_->W16(addr, instr);
|
memory_->W16(addr, instr);
|
||||||
|
|
||||||
code_cache_->InvalidateBlocks(addr);
|
code_cache_->RemoveBlocks(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SH4::ReadMemory(uint32_t addr, uint8_t *buffer, int size) {
|
void SH4::ReadMemory(uint32_t addr, uint8_t *buffer, int size) {
|
||||||
|
@ -550,17 +548,9 @@ void SH4::ResetCache() {
|
||||||
// to
|
// to
|
||||||
// the P0, P1, P3, or U0 area should be located at least eight instructions
|
// the P0, P1, P3, or U0 area should be located at least eight instructions
|
||||||
// after the CCR update instruction."
|
// after the CCR update instruction."
|
||||||
pending_cache_reset_ = true;
|
LOG_INFO("Reset instruction cache");
|
||||||
}
|
|
||||||
|
|
||||||
inline void SH4::CheckPendingCacheReset() {
|
code_cache_->UnlinkBlocks();
|
||||||
if (!pending_cache_reset_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
code_cache_->ResetBlocks();
|
|
||||||
|
|
||||||
pending_cache_reset_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -172,7 +172,6 @@ class SH4 : public Device,
|
||||||
|
|
||||||
// CCN
|
// CCN
|
||||||
void ResetCache();
|
void ResetCache();
|
||||||
void CheckPendingCacheReset();
|
|
||||||
|
|
||||||
// INTC
|
// INTC
|
||||||
void ReprioritizeInterrupts();
|
void ReprioritizeInterrupts();
|
||||||
|
@ -200,8 +199,6 @@ class SH4 : public Device,
|
||||||
#include "hw/sh4/sh4_regs.inc"
|
#include "hw/sh4/sh4_regs.inc"
|
||||||
#undef SH4_REG
|
#undef SH4_REG
|
||||||
|
|
||||||
bool pending_cache_reset_;
|
|
||||||
|
|
||||||
Interrupt sorted_interrupts_[NUM_INTERRUPTS];
|
Interrupt sorted_interrupts_[NUM_INTERRUPTS];
|
||||||
uint64_t sort_id_[NUM_INTERRUPTS];
|
uint64_t sort_id_[NUM_INTERRUPTS];
|
||||||
uint64_t priority_mask_[16];
|
uint64_t priority_mask_[16];
|
||||||
|
|
|
@ -98,8 +98,8 @@ SH4BlockEntry *SH4CodeCache::CompileBlock(uint32_t addr, int max_instrs) {
|
||||||
if (!run) {
|
if (!run) {
|
||||||
LOG_INFO("Assembler overflow, resetting block cache");
|
LOG_INFO("Assembler overflow, resetting block cache");
|
||||||
|
|
||||||
// the backend overflowed, reset the block cache
|
// the backend overflowed, completely clear the block cache
|
||||||
ResetBlocks();
|
ClearBlocks();
|
||||||
|
|
||||||
// if the backend fails to assemble on an empty cache, there's nothing to be
|
// if the backend fails to assemble on an empty cache, there's nothing to be
|
||||||
// done
|
// done
|
||||||
|
@ -124,8 +124,7 @@ SH4BlockEntry *SH4CodeCache::CompileBlock(uint32_t addr, int max_instrs) {
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
void SH4CodeCache::RemoveBlocks(uint32_t addr) {
|
||||||
void SH4CodeCache::InvalidateBlocks(uint32_t addr) {
|
|
||||||
// remove any block which overlaps the address
|
// remove any block which overlaps the address
|
||||||
while (true) {
|
while (true) {
|
||||||
SH4BlockEntry *block = LookupBlock(addr);
|
SH4BlockEntry *block = LookupBlock(addr);
|
||||||
|
@ -146,8 +145,19 @@ void SH4CodeCache::InvalidateBlocks(uint32_t addr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SH4CodeCache::ResetBlocks() {
|
void SH4CodeCache::UnlinkBlocks() {
|
||||||
// reset block cache
|
// unlink the block pointers, but don't remove the map entries. this is used
|
||||||
|
// when clearing the cache while a block is currently executing
|
||||||
|
for (int i = 0; i < MAX_BLOCKS; i++) {
|
||||||
|
SH4BlockEntry *block = &blocks_[i];
|
||||||
|
block->run = default_block_;
|
||||||
|
block->flags = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SH4CodeCache::ClearBlocks() {
|
||||||
|
// unlink all block pointers and remove all map entries. this is only safe to
|
||||||
|
// use when no blocks are currently executing
|
||||||
for (int i = 0; i < MAX_BLOCKS; i++) {
|
for (int i = 0; i < MAX_BLOCKS; i++) {
|
||||||
SH4BlockEntry *block = &blocks_[i];
|
SH4BlockEntry *block = &blocks_[i];
|
||||||
block->run = default_block_;
|
block->run = default_block_;
|
||||||
|
@ -158,7 +168,7 @@ void SH4CodeCache::ResetBlocks() {
|
||||||
block_map_.clear();
|
block_map_.clear();
|
||||||
reverse_block_map_.clear();
|
reverse_block_map_.clear();
|
||||||
|
|
||||||
// have the backend reset its codegen buffers
|
// have the backend reset its codegen buffers as well
|
||||||
backend_->Reset();
|
backend_->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,11 +186,10 @@ bool SH4CodeCache::HandleException(void *ctx, Exception &ex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// exception was handled, reset the block pointer back to the default compile
|
// exception was handled, unlink the block pointer and flag the block to be
|
||||||
// handler and flag the block to be recompiled without fastmem optimizations
|
// recompiled without fastmem optimizations on the next access. note, the
|
||||||
// on the next access. note, the block can't be removed from the lookup maps
|
// block can't be removed from the lookup maps at this point because it's
|
||||||
// at this point because blocks may trigger multiple exceptions before being
|
// still executing and may trigger subsequent exceptions
|
||||||
// recompiled
|
|
||||||
block->run = self->default_block_;
|
block->run = self->default_block_;
|
||||||
block->flags |= BF_SLOWMEM;
|
block->flags |= BF_SLOWMEM;
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,9 @@ class SH4CodeCache {
|
||||||
return &blocks_[offset];
|
return &blocks_[offset];
|
||||||
}
|
}
|
||||||
SH4BlockEntry *CompileBlock(uint32_t addr, int max_instrs);
|
SH4BlockEntry *CompileBlock(uint32_t addr, int max_instrs);
|
||||||
void InvalidateBlocks(uint32_t addr);
|
void RemoveBlocks(uint32_t addr);
|
||||||
void ResetBlocks();
|
void UnlinkBlocks();
|
||||||
|
void ClearBlocks();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool HandleException(void *ctx, sys::Exception &ex);
|
static bool HandleException(void *ctx, sys::Exception &ex);
|
||||||
|
|
Loading…
Reference in New Issue