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
|
#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_reps, cpu_reps_latched;
|
||||||
int cpu_notreps, cpu_notreps_latched;
|
int cpu_notreps, cpu_notreps_latched;
|
||||||
|
|
@ -663,16 +663,15 @@ void exec386_dynarec(int cycs)
|
||||||
valid_block = 0;
|
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
|
/*FPU top-of-stack does not match the value this block was compiled
|
||||||
with, re-compile using dynamic top-of-stack*/
|
with, re-compile using dynamic top-of-stack*/
|
||||||
block->flags &= ~CODEBLOCK_STATIC_TOP;
|
block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED);
|
||||||
block->was_recompiled = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid_block && block->was_recompiled)
|
if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED))
|
||||||
{
|
{
|
||||||
void (*code)() = (void *)&block->data[BLOCK_START];
|
void (*code)() = (void *)&block->data[BLOCK_START];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,19 @@
|
||||||
|
|
||||||
typedef struct codeblock_t
|
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 page_mask, page_mask2;
|
||||||
uint64_t *dirty_mask, *dirty_mask2;
|
uint64_t *dirty_mask, *dirty_mask2;
|
||||||
uint64_t cmp;
|
|
||||||
|
|
||||||
/*Previous and next pointers, for the codeblock list associated with
|
/*Previous and next pointers, for the codeblock list associated with
|
||||||
each physical page. Two sets of pointers, as a codeblock can be
|
each physical page. Two sets of pointers, as a codeblock can be
|
||||||
present in two pages.*/
|
present in two pages.*/
|
||||||
|
|
@ -50,21 +59,6 @@ typedef struct codeblock_t
|
||||||
/*Pointers for codeblock tree, used to search for blocks when hash lookup
|
/*Pointers for codeblock tree, used to search for blocks when hash lookup
|
||||||
fails.*/
|
fails.*/
|
||||||
struct codeblock_t *parent, *left, *right;
|
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;
|
} codeblock_t;
|
||||||
|
|
||||||
uint8_t *codeblock_data;
|
uint8_t *codeblock_data;
|
||||||
|
|
@ -73,6 +67,8 @@ uint8_t *codeblock_data;
|
||||||
#define CODEBLOCK_HAS_FPU 1
|
#define CODEBLOCK_HAS_FPU 1
|
||||||
/*Code block is always entered with the same FPU top-of-stack*/
|
/*Code block is always entered with the same FPU top-of-stack*/
|
||||||
#define CODEBLOCK_STATIC_TOP 2
|
#define CODEBLOCK_STATIC_TOP 2
|
||||||
|
/*Code block has been compiled*/
|
||||||
|
#define CODEBLOCK_WAS_RECOMPILED 4
|
||||||
|
|
||||||
#define BLOCK_PC_INVALID 0xffffffff
|
#define BLOCK_PC_INVALID 0xffffffff
|
||||||
|
|
||||||
|
|
@ -83,13 +79,14 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
|
||||||
|
|
||||||
while (block)
|
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) &&
|
if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
|
||||||
((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)))
|
((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (a < block->cmp)
|
if (a < block_cmp)
|
||||||
block = block->left;
|
block = block->left;
|
||||||
else
|
else
|
||||||
block = block->right;
|
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;
|
codeblock_t *block = pages[new_block->phys >> 12].head;
|
||||||
uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32);
|
uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32);
|
||||||
new_block->cmp = a;
|
|
||||||
|
|
||||||
if (!block)
|
if (!block)
|
||||||
{
|
{
|
||||||
pages[new_block->phys >> 12].head = new_block;
|
pages[new_block->phys >> 12].head = new_block;
|
||||||
|
|
@ -112,17 +108,20 @@ static inline void codeblock_tree_add(codeblock_t *new_block)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
codeblock_t *old_block = NULL;
|
codeblock_t *old_block = NULL;
|
||||||
|
uint64_t old_block_cmp;
|
||||||
|
|
||||||
while (block)
|
while (block)
|
||||||
{
|
{
|
||||||
old_block = 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;
|
block = block->left;
|
||||||
else
|
else
|
||||||
block = block->right;
|
block = block->right;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a < old_block->cmp)
|
if (a < old_block_cmp)
|
||||||
old_block->left = new_block;
|
old_block->left = new_block;
|
||||||
else
|
else
|
||||||
old_block->right = new_block;
|
old_block->right = new_block;
|
||||||
|
|
|
||||||
|
|
@ -277,7 +277,6 @@ void codegen_block_init(uint32_t phys_addr)
|
||||||
block->ins = 0;
|
block->ins = 0;
|
||||||
block->pc = cs + cpu_state.pc;
|
block->pc = cs + cpu_state.pc;
|
||||||
block->_cs = cs;
|
block->_cs = cs;
|
||||||
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_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK];
|
||||||
block->dirty_mask2 = NULL;
|
block->dirty_mask2 = NULL;
|
||||||
|
|
@ -287,8 +286,6 @@ void codegen_block_init(uint32_t phys_addr)
|
||||||
block->flags = CODEBLOCK_STATIC_TOP;
|
block->flags = CODEBLOCK_STATIC_TOP;
|
||||||
block->status = cpu_cur_status;
|
block->status = cpu_cur_status;
|
||||||
|
|
||||||
block->was_recompiled = 0;
|
|
||||||
|
|
||||||
recomp_page = block->phys & ~0xfff;
|
recomp_page = block->phys & ~0xfff;
|
||||||
|
|
||||||
codeblock_tree_add(block);
|
codeblock_tree_add(block);
|
||||||
|
|
@ -301,6 +298,11 @@ ir_data_t *codegen_get_ir_data()
|
||||||
return 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)
|
void codegen_block_start_recompile(codeblock_t *block)
|
||||||
{
|
{
|
||||||
page_t *page = &pages[block->phys >> 12];
|
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);
|
mem_flush_write_page(block->phys, cs+cpu_state.pc);
|
||||||
|
|
||||||
block_num = HASH(block->phys);
|
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");
|
fatal("Recompile to used block!\n");
|
||||||
|
|
||||||
block->status = cpu_cur_status;
|
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;
|
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->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_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS);
|
||||||
codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS);
|
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
|
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
#include "codegen.h"
|
#include "codegen.h"
|
||||||
#include "codegen_backend.h"
|
#include "codegen_backend.h"
|
||||||
|
|
@ -260,7 +261,28 @@ void codegen_backend_init()
|
||||||
long pagesize = sysconf(_SC_PAGESIZE);
|
long pagesize = sysconf(_SC_PAGESIZE);
|
||||||
long pagemask = ~(pagesize - 1);
|
long pagemask = ~(pagesize - 1);
|
||||||
#endif
|
#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));
|
codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t));
|
||||||
#if defined WIN32 || defined _WIN32 || defined _WIN32
|
#if defined WIN32 || defined _WIN32 || defined _WIN32
|
||||||
codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
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
|
#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
|
/*The flags below must match in both cpu_cur_status and block->status for a block
|
||||||
to be valid*/
|
to be valid*/
|
||||||
|
|
@ -202,13 +202,13 @@ extern uint32_t cpu_cur_status;
|
||||||
#define CPU_STATUS_STACK32 (1 << 1)
|
#define CPU_STATUS_STACK32 (1 << 1)
|
||||||
#define CPU_STATUS_PMODE (1 << 2)
|
#define CPU_STATUS_PMODE (1 << 2)
|
||||||
#define CPU_STATUS_V86 (1 << 3)
|
#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.
|
/*If the flags below are set in cpu_cur_status, they must be set in block->status.
|
||||||
Otherwise they are ignored*/
|
Otherwise they are ignored*/
|
||||||
#define CPU_STATUS_NOTFLATDS (1 << 16)
|
#define CPU_STATUS_NOTFLATDS (1 << 8)
|
||||||
#define CPU_STATUS_NOTFLATSS (1 << 17)
|
#define CPU_STATUS_NOTFLATSS (1 << 9)
|
||||||
#define CPU_STATUS_MASK 0xffff0000
|
#define CPU_STATUS_MASK 0xff00
|
||||||
|
|
||||||
#define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];
|
#define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue