Fixed P6 timings so they no longer fatal (and removed the 3DNow! stuff from them), and also fixed the Distributed DMA bug reported by TheCollector1995.
This commit is contained in:
@@ -1380,173 +1380,6 @@ static const risc86_instruction_t *opcode_timings_0f_mod3[256] =
|
|||||||
&mmx_op, &mmx_op, &mmx_op, INVALID,
|
&mmx_op, &mmx_op, &mmx_op, INVALID,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const risc86_instruction_t *opcode_timings_0f0f[256] =
|
|
||||||
{
|
|
||||||
/*00*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*10*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*20*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*30*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*40*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*50*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*60*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*70*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*80*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*90*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*a0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, &load_mmx_mul_op, &load_mmx_mul_op,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*b0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
&load_mmx_mul_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, &load_mmx_op,
|
|
||||||
|
|
||||||
/*c0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*d0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*e0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*f0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
};
|
|
||||||
static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] =
|
|
||||||
{
|
|
||||||
/*00*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*10*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*20*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*30*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*40*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*50*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*60*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*70*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*80*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*90*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*a0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, &mmx_mul_op, &mmx_mul_op,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*b0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
&mmx_mul_op, INVALID, &mmx_mul_op, &mmx_mul_op,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, &mmx_op,
|
|
||||||
|
|
||||||
/*c0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*d0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*e0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*f0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static const risc86_instruction_t *opcode_timings_shift[8] =
|
static const risc86_instruction_t *opcode_timings_shift[8] =
|
||||||
{
|
{
|
||||||
&complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op,
|
&complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op,
|
||||||
@@ -1876,11 +1709,11 @@ static int uop_run(const risc86_uop_t *uop, int decode_time)
|
|||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
int nr_uops;
|
int nr_uops;
|
||||||
const risc86_uop_t *uops[6];
|
const risc86_uop_t *uops[MAX_UOPS];
|
||||||
/*Earliest time a uop can start. If the timestamp is -1, then the uop is
|
/*Earliest time a uop can start. If the timestamp is -1, then the uop is
|
||||||
part of a dependency chain and the start time is the completion time of
|
part of a dependency chain and the start time is the completion time of
|
||||||
the previous uop*/
|
the previous uop*/
|
||||||
int earliest_start[6];
|
int earliest_start[MAX_UOPS];
|
||||||
} decode_buffer;
|
} decode_buffer;
|
||||||
|
|
||||||
#define NR_OPSEQS 3
|
#define NR_OPSEQS 3
|
||||||
@@ -1901,7 +1734,7 @@ static int last_uop_timestamp = 0;
|
|||||||
void decode_flush_p6()
|
void decode_flush_p6()
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int uop_timestamp = 0;
|
int start_timestamp, uop_timestamp = 0;
|
||||||
|
|
||||||
/*Decoded opseq can not be submitted if there are no free spaces in the
|
/*Decoded opseq can not be submitted if there are no free spaces in the
|
||||||
opseq buffer*/
|
opseq buffer*/
|
||||||
@@ -1915,9 +1748,6 @@ void decode_flush_p6()
|
|||||||
/*Submit uops to execution units, and determine the latest completion time*/
|
/*Submit uops to execution units, and determine the latest completion time*/
|
||||||
for (c = 0; c < (decode_buffer.nr_uops); c++)
|
for (c = 0; c < (decode_buffer.nr_uops); c++)
|
||||||
{
|
{
|
||||||
int start_timestamp;
|
|
||||||
|
|
||||||
|
|
||||||
start_timestamp = decode_buffer.earliest_start[c];
|
start_timestamp = decode_buffer.earliest_start[c];
|
||||||
|
|
||||||
last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp);
|
last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp);
|
||||||
@@ -2037,7 +1867,7 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u
|
|||||||
{
|
{
|
||||||
case DECODE_SIMPLE:
|
case DECODE_SIMPLE:
|
||||||
if (decode_buffer.nr_uops - d == 2)
|
if (decode_buffer.nr_uops - d == 2)
|
||||||
{
|
{
|
||||||
decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0];
|
decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0];
|
||||||
decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start;
|
decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start;
|
||||||
decode_buffer.nr_uops = 3;
|
decode_buffer.nr_uops = 3;
|
||||||
@@ -2084,10 +1914,10 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u
|
|||||||
decode_flush_p6(); /*The other two decoders are halted to preserve in-order issue*/
|
decode_flush_p6(); /*The other two decoders are halted to preserve in-order issue*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d)
|
if (d)
|
||||||
{
|
{
|
||||||
decode_buffer.nr_uops = d;
|
decode_buffer.nr_uops = d;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2188,59 +2018,8 @@ void codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint
|
|||||||
switch (last_prefix)
|
switch (last_prefix)
|
||||||
{
|
{
|
||||||
case 0x0f:
|
case 0x0f:
|
||||||
if (opcode == 0x0f)
|
ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||||
{
|
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||||
/*3DNow has the actual opcode after ModR/M, SIB and any offset*/
|
|
||||||
uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/
|
|
||||||
uint8_t modrm = fetchdat & 0xff;
|
|
||||||
uint8_t sib = (fetchdat >> 8) & 0xff;
|
|
||||||
|
|
||||||
if ((modrm & 0xc0) != 0xc0)
|
|
||||||
{
|
|
||||||
if (op_32 & 0x200)
|
|
||||||
{
|
|
||||||
if ((modrm & 7) == 4)
|
|
||||||
{
|
|
||||||
/* Has SIB*/
|
|
||||||
opcode_pc++;
|
|
||||||
if ((modrm & 0xc0) == 0x40)
|
|
||||||
opcode_pc++;
|
|
||||||
else if ((modrm & 0xc0) == 0x80)
|
|
||||||
opcode_pc += 4;
|
|
||||||
else if ((sib & 0x07) == 0x05)
|
|
||||||
opcode_pc += 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((modrm & 0xc0) == 0x40)
|
|
||||||
opcode_pc++;
|
|
||||||
else if ((modrm & 0xc0) == 0x80)
|
|
||||||
opcode_pc += 4;
|
|
||||||
else if ((modrm & 0xc7) == 0x05)
|
|
||||||
opcode_pc += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((modrm & 0xc0) == 0x40)
|
|
||||||
opcode_pc++;
|
|
||||||
else if ((modrm & 0xc0) == 0x80)
|
|
||||||
opcode_pc += 2;
|
|
||||||
else if ((modrm & 0xc7) == 0x06)
|
|
||||||
opcode_pc += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
opcode = fastreadb(cs + opcode_pc);
|
|
||||||
|
|
||||||
ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f;
|
|
||||||
deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
|
||||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xd8:
|
case 0xd8:
|
||||||
@@ -2365,4 +2144,4 @@ codegen_timing_t codegen_timing_p6 =
|
|||||||
codegen_timing_p6_block_start,
|
codegen_timing_p6_block_start,
|
||||||
codegen_timing_p6_block_end,
|
codegen_timing_p6_block_end,
|
||||||
codegen_timing_p6_jump_cycles
|
codegen_timing_p6_jump_cycles
|
||||||
};
|
};
|
||||||
|
@@ -1377,173 +1377,6 @@ static const risc86_instruction_t *opcode_timings_0f_mod3[256] =
|
|||||||
&mmx_op, &mmx_op, &mmx_op, INVALID,
|
&mmx_op, &mmx_op, &mmx_op, INVALID,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const risc86_instruction_t *opcode_timings_0f0f[256] =
|
|
||||||
{
|
|
||||||
/*00*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*10*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*20*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*30*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*40*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*50*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*60*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*70*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*80*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*90*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*a0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, &load_mmx_mul_op, &load_mmx_mul_op,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*b0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
&load_mmx_mul_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, &load_mmx_op,
|
|
||||||
|
|
||||||
/*c0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*d0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*e0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*f0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
};
|
|
||||||
static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] =
|
|
||||||
{
|
|
||||||
/*00*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*10*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*20*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*30*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*40*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*50*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*60*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*70*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*80*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*90*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*a0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, &mmx_mul_op, &mmx_mul_op,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*b0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
&mmx_mul_op, INVALID, &mmx_mul_op, &mmx_mul_op,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, &mmx_op,
|
|
||||||
|
|
||||||
/*c0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*d0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*e0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
/*f0*/ INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
INVALID, INVALID, INVALID, INVALID,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static const risc86_instruction_t *opcode_timings_shift[8] =
|
static const risc86_instruction_t *opcode_timings_shift[8] =
|
||||||
{
|
{
|
||||||
&complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op,
|
&complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op, &complex_alu_store_op,
|
||||||
@@ -1873,11 +1706,11 @@ static int uop_run(const risc86_uop_t *uop, int decode_time)
|
|||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
int nr_uops;
|
int nr_uops;
|
||||||
const risc86_uop_t *uops[6];
|
const risc86_uop_t *uops[MAX_UOPS];
|
||||||
/*Earliest time a uop can start. If the timestamp is -1, then the uop is
|
/*Earliest time a uop can start. If the timestamp is -1, then the uop is
|
||||||
part of a dependency chain and the start time is the completion time of
|
part of a dependency chain and the start time is the completion time of
|
||||||
the previous uop*/
|
the previous uop*/
|
||||||
int earliest_start[6];
|
int earliest_start[MAX_UOPS];
|
||||||
} decode_buffer;
|
} decode_buffer;
|
||||||
|
|
||||||
#define NR_OPSEQS 3
|
#define NR_OPSEQS 3
|
||||||
@@ -1898,7 +1731,7 @@ static int last_uop_timestamp = 0;
|
|||||||
void decode_flush_p6()
|
void decode_flush_p6()
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int uop_timestamp = 0;
|
int start_timestamp, uop_timestamp = 0;
|
||||||
|
|
||||||
/*Decoded opseq can not be submitted if there are no free spaces in the
|
/*Decoded opseq can not be submitted if there are no free spaces in the
|
||||||
opseq buffer*/
|
opseq buffer*/
|
||||||
@@ -1912,9 +1745,6 @@ void decode_flush_p6()
|
|||||||
/*Submit uops to execution units, and determine the latest completion time*/
|
/*Submit uops to execution units, and determine the latest completion time*/
|
||||||
for (c = 0; c < (decode_buffer.nr_uops); c++)
|
for (c = 0; c < (decode_buffer.nr_uops); c++)
|
||||||
{
|
{
|
||||||
int start_timestamp;
|
|
||||||
|
|
||||||
|
|
||||||
start_timestamp = decode_buffer.earliest_start[c];
|
start_timestamp = decode_buffer.earliest_start[c];
|
||||||
|
|
||||||
last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp);
|
last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp);
|
||||||
@@ -2034,7 +1864,7 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u
|
|||||||
{
|
{
|
||||||
case DECODE_SIMPLE:
|
case DECODE_SIMPLE:
|
||||||
if (decode_buffer.nr_uops - d == 2)
|
if (decode_buffer.nr_uops - d == 2)
|
||||||
{
|
{
|
||||||
decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0];
|
decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0];
|
||||||
decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start;
|
decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start;
|
||||||
decode_buffer.nr_uops = 3;
|
decode_buffer.nr_uops = 3;
|
||||||
@@ -2081,10 +1911,10 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u
|
|||||||
decode_flush_p6(); /*The other two decoders are halted to preserve in-order issue*/
|
decode_flush_p6(); /*The other two decoders are halted to preserve in-order issue*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d)
|
if (d)
|
||||||
{
|
{
|
||||||
decode_buffer.nr_uops = d;
|
decode_buffer.nr_uops = d;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2185,59 +2015,8 @@ void codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint
|
|||||||
switch (last_prefix)
|
switch (last_prefix)
|
||||||
{
|
{
|
||||||
case 0x0f:
|
case 0x0f:
|
||||||
if (opcode == 0x0f)
|
ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||||
{
|
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||||
/*3DNow has the actual opcode after ModR/M, SIB and any offset*/
|
|
||||||
uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/
|
|
||||||
uint8_t modrm = fetchdat & 0xff;
|
|
||||||
uint8_t sib = (fetchdat >> 8) & 0xff;
|
|
||||||
|
|
||||||
if ((modrm & 0xc0) != 0xc0)
|
|
||||||
{
|
|
||||||
if (op_32 & 0x200)
|
|
||||||
{
|
|
||||||
if ((modrm & 7) == 4)
|
|
||||||
{
|
|
||||||
/* Has SIB*/
|
|
||||||
opcode_pc++;
|
|
||||||
if ((modrm & 0xc0) == 0x40)
|
|
||||||
opcode_pc++;
|
|
||||||
else if ((modrm & 0xc0) == 0x80)
|
|
||||||
opcode_pc += 4;
|
|
||||||
else if ((sib & 0x07) == 0x05)
|
|
||||||
opcode_pc += 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((modrm & 0xc0) == 0x40)
|
|
||||||
opcode_pc++;
|
|
||||||
else if ((modrm & 0xc0) == 0x80)
|
|
||||||
opcode_pc += 4;
|
|
||||||
else if ((modrm & 0xc7) == 0x05)
|
|
||||||
opcode_pc += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((modrm & 0xc0) == 0x40)
|
|
||||||
opcode_pc++;
|
|
||||||
else if ((modrm & 0xc0) == 0x80)
|
|
||||||
opcode_pc += 2;
|
|
||||||
else if ((modrm & 0xc7) == 0x06)
|
|
||||||
opcode_pc += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
opcode = fastreadb(cs + opcode_pc);
|
|
||||||
|
|
||||||
ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f;
|
|
||||||
deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
|
||||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xd8:
|
case 0xd8:
|
||||||
@@ -2362,4 +2141,4 @@ codegen_timing_t codegen_timing_p6 =
|
|||||||
codegen_timing_p6_block_start,
|
codegen_timing_p6_block_start,
|
||||||
codegen_timing_p6_block_end,
|
codegen_timing_p6_block_end,
|
||||||
codegen_timing_p6_jump_cycles
|
codegen_timing_p6_jump_cycles
|
||||||
};
|
};
|
||||||
|
@@ -107,9 +107,9 @@ ddma_reg_write(uint16_t addr, uint8_t val, void *p)
|
|||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
if (ch >= 4)
|
if (ch >= 4)
|
||||||
outb(0x88 + page_regs[ch], val);
|
outb(0x88 + page_regs[ch & 3], val);
|
||||||
else
|
else
|
||||||
outb(0x80 + page_regs[ch], val);
|
outb(0x80 + page_regs[ch & 3], val);
|
||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
dma[ch].cb = (dma[ch].cb & 0xffff00) | val;
|
dma[ch].cb = (dma[ch].cb & 0xffff00) | val;
|
||||||
|
Reference in New Issue
Block a user