Added decoder length limitations to K6 timing model

This commit is contained in:
SarahW 2019-01-06 14:23:23 +00:00
commit 8ee9b07ab2
3 changed files with 75 additions and 10 deletions

View file

@ -823,21 +823,21 @@ uint64_t opcode_deps_df_mod3[8] =
uint64_t opcode_deps_81[8] = uint64_t opcode_deps_81[8] =
{ {
MODRM, MODRM, MODRM, MODRM, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632,
MODRM, MODRM, MODRM, MODRM MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632
}; };
uint64_t opcode_deps_81_mod3[8] = uint64_t opcode_deps_81_mod3[8] =
{ {
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632,
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | MODRM | HAS_IMM1632
}; };
uint64_t opcode_deps_8x[8] = uint64_t opcode_deps_8x[8] =
{ {
MODRM, MODRM, MODRM, MODRM, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8,
MODRM, MODRM, MODRM, MODRM MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8
}; };
uint64_t opcode_deps_8x_mod3[8] = uint64_t opcode_deps_8x_mod3[8] =
{ {
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8,
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | MODRM | HAS_IMM8
}; };

View file

@ -72,6 +72,9 @@
#define FPU_FXCH (1ull << 33) #define FPU_FXCH (1ull << 33)
#define HAS_IMM8 (1ull << 34)
#define HAS_IMM1632 (1ull << 35)
#define REGMASK_IMPL_ESP (1 << 8) #define REGMASK_IMPL_ESP (1 << 8)
#define REGMASK_SHIFTPACK (1 << 9) #define REGMASK_SHIFTPACK (1 << 9)

View file

@ -1723,6 +1723,7 @@ static const risc86_instruction_t *opcode_timings_df_mod3[8] =
static uint8_t last_prefix; static uint8_t last_prefix;
static int prefixes;
static int decode_timestamp; static int decode_timestamp;
static int last_complete_timestamp; static int last_complete_timestamp;
@ -1899,12 +1900,64 @@ void decode_flush()
decode_buffer.nr_uops = 0; decode_buffer.nr_uops = 0;
} }
/*The instruction is only of interest here if it's longer than 7 bytes, as that's the
limit on K6 short decoding*/
static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32)
{
int len = prefixes + 1; /*Opcode*/
if (deps & MODRM)
{
len++; /*ModR/M*/
if (deps & HAS_IMM8)
len++;
if (deps & HAS_IMM1632)
len += (op_32 & 0x100) ? 4 : 2;
if (op_32 & 0x200)
{
if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0)
{
/* Has SIB*/
len++;
if ((fetchdat & 0xc0) == 0x40)
len++;
else if ((fetchdat & 0xc0) == 0x80)
len += 4;
else if ((fetchdat & 0x700) == 0x500)
len += 4;
}
else
{
if ((fetchdat & 0xc0) == 0x40)
len++;
else if ((fetchdat & 0xc0) == 0x80)
len += 4;
else if ((fetchdat & 0xc7) == 0x05)
len += 4;
}
}
else
{
if ((fetchdat & 0xc0) == 0x40)
len++;
else if ((fetchdat & 0xc0) == 0x80)
len += 2;
else if ((fetchdat & 0xc7) == 0x06)
len += 2;
}
}
return len;
}
static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8)
{ {
uint32_t regmask_required; uint32_t regmask_required;
uint32_t regmask_modified; uint32_t regmask_modified;
int c, d; int c, d;
int earliest_start = 0; int earliest_start = 0;
decode_type_t decode_type = ins->decode_type;
int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32);
/*Generate input register mask, and determine the earliest time this /*Generate input register mask, and determine the earliest time this
instruction can start. This is not accurate, as this is calculated per instruction can start. This is not accurate, as this is calculated per
@ -1931,7 +1984,14 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u
earliest_start = fpu_st_timestamp[reg]; earliest_start = fpu_st_timestamp[reg];
} }
switch (ins->decode_type) /*Short decoders are limited to 7 bytes*/
if (decode_type == DECODE_SHORT && instr_length > 7)
decode_type = DECODE_LONG;
/*Long decoder is limited to 11 bytes*/
else if (instr_length > 11)
decode_type = DECODE_VECTOR;
switch (decode_type)
{ {
case DECODE_SHORT: case DECODE_SHORT:
if (decode_buffer.nr_uops) if (decode_buffer.nr_uops)
@ -2051,7 +2111,7 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u
void codegen_timing_k6_block_start() void codegen_timing_k6_block_start()
{ {
int c; int c;
for (c = 0; c < nr_units; c++) for (c = 0; c < nr_units; c++)
units[c].first_available_cycle = 0; units[c].first_available_cycle = 0;
@ -2085,6 +2145,7 @@ void codegen_timing_k6_start()
nr_units = NR_K6_2_UNITS; nr_units = NR_K6_2_UNITS;
} }
last_prefix = 0; last_prefix = 0;
prefixes = 0;
} }
void codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) void codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat)
@ -2093,6 +2154,7 @@ void codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat)
decode_timestamp++; decode_timestamp++;
last_prefix = prefix; last_prefix = prefix;
prefixes++;
} }
void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc)