x86-32 recompiler compiles FPU instructions using direct access to register stack when top-of-stack is static. Minor speedup.
This commit is contained in:
parent
1004d947d5
commit
75f9316c11
5 changed files with 1395 additions and 785 deletions
|
|
@ -1348,6 +1348,13 @@ 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)
|
||||||
|
{
|
||||||
|
/*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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid_block && block->was_recompiled)
|
if (valid_block && block->was_recompiled)
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,17 @@ typedef struct codeblock_t
|
||||||
uint64_t page_mask, page_mask2;
|
uint64_t page_mask, page_mask2;
|
||||||
|
|
||||||
int was_recompiled;
|
int was_recompiled;
|
||||||
|
uint32_t flags;
|
||||||
|
int TOP;
|
||||||
|
|
||||||
uint8_t data[2048];
|
uint8_t data[2048];
|
||||||
} codeblock_t;
|
} codeblock_t;
|
||||||
|
|
||||||
|
/*Code block uses FPU*/
|
||||||
|
#define CODEBLOCK_HAS_FPU 1
|
||||||
|
/*Code block is always entered with the same FPU top-of-stack*/
|
||||||
|
#define CODEBLOCK_STATIC_TOP 2
|
||||||
|
|
||||||
static inline codeblock_t *codeblock_tree_find(uint32_t phys)
|
static inline codeblock_t *codeblock_tree_find(uint32_t phys)
|
||||||
{
|
{
|
||||||
codeblock_t *block = pages[phys >> 12].head;
|
codeblock_t *block = pages[phys >> 12].head;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -281,6 +281,7 @@ void codegen_block_init(uint32_t phys_addr)
|
||||||
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;
|
||||||
|
block->flags = 0;
|
||||||
|
|
||||||
block->was_recompiled = 0;
|
block->was_recompiled = 0;
|
||||||
|
|
||||||
|
|
@ -1005,6 +1006,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xd9:
|
case 0xd9:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
|
||||||
|
|
@ -1013,6 +1015,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xda:
|
case 0xda:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
|
||||||
|
|
@ -1021,6 +1024,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xdb:
|
case 0xdb:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
|
||||||
|
|
@ -1029,6 +1033,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xdc:
|
case 0xdc:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
|
||||||
|
|
@ -1038,6 +1043,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xdd:
|
case 0xdd:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
|
||||||
|
|
@ -1046,6 +1052,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xde:
|
case 0xde:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
|
||||||
|
|
@ -1054,6 +1061,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xdf:
|
case 0xdf:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
|
||||||
|
|
@ -1062,6 +1070,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf0: /*LOCK*/
|
case 0xf0: /*LOCK*/
|
||||||
|
|
|
||||||
|
|
@ -281,6 +281,7 @@ void codegen_block_init(uint32_t phys_addr)
|
||||||
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;
|
||||||
|
block->flags = CODEBLOCK_STATIC_TOP;
|
||||||
|
|
||||||
block->was_recompiled = 0;
|
block->was_recompiled = 0;
|
||||||
|
|
||||||
|
|
@ -359,6 +360,7 @@ void codegen_block_start_recompile(codeblock_t *block)
|
||||||
|
|
||||||
_ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1;
|
_ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1;
|
||||||
|
|
||||||
|
block->TOP = cpu_state.TOP;
|
||||||
block->was_recompiled = 1;
|
block->was_recompiled = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -484,6 +486,9 @@ void codegen_block_end_recompile(codeblock_t *block)
|
||||||
codegen_block_generate_end_mask();
|
codegen_block_generate_end_mask();
|
||||||
add_to_block_list(block);
|
add_to_block_list(block);
|
||||||
// pclog("End block %i\n", block_num);
|
// pclog("End block %i\n", block_num);
|
||||||
|
|
||||||
|
if (!(block->flags & CODEBLOCK_HAS_FPU))
|
||||||
|
block->flags &= ~CODEBLOCK_STATIC_TOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void codegen_flush()
|
void codegen_flush()
|
||||||
|
|
@ -821,6 +826,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xd9:
|
case 0xd9:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
|
||||||
|
|
@ -829,6 +835,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xda:
|
case 0xda:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
|
||||||
|
|
@ -837,6 +844,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xdb:
|
case 0xdb:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
|
||||||
|
|
@ -845,6 +853,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xdc:
|
case 0xdc:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
|
||||||
|
|
@ -854,6 +863,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xdd:
|
case 0xdd:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
|
||||||
|
|
@ -862,6 +872,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xde:
|
case 0xde:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
|
||||||
|
|
@ -870,6 +881,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
case 0xdf:
|
case 0xdf:
|
||||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
|
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
|
||||||
|
|
@ -878,6 +890,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||||
over = 1;
|
over = 1;
|
||||||
pc_off = -1;
|
pc_off = -1;
|
||||||
test_modrm = 0;
|
test_modrm = 0;
|
||||||
|
block->flags |= CODEBLOCK_HAS_FPU;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf0: /*LOCK*/
|
case 0xf0: /*LOCK*/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue