Ensure that taken jump/branch instructions do not count as 0 cycles. Fixes Windows 95 hang with K6.
This commit is contained in:
parent
1953f4afb9
commit
3c7d1b1204
8 changed files with 61 additions and 6 deletions
|
|
@ -21,6 +21,7 @@ void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat);
|
|||
void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
void (*codegen_timing_block_start)();
|
||||
void (*codegen_timing_block_end)();
|
||||
int (*codegen_timing_jump_cycles)();
|
||||
|
||||
void codegen_timing_set(codegen_timing_t *timing)
|
||||
{
|
||||
|
|
@ -29,6 +30,7 @@ void codegen_timing_set(codegen_timing_t *timing)
|
|||
codegen_timing_opcode = timing->opcode;
|
||||
codegen_timing_block_start = timing->block_start;
|
||||
codegen_timing_block_end = timing->block_end;
|
||||
codegen_timing_jump_cycles = timing->jump_cycles;
|
||||
}
|
||||
|
||||
int codegen_in_recompile;
|
||||
|
|
@ -508,7 +510,20 @@ generate_call:
|
|||
(opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 ||
|
||||
(opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) ||
|
||||
(op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80)))
|
||||
{
|
||||
/*On some CPUs (eg K6), a jump/branch instruction may be able to pair with
|
||||
subsequent instructions, so no cycles may have been deducted for it yet.
|
||||
To prevent having zero cycle blocks (eg with a jump instruction pointing
|
||||
to itself), apply the cycles that would be taken if this jump is taken,
|
||||
then reverse it for subsequent instructions if the jump is not taken*/
|
||||
int jump_cycles = codegen_timing_jump_cycles();
|
||||
|
||||
if (jump_cycles)
|
||||
codegen_accumulate(ACCREG_cycles, -jump_cycles);
|
||||
codegen_accumulate_flush(ir);
|
||||
if (jump_cycles)
|
||||
codegen_accumulate(ACCREG_cycles, jump_cycles);
|
||||
}
|
||||
|
||||
if (op_table == x86_dynarec_opcodes_0f && opcode == 0x0f)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -320,6 +320,7 @@ extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat);
|
|||
extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
extern void (*codegen_timing_block_start)();
|
||||
extern void (*codegen_timing_block_end)();
|
||||
extern int (*codegen_timing_jump_cycles)();
|
||||
|
||||
typedef struct codegen_timing_t
|
||||
{
|
||||
|
|
@ -328,6 +329,7 @@ typedef struct codegen_timing_t
|
|||
void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
void (*block_start)();
|
||||
void (*block_end)();
|
||||
int (*jump_cycles)();
|
||||
} codegen_timing_t;
|
||||
|
||||
extern codegen_timing_t codegen_timing_pentium;
|
||||
|
|
|
|||
|
|
@ -422,11 +422,17 @@ void codegen_timing_486_block_end()
|
|||
{
|
||||
}
|
||||
|
||||
int codegen_timing_486_jump_cycles()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_486 =
|
||||
{
|
||||
codegen_timing_486_start,
|
||||
codegen_timing_486_prefix,
|
||||
codegen_timing_486_opcode,
|
||||
codegen_timing_486_block_start,
|
||||
codegen_timing_486_block_end
|
||||
codegen_timing_486_block_end,
|
||||
codegen_timing_486_jump_cycles
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1067,11 +1067,17 @@ void codegen_timing_686_block_end()
|
|||
}
|
||||
}
|
||||
|
||||
int codegen_timing_686_jump_cycles()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_686 =
|
||||
{
|
||||
codegen_timing_686_start,
|
||||
codegen_timing_686_prefix,
|
||||
codegen_timing_686_opcode,
|
||||
codegen_timing_686_block_start,
|
||||
codegen_timing_686_block_end
|
||||
codegen_timing_686_block_end,
|
||||
codegen_timing_686_jump_cycles
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2278,11 +2278,19 @@ void codegen_timing_k6_block_end()
|
|||
decode_flush();
|
||||
}
|
||||
|
||||
int codegen_timing_k6_jump_cycles()
|
||||
{
|
||||
if (decode_buffer.nr_uops)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_k6 =
|
||||
{
|
||||
codegen_timing_k6_start,
|
||||
codegen_timing_k6_prefix,
|
||||
codegen_timing_k6_opcode,
|
||||
codegen_timing_k6_block_start,
|
||||
codegen_timing_k6_block_end
|
||||
codegen_timing_k6_block_end,
|
||||
codegen_timing_k6_jump_cycles
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1328,11 +1328,17 @@ void codegen_timing_pentium_block_end()
|
|||
}
|
||||
}
|
||||
|
||||
int codegen_timing_pentium_jump_cycles()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_pentium =
|
||||
{
|
||||
codegen_timing_pentium_start,
|
||||
codegen_timing_pentium_prefix,
|
||||
codegen_timing_pentium_opcode,
|
||||
codegen_timing_pentium_block_start,
|
||||
codegen_timing_pentium_block_end
|
||||
codegen_timing_pentium_block_end,
|
||||
codegen_timing_pentium_jump_cycles
|
||||
};
|
||||
|
|
|
|||
|
|
@ -422,11 +422,17 @@ void codegen_timing_winchip_block_end()
|
|||
{
|
||||
}
|
||||
|
||||
int codegen_timing_winchip_jump_cycles()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_winchip =
|
||||
{
|
||||
codegen_timing_winchip_start,
|
||||
codegen_timing_winchip_prefix,
|
||||
codegen_timing_winchip_opcode,
|
||||
codegen_timing_winchip_block_start,
|
||||
codegen_timing_winchip_block_end
|
||||
codegen_timing_winchip_block_end,
|
||||
codegen_timing_winchip_jump_cycles
|
||||
};
|
||||
|
|
|
|||
|
|
@ -743,11 +743,17 @@ static void codegen_timing_winchip2_block_end()
|
|||
}
|
||||
}
|
||||
|
||||
int codegen_timing_winchip2_jump_cycles()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
codegen_timing_t codegen_timing_winchip2 =
|
||||
{
|
||||
codegen_timing_winchip2_start,
|
||||
codegen_timing_winchip2_prefix,
|
||||
codegen_timing_winchip2_opcode,
|
||||
codegen_timing_winchip2_block_start,
|
||||
codegen_timing_winchip2_block_end
|
||||
codegen_timing_winchip2_block_end,
|
||||
codegen_timing_winchip2_jump_cycles
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue