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),
|
||||
dc_(dc),
|
||||
code_cache_(nullptr),
|
||||
pending_cache_reset_(false),
|
||||
requested_interrupts_(0),
|
||||
pending_interrupts_(0),
|
||||
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);
|
||||
ctx_.pc = block->run();
|
||||
|
||||
CheckPendingCacheReset();
|
||||
CheckPendingInterrupts();
|
||||
}
|
||||
|
||||
|
@ -147,7 +145,7 @@ int SH4::NumRegisters() { return 59; }
|
|||
|
||||
void SH4::Step() {
|
||||
// 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
|
||||
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
|
||||
memory_->W16(addr, 0);
|
||||
|
||||
code_cache_->InvalidateBlocks(addr);
|
||||
code_cache_->RemoveBlocks(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
|
||||
memory_->W16(addr, instr);
|
||||
|
||||
code_cache_->InvalidateBlocks(addr);
|
||||
code_cache_->RemoveBlocks(addr);
|
||||
}
|
||||
|
||||
void SH4::ReadMemory(uint32_t addr, uint8_t *buffer, int size) {
|
||||
|
@ -550,17 +548,9 @@ void SH4::ResetCache() {
|
|||
// to
|
||||
// the P0, P1, P3, or U0 area should be located at least eight instructions
|
||||
// after the CCR update instruction."
|
||||
pending_cache_reset_ = true;
|
||||
}
|
||||
LOG_INFO("Reset instruction cache");
|
||||
|
||||
inline void SH4::CheckPendingCacheReset() {
|
||||
if (!pending_cache_reset_) {
|
||||
return;
|
||||
}
|
||||
|
||||
code_cache_->ResetBlocks();
|
||||
|
||||
pending_cache_reset_ = false;
|
||||
code_cache_->UnlinkBlocks();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -172,7 +172,6 @@ class SH4 : public Device,
|
|||
|
||||
// CCN
|
||||
void ResetCache();
|
||||
void CheckPendingCacheReset();
|
||||
|
||||
// INTC
|
||||
void ReprioritizeInterrupts();
|
||||
|
@ -200,8 +199,6 @@ class SH4 : public Device,
|
|||
#include "hw/sh4/sh4_regs.inc"
|
||||
#undef SH4_REG
|
||||
|
||||
bool pending_cache_reset_;
|
||||
|
||||
Interrupt sorted_interrupts_[NUM_INTERRUPTS];
|
||||
uint64_t sort_id_[NUM_INTERRUPTS];
|
||||
uint64_t priority_mask_[16];
|
||||
|
|
|
@ -98,8 +98,8 @@ SH4BlockEntry *SH4CodeCache::CompileBlock(uint32_t addr, int max_instrs) {
|
|||
if (!run) {
|
||||
LOG_INFO("Assembler overflow, resetting block cache");
|
||||
|
||||
// the backend overflowed, reset the block cache
|
||||
ResetBlocks();
|
||||
// the backend overflowed, completely clear the block cache
|
||||
ClearBlocks();
|
||||
|
||||
// if the backend fails to assemble on an empty cache, there's nothing to be
|
||||
// done
|
||||
|
@ -124,8 +124,7 @@ SH4BlockEntry *SH4CodeCache::CompileBlock(uint32_t addr, int max_instrs) {
|
|||
|
||||
return block;
|
||||
}
|
||||
|
||||
void SH4CodeCache::InvalidateBlocks(uint32_t addr) {
|
||||
void SH4CodeCache::RemoveBlocks(uint32_t addr) {
|
||||
// remove any block which overlaps the address
|
||||
while (true) {
|
||||
SH4BlockEntry *block = LookupBlock(addr);
|
||||
|
@ -146,8 +145,19 @@ void SH4CodeCache::InvalidateBlocks(uint32_t addr) {
|
|||
}
|
||||
}
|
||||
|
||||
void SH4CodeCache::ResetBlocks() {
|
||||
// reset block cache
|
||||
void SH4CodeCache::UnlinkBlocks() {
|
||||
// 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++) {
|
||||
SH4BlockEntry *block = &blocks_[i];
|
||||
block->run = default_block_;
|
||||
|
@ -158,7 +168,7 @@ void SH4CodeCache::ResetBlocks() {
|
|||
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();
|
||||
}
|
||||
|
||||
|
@ -176,11 +186,10 @@ bool SH4CodeCache::HandleException(void *ctx, Exception &ex) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// exception was handled, reset the block pointer back to the default compile
|
||||
// handler and flag the block to be recompiled without fastmem optimizations
|
||||
// on the next access. note, the block can't be removed from the lookup maps
|
||||
// at this point because blocks may trigger multiple exceptions before being
|
||||
// recompiled
|
||||
// exception was handled, unlink the block pointer and flag the block to be
|
||||
// recompiled without fastmem optimizations on the next access. note, the
|
||||
// block can't be removed from the lookup maps at this point because it's
|
||||
// still executing and may trigger subsequent exceptions
|
||||
block->run = self->default_block_;
|
||||
block->flags |= BF_SLOWMEM;
|
||||
|
||||
|
|
|
@ -58,8 +58,9 @@ class SH4CodeCache {
|
|||
return &blocks_[offset];
|
||||
}
|
||||
SH4BlockEntry *CompileBlock(uint32_t addr, int max_instrs);
|
||||
void InvalidateBlocks(uint32_t addr);
|
||||
void ResetBlocks();
|
||||
void RemoveBlocks(uint32_t addr);
|
||||
void UnlinkBlocks();
|
||||
void ClearBlocks();
|
||||
|
||||
private:
|
||||
static bool HandleException(void *ctx, sys::Exception &ex);
|
||||
|
|
Loading…
Reference in New Issue