Don't unroll a loop if x87 top of stack is different at the start and end of the loop. Fixes Battlezone.
This commit is contained in:
parent
2b6b14f175
commit
83f2869123
3 changed files with 13 additions and 3 deletions
|
|
@ -22,9 +22,10 @@ static struct
|
||||||
x86seg *op_ea_seg;
|
x86seg *op_ea_seg;
|
||||||
uint32_t op_32;
|
uint32_t op_32;
|
||||||
int first_uop;
|
int first_uop;
|
||||||
|
int TOP;
|
||||||
} codegen_instructions[MAX_INSTRUCTION_COUNT];
|
} codegen_instructions[MAX_INSTRUCTION_COUNT];
|
||||||
|
|
||||||
int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction)
|
int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
|
@ -33,6 +34,7 @@ int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_inst
|
||||||
if (codegen_instructions[c].pc == pc)
|
if (codegen_instructions[c].pc == pc)
|
||||||
{
|
{
|
||||||
*first_instruction = c;
|
*first_instruction = c;
|
||||||
|
*TOP = codegen_instructions[c].TOP;
|
||||||
return codegen_instructions[c].first_uop;
|
return codegen_instructions[c].first_uop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -590,6 +592,7 @@ generate_call:
|
||||||
codegen_instructions[block->ins].op_ssegs = last_op_ssegs;
|
codegen_instructions[block->ins].op_ssegs = last_op_ssegs;
|
||||||
codegen_instructions[block->ins].op_ea_seg = last_op_ea_seg;
|
codegen_instructions[block->ins].op_ea_seg = last_op_ea_seg;
|
||||||
codegen_instructions[block->ins].op_32 = last_op_32;
|
codegen_instructions[block->ins].op_32 = last_op_32;
|
||||||
|
codegen_instructions[block->ins].TOP = cpu_state.TOP;
|
||||||
codegen_instructions[block->ins].first_uop = ir->wr_pos;
|
codegen_instructions[block->ins].first_uop = ir->wr_pos;
|
||||||
|
|
||||||
codegen_timing_opcode(opcode, fetchdat, op_32, op_pc);
|
codegen_timing_opcode(opcode, fetchdat, op_32, op_pc);
|
||||||
|
|
|
||||||
|
|
@ -404,7 +404,7 @@ extern int codegen_in_recompile;
|
||||||
|
|
||||||
void codegen_generate_reset();
|
void codegen_generate_reset();
|
||||||
|
|
||||||
int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction);
|
int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP);
|
||||||
void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction);
|
void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction);
|
||||||
|
|
||||||
#ifdef DEBUG_EXTRA
|
#ifdef DEBUG_EXTRA
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,10 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc,
|
||||||
int start;
|
int start;
|
||||||
int max_unroll;
|
int max_unroll;
|
||||||
int first_instruction;
|
int first_instruction;
|
||||||
|
int TOP = -1;
|
||||||
|
|
||||||
/*Check that dest instruction was actually compiled into block*/
|
/*Check that dest instruction was actually compiled into block*/
|
||||||
start = codegen_get_instruction_uop(block, dest_addr, &first_instruction);
|
start = codegen_get_instruction_uop(block, dest_addr, &first_instruction, &TOP);
|
||||||
|
|
||||||
/*Couldn't find any uOPs corresponding to the destination instruction*/
|
/*Couldn't find any uOPs corresponding to the destination instruction*/
|
||||||
if (start == -1)
|
if (start == -1)
|
||||||
|
|
@ -48,8 +49,14 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
start = ir->wr_pos;
|
start = ir->wr_pos;
|
||||||
|
TOP = cpu_state.TOP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TOP != cpu_state.TOP)
|
||||||
|
return 0;
|
||||||
|
|
||||||
max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos-start)+6);
|
max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos-start)+6);
|
||||||
if (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount))
|
if (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue