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

View File

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

View File

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

View File

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