Reduce self modifying code granularity from 64 bytes to 16.

This commit is contained in:
SarahW 2017-06-13 21:05:10 +01:00
commit 3a7c4687d6
6 changed files with 95 additions and 78 deletions

View file

@ -1440,7 +1440,7 @@ void exec386_dynarec(int cycs)
{ {
uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
if (page->code_present_mask & mask) if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask)
{ {
/*Walk page tree to see if we find the correct block*/ /*Walk page tree to see if we find the correct block*/
codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
@ -1453,10 +1453,11 @@ void exec386_dynarec(int cycs)
} }
} }
} }
if (valid_block && (block->page_mask & page->dirty_mask))
if (valid_block && (block->page_mask & *block->dirty_mask))
{ {
codegen_check_flush(page, page->dirty_mask, phys_addr); codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr);
page->dirty_mask = 0; page->dirty_mask[(phys_addr >> 10) & 3] = 0;
if (!block->pc) if (!block->pc)
valid_block = 0; valid_block = 0;
} }
@ -1469,15 +1470,14 @@ void exec386_dynarec(int cycs)
allow the first page to be interpreted and for allow the first page to be interpreted and for
the page fault to occur when the page boundary the page fault to occur when the page boundary
is actually crossed.*/ is actually crossed.*/
uint32_t phys_addr_2 = get_phys_noabrt(block->endpc) & ~0xfff; uint32_t phys_addr_2 = get_phys_noabrt(block->endpc);
page_t *page_2 = &pages[phys_addr_2 >> 12]; page_t *page_2 = &pages[phys_addr_2 >> 12];
if ((block->phys_2 ^ phys_addr_2) & ~0xfff) if ((block->phys_2 ^ phys_addr_2) & ~0xfff)
valid_block = 0; valid_block = 0;
else if (block->page_mask2 & page_2->dirty_mask) else if (block->page_mask2 & *block->dirty_mask2)
{ {
codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2);
page_2->dirty_mask = 0; page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0;
if (!block->pc) if (!block->pc)
valid_block = 0; valid_block = 0;
} }
@ -1562,7 +1562,7 @@ inrecomp=0;
will prevent any block from spanning more than will prevent any block from spanning more than
2 pages. In practice this limit will never be 2 pages. In practice this limit will never be
hit, as host block size is only 2kB*/ hit, as host block size is only 2kB*/
if ((cpu_state.pc - start_pc) > 4000) if ((cpu_state.pc - start_pc) > 1000)
CPU_BLOCK_END(); CPU_BLOCK_END();
if (trap) if (trap)
@ -1638,7 +1638,7 @@ inrecomp=0;
will prevent any block from spanning more than will prevent any block from spanning more than
2 pages. In practice this limit will never be 2 pages. In practice this limit will never be
hit, as host block size is only 2kB*/ hit, as host block size is only 2kB*/
if ((cpu_state.pc - start_pc) > 4000) if ((cpu_state.pc - start_pc) > 1000)
CPU_BLOCK_END(); CPU_BLOCK_END();
if (trap) if (trap)

View file

@ -36,6 +36,7 @@
typedef struct codeblock_t typedef struct codeblock_t
{ {
uint64_t page_mask, page_mask2; uint64_t page_mask, page_mask2;
uint64_t *dirty_mask, *dirty_mask2;
uint64_t cmp; uint64_t cmp;
/*Previous and next pointers, for the codeblock list associated with /*Previous and next pointers, for the codeblock list associated with
@ -236,8 +237,10 @@ static inline void codeblock_tree_delete(codeblock_t *block)
} }
} }
#define PAGE_MASK_INDEX_MASK 3
#define PAGE_MASK_INDEX_SHIFT 10
#define PAGE_MASK_MASK 63 #define PAGE_MASK_MASK 63
#define PAGE_MASK_SHIFT 6 #define PAGE_MASK_SHIFT 4
extern codeblock_t *codeblock; extern codeblock_t *codeblock;

View file

@ -99,7 +99,7 @@ void codegen_reset()
void dump_block() void dump_block()
{ {
codeblock_t *block = pages[0x119000 >> 12].block; /* codeblock_t *block = pages[0x119000 >> 12].block;
pclog("dump_block:\n"); pclog("dump_block:\n");
while (block) while (block)
@ -112,12 +112,12 @@ void dump_block()
block = block->next; block = block->next;
} }
pclog("dump_block done\n"); pclog("dump_block done\n");*/
} }
static void add_to_block_list(codeblock_t *block) static void add_to_block_list(codeblock_t *block)
{ {
codeblock_t *block_prev = pages[block->phys >> 12].block; codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3];
if (!block->page_mask) if (!block->page_mask)
fatal("add_to_block_list - mask = 0\n"); fatal("add_to_block_list - mask = 0\n");
@ -126,12 +126,12 @@ static void add_to_block_list(codeblock_t *block)
{ {
block->next = block_prev; block->next = block_prev;
block_prev->prev = block; block_prev->prev = block;
pages[block->phys >> 12].block = block; pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block;
} }
else else
{ {
block->next = NULL; block->next = NULL;
pages[block->phys >> 12].block = block; pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block;
} }
if (block->next) if (block->next)
@ -142,18 +142,18 @@ static void add_to_block_list(codeblock_t *block)
if (block->page_mask2) if (block->page_mask2)
{ {
block_prev = pages[block->phys_2 >> 12].block_2; block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3];
if (block_prev) if (block_prev)
{ {
block->next_2 = block_prev; block->next_2 = block_prev;
block_prev->prev_2 = block; block_prev->prev_2 = block;
pages[block->phys_2 >> 12].block_2 = block; pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block;
} }
else else
{ {
block->next_2 = NULL; block->next_2 = NULL;
pages[block->phys_2 >> 12].block_2 = block; pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block;
} }
} }
} }
@ -171,7 +171,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc)
} }
else else
{ {
pages[block->phys >> 12].block = block->next; pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next;
if (block->next) if (block->next)
block->next->prev = NULL; block->next->prev = NULL;
else else
@ -193,7 +193,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc)
else else
{ {
// pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2); // pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2);
pages[block->phys_2 >> 12].block_2 = block->next_2; pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2;
if (block->next_2) if (block->next_2)
block->next_2->prev_2 = NULL; block->next_2->prev_2 = NULL;
else else
@ -218,7 +218,7 @@ static void delete_block(codeblock_t *block)
void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
{ {
struct codeblock_t *block = page->block; struct codeblock_t *block = page->block[(phys_addr >> 10) & 3];
while (block) while (block)
{ {
@ -232,7 +232,7 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
block = block->next; block = block->next;
} }
block = page->block_2; block = page->block_2[(phys_addr >> 10) & 3];
while (block) while (block)
{ {
@ -252,7 +252,7 @@ void codegen_block_init(uint32_t phys_addr)
codeblock_t *block; codeblock_t *block;
page_t *page = &pages[phys_addr >> 12]; page_t *page = &pages[phys_addr >> 12];
if (!page->block) if (!page->block[(phys_addr >> 10) & 3])
mem_flush_write_page(phys_addr, cs+cpu_state.pc); mem_flush_write_page(phys_addr, cs+cpu_state.pc);
block_current = (block_current + 1) & BLOCK_MASK; block_current = (block_current + 1) & BLOCK_MASK;
@ -274,6 +274,8 @@ void codegen_block_init(uint32_t phys_addr)
block->_cs = cs; block->_cs = cs;
block->pnt = block_current; block->pnt = block_current;
block->phys = phys_addr; block->phys = phys_addr;
block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK];
block->dirty_mask2 = NULL;
block->next = block->prev = NULL; block->next = block->prev = NULL;
block->next_2 = block->prev_2 = NULL; block->next_2 = block->prev_2 = NULL;
block->page_mask = 0; block->page_mask = 0;
@ -291,7 +293,7 @@ void codegen_block_start_recompile(codeblock_t *block)
{ {
page_t *page = &pages[block->phys >> 12]; page_t *page = &pages[block->phys >> 12];
if (!page->block) if (!page->block[(block->phys >> 10) & 3])
mem_flush_write_page(block->phys, cs+cpu_state.pc); mem_flush_write_page(block->phys, cs+cpu_state.pc);
block_num = HASH(block->phys); block_num = HASH(block->phys);
@ -402,17 +404,19 @@ void codegen_block_remove()
void codegen_block_generate_end_mask() void codegen_block_generate_end_mask()
{ {
codeblock_t *block = &codeblock[block_current]; codeblock_t *block = &codeblock[block_current];
uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); uint32_t start_pc;
uint32_t end_pc = ((codegen_endpc + 3) & 0xffc) | (block->phys & ~0xfff); uint32_t end_pc;
block->endpc = codegen_endpc; block->endpc = codegen_endpc;
block->page_mask = 0; block->page_mask = 0;
start_pc = block->pc & 0xffc; start_pc = (block->pc & 0x3ff) & ~15;
start_pc &= ~PAGE_MASK_MASK; if ((block->pc ^ block->endpc) & ~0x3ff)
end_pc = ((block->endpc & 0xffc) + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; end_pc = 0x3ff & ~15;
if (end_pc > 0xfff || end_pc < start_pc) else
end_pc = 0xfff; end_pc = (block->endpc & 0x3ff) & ~15;
if (end_pc < start_pc)
end_pc = 0x3ff;
start_pc >>= PAGE_MASK_SHIFT; start_pc >>= PAGE_MASK_SHIFT;
end_pc >>= PAGE_MASK_SHIFT; end_pc >>= PAGE_MASK_SHIFT;
@ -423,26 +427,27 @@ void codegen_block_generate_end_mask()
// pclog(" %08x %llx\n", start_pc, block->page_mask); // pclog(" %08x %llx\n", start_pc, block->page_mask);
} }
pages[block->phys >> 12].code_present_mask |= block->page_mask; pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask;
block->phys_2 = -1; block->phys_2 = -1;
block->page_mask2 = 0; block->page_mask2 = 0;
block->next_2 = block->prev_2 = NULL; block->next_2 = block->prev_2 = NULL;
if ((block->pc ^ block->endpc) & ~0xfff) if ((block->pc ^ block->endpc) & ~0x3ff)
{ {
block->phys_2 = get_phys_noabrt(block->endpc); block->phys_2 = get_phys_noabrt(block->endpc);
if (block->phys_2 != -1) if (block->phys_2 != -1)
{ {
// pclog("start block - %08x %08x %p %p %p %08x\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, (void *)pages[block->phys_2 >> 12].block_2, block->phys_2); page_t *page_2 = &pages[block->phys_2 >> 12];
start_pc = 0; start_pc = 0;
end_pc = (block->endpc & 0xfff) >> PAGE_MASK_SHIFT; end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT;
for (; start_pc <= end_pc; start_pc++) for (; start_pc <= end_pc; start_pc++)
block->page_mask2 |= ((uint64_t)1 << start_pc); block->page_mask2 |= ((uint64_t)1 << start_pc);
page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2;
if (!pages[block->phys_2 >> 12].block_2)
if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3])
mem_flush_write_page(block->phys_2, block->endpc); mem_flush_write_page(block->phys_2, block->endpc);
// pclog("New block - %08x %08x %p %p phys %08x %08x %016llx\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, block->phys, block->phys_2, block->page_mask2);
if (!block->page_mask2) if (!block->page_mask2)
fatal("!page_mask2\n"); fatal("!page_mask2\n");
if (block->next_2) if (block->next_2)
@ -451,6 +456,8 @@ void codegen_block_generate_end_mask()
if (!block->next_2->pc) if (!block->next_2->pc)
fatal("block->next_2->pc=0 %p\n", (void *)block->next_2); fatal("block->next_2->pc=0 %p\n", (void *)block->next_2);
} }
block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK];
} }
} }

View file

@ -1212,7 +1212,7 @@ void codegen_reset()
void dump_block() void dump_block()
{ {
codeblock_t *block = pages[0x119000 >> 12].block; /* codeblock_t *block = pages[0x119000 >> 12].block;
pclog("dump_block:\n"); pclog("dump_block:\n");
while (block) while (block)
@ -1225,12 +1225,12 @@ void dump_block()
block = block->next; block = block->next;
} }
pclog("dump_block done\n"); pclog("dump_block done\n");*/
} }
static void add_to_block_list(codeblock_t *block) static void add_to_block_list(codeblock_t *block)
{ {
codeblock_t *block_prev = pages[block->phys >> 12].block; codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3];
if (!block->page_mask) if (!block->page_mask)
fatal("add_to_block_list - mask = 0\n"); fatal("add_to_block_list - mask = 0\n");
@ -1239,12 +1239,12 @@ static void add_to_block_list(codeblock_t *block)
{ {
block->next = block_prev; block->next = block_prev;
block_prev->prev = block; block_prev->prev = block;
pages[block->phys >> 12].block = block; pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block;
} }
else else
{ {
block->next = NULL; block->next = NULL;
pages[block->phys >> 12].block = block; pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block;
} }
if (block->next) if (block->next)
@ -1255,18 +1255,18 @@ static void add_to_block_list(codeblock_t *block)
if (block->page_mask2) if (block->page_mask2)
{ {
block_prev = pages[block->phys_2 >> 12].block_2; block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3];
if (block_prev) if (block_prev)
{ {
block->next_2 = block_prev; block->next_2 = block_prev;
block_prev->prev_2 = block; block_prev->prev_2 = block;
pages[block->phys_2 >> 12].block_2 = block; pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block;
} }
else else
{ {
block->next_2 = NULL; block->next_2 = NULL;
pages[block->phys_2 >> 12].block_2 = block; pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block;
} }
} }
} }
@ -1284,7 +1284,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc)
} }
else else
{ {
pages[block->phys >> 12].block = block->next; pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next;
if (block->next) if (block->next)
block->next->prev = NULL; block->next->prev = NULL;
else else
@ -1306,7 +1306,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc)
else else
{ {
// pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2); // pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2);
pages[block->phys_2 >> 12].block_2 = block->next_2; pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2;
if (block->next_2) if (block->next_2)
block->next_2->prev_2 = NULL; block->next_2->prev_2 = NULL;
else else
@ -1331,7 +1331,7 @@ static void delete_block(codeblock_t *block)
void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
{ {
struct codeblock_t *block = page->block; struct codeblock_t *block = page->block[(phys_addr >> 10) & 3];
while (block) while (block)
{ {
@ -1345,7 +1345,7 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
block = block->next; block = block->next;
} }
block = page->block_2; block = page->block_2[(phys_addr >> 10) & 3];
while (block) while (block)
{ {
@ -1365,7 +1365,7 @@ void codegen_block_init(uint32_t phys_addr)
codeblock_t *block; codeblock_t *block;
page_t *page = &pages[phys_addr >> 12]; page_t *page = &pages[phys_addr >> 12];
if (!page->block) if (!page->block[(phys_addr >> 10) & 3])
mem_flush_write_page(phys_addr, cs+cpu_state.pc); mem_flush_write_page(phys_addr, cs+cpu_state.pc);
block_current = (block_current + 1) & BLOCK_MASK; block_current = (block_current + 1) & BLOCK_MASK;
@ -1387,6 +1387,8 @@ void codegen_block_init(uint32_t phys_addr)
block->_cs = cs; block->_cs = cs;
block->pnt = block_current; block->pnt = block_current;
block->phys = phys_addr; block->phys = phys_addr;
block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK];
block->dirty_mask2 = NULL;
block->next = block->prev = NULL; block->next = block->prev = NULL;
block->next_2 = block->prev_2 = NULL; block->next_2 = block->prev_2 = NULL;
block->page_mask = 0; block->page_mask = 0;
@ -1404,7 +1406,7 @@ void codegen_block_start_recompile(codeblock_t *block)
{ {
page_t *page = &pages[block->phys >> 12]; page_t *page = &pages[block->phys >> 12];
if (!page->block) if (!page->block[(block->phys >> 10) & 3])
mem_flush_write_page(block->phys, cs+cpu_state.pc); mem_flush_write_page(block->phys, cs+cpu_state.pc);
block_num = HASH(block->phys); block_num = HASH(block->phys);
@ -1489,17 +1491,19 @@ void codegen_block_remove()
void codegen_block_generate_end_mask() void codegen_block_generate_end_mask()
{ {
codeblock_t *block = &codeblock[block_current]; codeblock_t *block = &codeblock[block_current];
uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); uint32_t start_pc;
uint32_t end_pc = ((codegen_endpc + 3) & 0xffc) | (block->phys & ~0xfff); uint32_t end_pc;
block->endpc = codegen_endpc; block->endpc = codegen_endpc;
block->page_mask = 0; block->page_mask = 0;
start_pc = block->pc & 0xffc; start_pc = (block->pc & 0x3ff) & ~15;
start_pc &= ~PAGE_MASK_MASK; if ((block->pc ^ block->endpc) & ~0x3ff)
end_pc = ((block->endpc & 0xffc) + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; end_pc = 0x3ff & ~15;
if (end_pc > 0xfff || end_pc < start_pc) else
end_pc = 0xfff; end_pc = (block->endpc & 0x3ff) & ~15;
if (end_pc < start_pc)
end_pc = 0x3ff;
start_pc >>= PAGE_MASK_SHIFT; start_pc >>= PAGE_MASK_SHIFT;
end_pc >>= PAGE_MASK_SHIFT; end_pc >>= PAGE_MASK_SHIFT;
@ -1510,26 +1514,27 @@ void codegen_block_generate_end_mask()
// pclog(" %08x %llx\n", start_pc, block->page_mask); // pclog(" %08x %llx\n", start_pc, block->page_mask);
} }
pages[block->phys >> 12].code_present_mask |= block->page_mask; pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask;
block->phys_2 = -1; block->phys_2 = -1;
block->page_mask2 = 0; block->page_mask2 = 0;
block->next_2 = block->prev_2 = NULL; block->next_2 = block->prev_2 = NULL;
if ((block->pc ^ block->endpc) & ~0xfff) if ((block->pc ^ block->endpc) & ~0x3ff)
{ {
block->phys_2 = get_phys_noabrt(block->endpc); block->phys_2 = get_phys_noabrt(block->endpc);
if (block->phys_2 != -1) if (block->phys_2 != -1)
{ {
// pclog("start block - %08x %08x %p %p %p %08x\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, (void *)pages[block->phys_2 >> 12].block_2, block->phys_2); page_t *page_2 = &pages[block->phys_2 >> 12];
start_pc = 0; start_pc = 0;
end_pc = (block->endpc & 0xfff) >> PAGE_MASK_SHIFT; end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT;
for (; start_pc <= end_pc; start_pc++) for (; start_pc <= end_pc; start_pc++)
block->page_mask2 |= ((uint64_t)1 << start_pc); block->page_mask2 |= ((uint64_t)1 << start_pc);
page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2;
if (!pages[block->phys_2 >> 12].block_2) if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3])
mem_flush_write_page(block->phys_2, block->endpc); mem_flush_write_page(block->phys_2, block->endpc);
// pclog("New block - %08x %08x %p %p phys %08x %08x %016llx\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, block->phys, block->phys_2, block->page_mask2);
if (!block->page_mask2) if (!block->page_mask2)
fatal("!page_mask2\n"); fatal("!page_mask2\n");
if (block->next_2) if (block->next_2)
@ -1538,6 +1543,8 @@ void codegen_block_generate_end_mask()
if (!block->next_2->pc) if (!block->next_2->pc)
fatal("block->next_2->pc=0 %p\n", (void *)block->next_2); fatal("block->next_2->pc=0 %p\n", (void *)block->next_2);
} }
block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK];
} }
} }

View file

@ -988,7 +988,7 @@ void addwritelookup(uint32_t virt, uint32_t phys)
// if (page_lookup[virt >> 12] && (writelookup2[virt>>12] != 0xffffffff)) // if (page_lookup[virt >> 12] && (writelookup2[virt>>12] != 0xffffffff))
// fatal("Bad write mapping\n"); // fatal("Bad write mapping\n");
if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page)
page_lookup[virt >> 12] = &pages[phys >> 12];//(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; page_lookup[virt >> 12] = &pages[phys >> 12];//(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)];
else else
writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)];
@ -1516,7 +1516,7 @@ void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
{ {
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
// pclog("mem_write_ramb_page: %08x %02x %08x %llx %llx\n", addr, val, cs+pc, p->dirty_mask, mask); // pclog("mem_write_ramb_page: %08x %02x %08x %llx %llx\n", addr, val, cs+pc, p->dirty_mask, mask);
p->dirty_mask |= mask; p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
p->mem[addr & 0xfff] = val; p->mem[addr & 0xfff] = val;
} }
} }
@ -1525,10 +1525,10 @@ void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile)
{ {
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
if ((addr & 0x3f) == 0x3f) if ((addr & 0xf) == 0xf)
mask |= (mask << 1); mask |= (mask << 1);
// pclog("mem_write_ramw_page: %08x %04x %08x\n", addr, val, cs+pc); // pclog("mem_write_ramw_page: %08x %04x %08x\n", addr, val, cs+pc);
p->dirty_mask |= mask; p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
*(uint16_t *)&p->mem[addr & 0xfff] = val; *(uint16_t *)&p->mem[addr & 0xfff] = val;
} }
} }
@ -1537,10 +1537,10 @@ void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile)
{ {
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
if ((addr & 0x3f) >= 0x3d) if ((addr & 0xf) >= 0xd)
mask |= (mask << 1); mask |= (mask << 1);
// pclog("mem_write_raml_page: %08x %08x %08x\n", addr, val, cs+pc); // pclog("mem_write_raml_page: %08x %08x %08x\n", addr, val, cs+pc);
p->dirty_mask |= mask; p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
*(uint32_t *)&p->mem[addr & 0xfff] = val; *(uint32_t *)&p->mem[addr & 0xfff] = val;
} }
} }
@ -1615,7 +1615,7 @@ void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
{ {
uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
pages[start_addr >> 12].dirty_mask |= mask; pages[start_addr >> 12].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
} }
} }
@ -2027,8 +2027,8 @@ void mem_reset_page_blocks()
pages[c].write_b = mem_write_ramb_page; pages[c].write_b = mem_write_ramb_page;
pages[c].write_w = mem_write_ramw_page; pages[c].write_w = mem_write_ramw_page;
pages[c].write_l = mem_write_raml_page; pages[c].write_l = mem_write_raml_page;
pages[c].block = NULL; pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL;
pages[c].block_2 = NULL; pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL;
} }
} }

View file

@ -112,12 +112,12 @@ typedef struct page_t
uint8_t *mem; uint8_t *mem;
struct codeblock_t *block, *block_2; struct codeblock_t *block[4], *block_2[4];
/*Head of codeblock tree associated with this page*/ /*Head of codeblock tree associated with this page*/
struct codeblock_t *head; struct codeblock_t *head;
uint64_t code_present_mask, dirty_mask; uint64_t code_present_mask[4], dirty_mask[4];
} page_t; } page_t;
extern page_t *pages; extern page_t *pages;