Ensure that taken jump/branch instructions do not count as 0 cycles. Fixes Windows 95 hang with K6.

This commit is contained in:
SarahW 2019-01-06 13:46:17 +00:00
commit 3c7d1b1204
8 changed files with 61 additions and 6 deletions

View file

@ -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)
{

View file

@ -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;

View file

@ -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
};

View file

@ -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
};

View file

@ -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
};

View file

@ -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
};

View file

@ -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
};

View file

@ -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
};