factor out CheckPendingCacheReset

This commit is contained in:
Anthony Pesch 2016-03-03 00:41:42 -08:00
parent 4d811ae557
commit 86f77ba905
4 changed files with 29 additions and 32 deletions

View File

@ -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();
}
//

View File

@ -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];

View File

@ -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;

View File

@ -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);