Added AGI stalls to 486 and later CPUs.
Reworked codegen timing a bit - split timing tables into CPU-specific and generic files. A few other timing tweaks.
This commit is contained in:
parent
a96e87527e
commit
a883399781
17 changed files with 1755 additions and 763 deletions
|
|
@ -5,6 +5,8 @@
|
|||
#include "x87.h"
|
||||
#include "mem.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
#define CYCLES(c) (int *)c
|
||||
#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8))
|
||||
|
|
@ -247,9 +249,22 @@ static int *opcode_timings_8x[8] =
|
|||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_8x_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_81[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_81_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
|
||||
static int timing_count;
|
||||
static uint8_t last_prefix;
|
||||
static uint32_t regmask_modified;
|
||||
|
||||
static inline int COUNT(int *c, int op_32)
|
||||
{
|
||||
|
|
@ -266,6 +281,7 @@ static inline int COUNT(int *c, int op_32)
|
|||
|
||||
void codegen_timing_winchip_block_start()
|
||||
{
|
||||
regmask_modified = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_start()
|
||||
|
|
@ -283,82 +299,123 @@ void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat)
|
|||
void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
int **timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
|
||||
switch (last_prefix)
|
||||
{
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
// pclog("timings 0f\n");
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
// pclog("timings d8\n");
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
// pclog("timings d9\n");
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
// pclog("timings da\n");
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
// pclog("timings db\n");
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
// pclog("timings dc\n");
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
// pclog("timings dd\n");
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
// pclog("timings de\n");
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
// pclog("timings df\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x81: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x;
|
||||
if (!mod3)
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x);
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x);
|
||||
break;
|
||||
|
||||
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
// pclog("timings c0\n");
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
// pclog("timings f6\n");
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
// pclog("timings f7\n");
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
// pclog("timings ff\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
// pclog("timings normal\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timing_count += COUNT(timings[opcode], op_32);
|
||||
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
|
||||
timing_count++; /*AGI stall*/
|
||||
codegen_block_cycles += timing_count;
|
||||
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_block_end()
|
||||
|
|
|
|||
Loading…
Reference in a new issue