From 34ccfaec462159524c050a42af14c974008728f0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Thu, 22 Feb 2007 08:45:14 +0000 Subject: [PATCH] Add writemap. Fixes stonekeep in dynamic core. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2818 --- src/cpu/core_dyn_x86/cache.h | 25 ++++++++++++++++++++-- src/cpu/core_dyn_x86/decoder.h | 39 +++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index ce3f2556..7fe2965e 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -15,6 +15,9 @@ public: Bit8u * start; //Where in the cache are we Bitu size; CacheBlock * next; + Bit8u * wmapmask; + Bit16u maskstart; + Bit16u masklen; } cache; struct { Bitu index; @@ -222,8 +225,22 @@ public: //Will crash if a block isn't found, which should never happen. } *where=block->hash.next; - for (Bitu i=block->page.start;i<=block->page.end;i++) { - if (write_map[i]) write_map[i]--; + if (GCC_UNLIKELY(block->cache.wmapmask!=NULL)) { + for (Bitu i=block->page.start;icache.maskstart;i++) { + if (write_map[i]) write_map[i]--; + } + Bitu maskct=0; + for (Bitu i=block->cache.maskstart;i<=block->page.end;i++,maskct++) { + if (write_map[i]) { + if ((maskct>=block->cache.masklen) || (!block->cache.wmapmask[maskct])) write_map[i]--; + } + } + free(block->cache.wmapmask); + block->cache.wmapmask=NULL; + } else { + for (Bitu i=block->page.start;i<=block->page.end;i++) { + if (write_map[i]) write_map[i]--; + } } } void Release(void) { @@ -324,6 +341,10 @@ void CacheBlock::Clear(void) { page.handler->DelCacheBlock(this); page.handler=0; } + if (cache.wmapmask){ + free(cache.wmapmask); + cache.wmapmask=NULL; + } } diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index caec4c29..ba03a074 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -140,11 +140,43 @@ static Bit32u decode_fetchd(void) { return mem_readd(decode.code-4); } +#define START_WMMEM 64 + +static void INLINE decode_increase_wmapmask(Bitu size) { + Bitu mapidx; + CacheBlock* activecb=decode.active_block; + if (GCC_UNLIKELY(!activecb->cache.wmapmask)) { + activecb->cache.wmapmask=(Bit8u*)malloc(START_WMMEM); + memset(activecb->cache.wmapmask,0,START_WMMEM); + activecb->cache.maskstart=decode.page.index; + activecb->cache.masklen=START_WMMEM; + mapidx=0; + } else { + mapidx=decode.page.index-activecb->cache.maskstart; + if (GCC_UNLIKELY(mapidx+size>=activecb->cache.masklen)) { + Bitu newmasklen=activecb->cache.masklen*4; + if (newmasklencache.wmapmask,activecb->cache.masklen); + free(activecb->cache.wmapmask); + activecb->cache.wmapmask=tempmem; + activecb->cache.masklen=newmasklen; + } + } + switch (size) { + case 1 : activecb->cache.wmapmask[mapidx]+=0x01; break; + case 2 : (*(Bit16u*)&activecb->cache.wmapmask[mapidx])+=0x0101; break; + case 4 : (*(Bit32u*)&activecb->cache.wmapmask[mapidx])+=0x01010101; break; + } +} + static bool decode_fetchb_imm(Bitu & val) { if (decode.page.index<4096) { Bitu index=(decode.code>>12); if (paging.tlb.read[index]) { val=(Bitu)(paging.tlb.read[index]+decode.code); + decode_increase_wmapmask(1); decode.code++; decode.page.index++; return true; @@ -158,6 +190,7 @@ static bool decode_fetchw_imm(Bitu & val) { Bitu index=(decode.code>>12); if (paging.tlb.read[index]) { val=(Bitu)(paging.tlb.read[index]+decode.code); + decode_increase_wmapmask(2); decode.code+=2; decode.page.index+=2; return true; @@ -171,6 +204,7 @@ static bool decode_fetchd_imm(Bitu & val) { Bitu index=(decode.code>>12); if (paging.tlb.read[index]) { val=(Bitu)(paging.tlb.read[index]+decode.code); + decode_increase_wmapmask(4); decode.code+=4; decode.page.index+=4; return true; @@ -1919,7 +1953,10 @@ restart_prefix: if (!decode.page.invmap) opcode=decode_fetchb(); else { if (decode.page.index<4096) { - if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) goto illegalopcode; + if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) { + decode.page.index++; + goto illegalopcode; + } opcode=decode_fetchb(); } else { opcode=decode_fetchb();