Start reducing size of codeblock_t structure.
Re-arrange all variables needed to run a block to fit in a single cache line.
This commit is contained in:
parent
d63176e472
commit
2007c25177
5 changed files with 62 additions and 40 deletions
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
uint32_t cpu_cur_status = 0;
|
||||
uint16_t cpu_cur_status = 0;
|
||||
|
||||
int cpu_reps, cpu_reps_latched;
|
||||
int cpu_notreps, cpu_notreps_latched;
|
||||
|
|
@ -663,16 +663,15 @@ void exec386_dynarec(int cycs)
|
|||
valid_block = 0;
|
||||
}
|
||||
}
|
||||
if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7))
|
||||
if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7))
|
||||
{
|
||||
/*FPU top-of-stack does not match the value this block was compiled
|
||||
with, re-compile using dynamic top-of-stack*/
|
||||
block->flags &= ~CODEBLOCK_STATIC_TOP;
|
||||
block->was_recompiled = 0;
|
||||
block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED);
|
||||
}
|
||||
}
|
||||
|
||||
if (valid_block && block->was_recompiled)
|
||||
if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED))
|
||||
{
|
||||
void (*code)() = (void *)&block->data[BLOCK_START];
|
||||
|
||||
|
|
|
|||
|
|
@ -37,10 +37,19 @@
|
|||
|
||||
typedef struct codeblock_t
|
||||
{
|
||||
uint32_t pc;
|
||||
uint32_t _cs;
|
||||
uint32_t phys, phys_2;
|
||||
uint16_t status;
|
||||
uint16_t flags;
|
||||
uint16_t ins;
|
||||
uint8_t TOP;
|
||||
uint32_t endpc;
|
||||
uint8_t *data;
|
||||
|
||||
uint64_t page_mask, page_mask2;
|
||||
uint64_t *dirty_mask, *dirty_mask2;
|
||||
uint64_t cmp;
|
||||
|
||||
|
||||
/*Previous and next pointers, for the codeblock list associated with
|
||||
each physical page. Two sets of pointers, as a codeblock can be
|
||||
present in two pages.*/
|
||||
|
|
@ -50,21 +59,6 @@ typedef struct codeblock_t
|
|||
/*Pointers for codeblock tree, used to search for blocks when hash lookup
|
||||
fails.*/
|
||||
struct codeblock_t *parent, *left, *right;
|
||||
|
||||
int pnt;
|
||||
int ins;
|
||||
|
||||
int was_recompiled;
|
||||
int TOP;
|
||||
|
||||
uint32_t pc;
|
||||
uint32_t _cs;
|
||||
uint32_t endpc;
|
||||
uint32_t phys, phys_2;
|
||||
uint32_t status;
|
||||
uint32_t flags;
|
||||
|
||||
uint8_t *data;
|
||||
} codeblock_t;
|
||||
|
||||
uint8_t *codeblock_data;
|
||||
|
|
@ -73,6 +67,8 @@ uint8_t *codeblock_data;
|
|||
#define CODEBLOCK_HAS_FPU 1
|
||||
/*Code block is always entered with the same FPU top-of-stack*/
|
||||
#define CODEBLOCK_STATIC_TOP 2
|
||||
/*Code block has been compiled*/
|
||||
#define CODEBLOCK_WAS_RECOMPILED 4
|
||||
|
||||
#define BLOCK_PC_INVALID 0xffffffff
|
||||
|
||||
|
|
@ -83,13 +79,14 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
|
|||
|
||||
while (block)
|
||||
{
|
||||
if (a == block->cmp)
|
||||
uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32);
|
||||
if (a == block_cmp)
|
||||
{
|
||||
if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
|
||||
((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)))
|
||||
break;
|
||||
}
|
||||
if (a < block->cmp)
|
||||
if (a < block_cmp)
|
||||
block = block->left;
|
||||
else
|
||||
block = block->right;
|
||||
|
|
@ -102,8 +99,7 @@ static inline void codeblock_tree_add(codeblock_t *new_block)
|
|||
{
|
||||
codeblock_t *block = pages[new_block->phys >> 12].head;
|
||||
uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32);
|
||||
new_block->cmp = a;
|
||||
|
||||
|
||||
if (!block)
|
||||
{
|
||||
pages[new_block->phys >> 12].head = new_block;
|
||||
|
|
@ -112,17 +108,20 @@ static inline void codeblock_tree_add(codeblock_t *new_block)
|
|||
else
|
||||
{
|
||||
codeblock_t *old_block = NULL;
|
||||
uint64_t old_block_cmp;
|
||||
|
||||
while (block)
|
||||
{
|
||||
old_block = block;
|
||||
if (a < old_block->cmp)
|
||||
old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32);
|
||||
|
||||
if (a < old_block_cmp)
|
||||
block = block->left;
|
||||
else
|
||||
block = block->right;
|
||||
}
|
||||
|
||||
if (a < old_block->cmp)
|
||||
if (a < old_block_cmp)
|
||||
old_block->left = new_block;
|
||||
else
|
||||
old_block->right = new_block;
|
||||
|
|
|
|||
|
|
@ -277,7 +277,6 @@ void codegen_block_init(uint32_t phys_addr)
|
|||
block->ins = 0;
|
||||
block->pc = cs + cpu_state.pc;
|
||||
block->_cs = cs;
|
||||
block->pnt = block_current;
|
||||
block->phys = phys_addr;
|
||||
block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK];
|
||||
block->dirty_mask2 = NULL;
|
||||
|
|
@ -287,8 +286,6 @@ void codegen_block_init(uint32_t phys_addr)
|
|||
block->flags = CODEBLOCK_STATIC_TOP;
|
||||
block->status = cpu_cur_status;
|
||||
|
||||
block->was_recompiled = 0;
|
||||
|
||||
recomp_page = block->phys & ~0xfff;
|
||||
|
||||
codeblock_tree_add(block);
|
||||
|
|
@ -301,6 +298,11 @@ ir_data_t *codegen_get_ir_data()
|
|||
return ir_data;
|
||||
}
|
||||
|
||||
static int get_block_nr(codeblock_t *block)
|
||||
{
|
||||
return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t);
|
||||
}
|
||||
|
||||
void codegen_block_start_recompile(codeblock_t *block)
|
||||
{
|
||||
page_t *page = &pages[block->phys >> 12];
|
||||
|
|
@ -309,9 +311,9 @@ void codegen_block_start_recompile(codeblock_t *block)
|
|||
mem_flush_write_page(block->phys, cs+cpu_state.pc);
|
||||
|
||||
block_num = HASH(block->phys);
|
||||
block_current = block->pnt;
|
||||
block_current = get_block_nr(block);//block->pnt;
|
||||
|
||||
if (block->pc != cs + cpu_state.pc || block->was_recompiled)
|
||||
if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED))
|
||||
fatal("Recompile to used block!\n");
|
||||
|
||||
block->status = cpu_cur_status;
|
||||
|
|
@ -342,7 +344,7 @@ void codegen_block_start_recompile(codeblock_t *block)
|
|||
cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1;
|
||||
|
||||
block->TOP = cpu_state.TOP & 7;
|
||||
block->was_recompiled = 1;
|
||||
block->flags |= CODEBLOCK_WAS_RECOMPILED;
|
||||
|
||||
codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS);
|
||||
codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
|
||||
|
||||
#include <stddef.h>
|
||||
#include "ibm.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_backend.h"
|
||||
|
|
@ -260,7 +261,28 @@ void codegen_backend_init()
|
|||
long pagesize = sysconf(_SC_PAGESIZE);
|
||||
long pagemask = ~(pagesize - 1);
|
||||
#endif
|
||||
|
||||
pclog("sizeof(codeblock_t)=%i\n", sizeof(codeblock_t));
|
||||
pclog(" offsetof(codeblock_t, pc)=%i\n", offsetof(codeblock_t, pc));
|
||||
pclog(" offsetof(codeblock_t, _cs)=%i\n", offsetof(codeblock_t, _cs));
|
||||
pclog(" offsetof(codeblock_t, phys)=%i\n", offsetof(codeblock_t, phys));
|
||||
pclog(" offsetof(codeblock_t, phys_2)=%i\n", offsetof(codeblock_t, phys_2));
|
||||
pclog(" offsetof(codeblock_t, status)=%i\n", offsetof(codeblock_t, status));
|
||||
pclog(" offsetof(codeblock_t, flags)=%i\n", offsetof(codeblock_t, flags));
|
||||
pclog(" offsetof(codeblock_t, ins)=%i\n", offsetof(codeblock_t, ins));
|
||||
pclog(" offsetof(codeblock_t, TOP)=%i\n", offsetof(codeblock_t, TOP));
|
||||
pclog(" offsetof(codeblock_t, endpc)=%i\n", offsetof(codeblock_t, endpc));
|
||||
pclog(" offsetof(codeblock_t, data)=%i\n", offsetof(codeblock_t, data));
|
||||
pclog(" offsetof(codeblock_t, page_mask=%i\n", offsetof(codeblock_t, page_mask));
|
||||
pclog(" offsetof(codeblock_t, page_mask2=%i\n", offsetof(codeblock_t, page_mask2));
|
||||
pclog(" offsetof(codeblock_t, dirty_mask=%i\n", offsetof(codeblock_t, dirty_mask));
|
||||
pclog(" offsetof(codeblock_t, dirty_mask2=%i\n", offsetof(codeblock_t, dirty_mask2));
|
||||
pclog(" offsetof(codeblock_t, prev=%i\n", offsetof(codeblock_t, prev));
|
||||
pclog(" offsetof(codeblock_t, next=%i\n", offsetof(codeblock_t, next));
|
||||
pclog(" offsetof(codeblock_t, prev_2=%i\n", offsetof(codeblock_t, prev_2));
|
||||
pclog(" offsetof(codeblock_t, next_2=%i\n", offsetof(codeblock_t, next_2));
|
||||
pclog(" offsetof(codeblock_t, parent=%i\n", offsetof(codeblock_t, parent));
|
||||
pclog(" offsetof(codeblock_t, left=%i\n", offsetof(codeblock_t, left));
|
||||
pclog(" offsetof(codeblock_t, right=%i\n", offsetof(codeblock_t, right));
|
||||
codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t));
|
||||
#if defined WIN32 || defined _WIN32 || defined _WIN32
|
||||
codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
|
|
|
|||
10
src/ibm.h
10
src/ibm.h
|
|
@ -194,7 +194,7 @@ struct
|
|||
|
||||
#define cycles cpu_state._cycles
|
||||
|
||||
extern uint32_t cpu_cur_status;
|
||||
extern uint16_t cpu_cur_status;
|
||||
|
||||
/*The flags below must match in both cpu_cur_status and block->status for a block
|
||||
to be valid*/
|
||||
|
|
@ -202,13 +202,13 @@ extern uint32_t cpu_cur_status;
|
|||
#define CPU_STATUS_STACK32 (1 << 1)
|
||||
#define CPU_STATUS_PMODE (1 << 2)
|
||||
#define CPU_STATUS_V86 (1 << 3)
|
||||
#define CPU_STATUS_FLAGS 0xffff
|
||||
#define CPU_STATUS_FLAGS 0xff
|
||||
|
||||
/*If the flags below are set in cpu_cur_status, they must be set in block->status.
|
||||
Otherwise they are ignored*/
|
||||
#define CPU_STATUS_NOTFLATDS (1 << 16)
|
||||
#define CPU_STATUS_NOTFLATSS (1 << 17)
|
||||
#define CPU_STATUS_MASK 0xffff0000
|
||||
#define CPU_STATUS_NOTFLATDS (1 << 8)
|
||||
#define CPU_STATUS_NOTFLATSS (1 << 9)
|
||||
#define CPU_STATUS_MASK 0xff00
|
||||
|
||||
#define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue