m680x0: Change method pointers to state ids in the big tables [O. Galibert]

This commit is contained in:
Olivier Galibert 2018-09-17 09:41:09 +02:00
parent c11d6a2093
commit e75036c2e1
4 changed files with 4009 additions and 2085 deletions

View File

@ -110,21 +110,22 @@ protected:
static constexpr int NUM_CPU_TYPES = 7;
typedef void (m68000_base_device::*opcode_handler_ptr)();
static opcode_handler_ptr m68ki_instruction_jump_table[NUM_CPU_TYPES][0x10000]; /* opcode handler jump table */
static u16 m68ki_instruction_state_table[NUM_CPU_TYPES][0x10000]; /* opcode handler state numbers */
static unsigned char m68ki_cycles[NUM_CPU_TYPES][0x10000]; /* Cycles used by CPU type */
/* This is used to generate the opcode handler jump table */
/* This is used to generate the opcode handler state table */
struct opcode_handler_struct
{
opcode_handler_ptr opcode_handler; /* handler function */
unsigned int mask; /* mask on opcode */
unsigned int match; /* what to match after masking */
unsigned int mask; /* mask on opcode */
unsigned char cycles[NUM_CPU_TYPES]; /* cycles each cpu type takes */
};
static const opcode_handler_struct m68k_opcode_handler_table[];
static const opcode_handler_ptr m68k_handler_table[];
static const opcode_handler_struct m68k_opcode_table[];
static const u16 m68k_state_illegal;
static void m68ki_set_one(unsigned short opcode, const opcode_handler_struct *s);
static void m68ki_set_one(unsigned short opcode, u16 state, const opcode_handler_struct &s);
static void m68ki_build_opcode_table(void);
void presave();
@ -247,7 +248,7 @@ protected:
uint32_t m_virq_state;
uint32_t m_nmi_pending;
void (m68000_base_device::**m_jump_table)();
const u16 *m_state_table;
const uint8_t* m_cyc_instruction;
const uint8_t* m_cyc_exception;

View File

@ -31,7 +31,7 @@ static const char copyright_notice[] =
// Generated data
m68000_base_device::opcode_handler_ptr m68000_base_device::m68ki_instruction_jump_table[NUM_CPU_TYPES][0x10000]; /* opcode handler jump table */
u16 m68000_base_device::m68ki_instruction_state_table[NUM_CPU_TYPES][0x10000]; /* opcode handler jump table */
unsigned char m68000_base_device::m68ki_cycles[NUM_CPU_TYPES][0x10000]; /* Cycles used by CPU type */
/* ======================================================================== */
@ -826,7 +826,8 @@ void m68000_base_device::execute_run()
m_run_mode = RUN_MODE_NORMAL;
/* Read an instruction and call its handler */
m_ir = m68ki_read_imm_16();
(this->*m_jump_table[m_ir])();
u16 state = m_state_table[m_ir];
(this->*m68k_handler_table[state])();
m_icount -= m_cyc_instruction[m_ir];
}
else
@ -848,7 +849,8 @@ void m68000_base_device::execute_run()
if (!m_mmu_tmp_buserror_occurred)
{
(this->*m_jump_table[m_ir])();
u16 state = m_state_table[m_ir];
(this->*m68k_handler_table[state])();
m_icount -= m_cyc_instruction[m_ir];
}
@ -1664,7 +1666,7 @@ void m68000_base_device::init_cpu_m68000(void)
init16(*m_program, *m_oprogram);
m_sr_mask = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[0];
m_state_table = m68ki_instruction_state_table[0];
m_cyc_instruction = m68ki_cycles[0];
m_cyc_exception = m68ki_exception_cycle_table[0];
m_cyc_bcc_notake_b = -2;
@ -1693,7 +1695,7 @@ void m68000_base_device::init_cpu_m68008(void)
init8(*m_program, *m_oprogram);
m_sr_mask = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[0];
m_state_table = m68ki_instruction_state_table[0];
m_cyc_instruction = m68ki_cycles[0];
m_cyc_exception = m68ki_exception_cycle_table[0];
m_cyc_bcc_notake_b = -2;
@ -1720,7 +1722,7 @@ void m68000_base_device::init_cpu_m68010(void)
init16(*m_program, *m_oprogram);
m_sr_mask = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[1];
m_state_table = m68ki_instruction_state_table[1];
m_cyc_instruction = m68ki_cycles[1];
m_cyc_exception = m68ki_exception_cycle_table[1];
m_cyc_bcc_notake_b = -4;
@ -1746,7 +1748,7 @@ void m68000_base_device::init_cpu_m68020(void)
init32(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[2];
m_state_table = m68ki_instruction_state_table[2];
m_cyc_instruction = m68ki_cycles[2];
m_cyc_exception = m68ki_exception_cycle_table[2];
m_cyc_bcc_notake_b = -2;
@ -1802,7 +1804,7 @@ void m68000_base_device::init_cpu_m68ec020(void)
init32(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[2];
m_state_table = m68ki_instruction_state_table[2];
m_cyc_instruction = m68ki_cycles[2];
m_cyc_exception = m68ki_exception_cycle_table[2];
m_cyc_bcc_notake_b = -2;
@ -1830,7 +1832,7 @@ void m68000_base_device::init_cpu_m68030(void)
init32mmu(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[3];
m_state_table = m68ki_instruction_state_table[3];
m_cyc_instruction = m68ki_cycles[3];
m_cyc_exception = m68ki_exception_cycle_table[3];
m_cyc_bcc_notake_b = -2;
@ -1859,7 +1861,7 @@ void m68000_base_device::init_cpu_m68ec030(void)
init32(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[3];
m_state_table = m68ki_instruction_state_table[3];
m_cyc_instruction = m68ki_cycles[3];
m_cyc_exception = m68ki_exception_cycle_table[3];
m_cyc_bcc_notake_b = -2;
@ -1888,7 +1890,7 @@ void m68000_base_device::init_cpu_m68040(void)
init32mmu(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[4];
m_state_table = m68ki_instruction_state_table[4];
m_cyc_instruction = m68ki_cycles[4];
m_cyc_exception = m68ki_exception_cycle_table[4];
m_cyc_bcc_notake_b = -2;
@ -1916,7 +1918,7 @@ void m68000_base_device::init_cpu_m68ec040(void)
init32(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[4];
m_state_table = m68ki_instruction_state_table[4];
m_cyc_instruction = m68ki_cycles[4];
m_cyc_exception = m68ki_exception_cycle_table[4];
m_cyc_bcc_notake_b = -2;
@ -1944,7 +1946,7 @@ void m68000_base_device::init_cpu_m68lc040(void)
init32mmu(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[4];
m_state_table = m68ki_instruction_state_table[4];
m_cyc_instruction = m68ki_cycles[4];
m_cyc_exception = m68ki_exception_cycle_table[4];
m_cyc_bcc_notake_b = -2;
@ -1999,7 +2001,7 @@ void m68000_base_device::init_cpu_fscpu32(void)
init32(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[5];
m_state_table = m68ki_instruction_state_table[5];
m_cyc_instruction = m68ki_cycles[5];
m_cyc_exception = m68ki_exception_cycle_table[5];
m_cyc_bcc_notake_b = -2;
@ -2026,7 +2028,7 @@ void m68000_base_device::init_cpu_coldfire(void)
init32(*m_program, *m_oprogram);
m_sr_mask = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
m_jump_table = m68ki_instruction_jump_table[6];
m_state_table = m68ki_instruction_state_table[6];
m_cyc_instruction = m68ki_cycles[6];
m_cyc_exception = m68ki_exception_cycle_table[6];
m_cyc_bcc_notake_b = -2;
@ -2678,106 +2680,35 @@ void mcf5206e_device::device_start()
init_cpu_coldfire();
}
void m68000_base_device::m68ki_set_one(unsigned short opcode, const opcode_handler_struct *s)
void m68000_base_device::m68ki_set_one(unsigned short opcode, u16 state, const opcode_handler_struct &s)
{
for(int i=0; i<NUM_CPU_TYPES; i++)
if(s->cycles[i] != 0xff) {
m68ki_cycles[i][opcode] = s->cycles[i];
m68ki_instruction_jump_table[i][opcode] = s->opcode_handler;
if(s.cycles[i] != 0xff) {
m68ki_cycles[i][opcode] = s.cycles[i];
m68ki_instruction_state_table[i][opcode] = state;
}
}
void m68000_base_device::m68ki_build_opcode_table()
{
const opcode_handler_struct *ostruct;
int i;
int j;
int k;
for(i = 0; i < 0x10000; i++)
for(int i = 0; i < 0x10000; i++)
{
/* default to illegal */
for(k=0;k<NUM_CPU_TYPES;k++)
for(int k=0;k<NUM_CPU_TYPES;k++)
{
m68ki_instruction_jump_table[k][i] = &m68000_base_device::m68k_op_illegal_0;
m68ki_instruction_state_table[k][i] = m68k_state_illegal;
m68ki_cycles[k][i] = 0;
}
}
ostruct = m68k_opcode_handler_table;
while(ostruct->mask != 0xff00)
for(u16 state = 0; m68k_opcode_table[state].mask; state++)
{
for(i = 0;i < 0x10000;i++)
{
if((i & ostruct->mask) == ostruct->match)
m68ki_set_one(i, ostruct);
}
ostruct++;
}
while(ostruct->mask == 0xff00)
{
for(i = 0;i <= 0xff;i++)
m68ki_set_one(ostruct->match | i, ostruct);
ostruct++;
}
while(ostruct->mask == 0xff20)
{
for(i = 0;i < 4;i++)
{
for(j = 0;j < 32;j++)
{
m68ki_set_one(ostruct->match | (i << 6) | j, ostruct);
}
}
ostruct++;
}
while(ostruct->mask == 0xf1f8)
{
for(i = 0;i < 8;i++)
{
for(j = 0;j < 8;j++)
m68ki_set_one(ostruct->match | (i << 9) | j, ostruct);
}
ostruct++;
}
while(ostruct->mask == 0xffd8)
{
for(i = 0;i < 2;i++)
{
for(j = 0;j < 8;j++)
{
m68ki_set_one(ostruct->match | (i << 5) | j, ostruct);
}
}
ostruct++;
}
while(ostruct->mask == 0xfff0)
{
for(i = 0;i <= 0x0f;i++)
m68ki_set_one(ostruct->match | i, ostruct);
ostruct++;
}
while(ostruct->mask == 0xf1ff)
{
for(i = 0;i <= 0x07;i++)
m68ki_set_one(ostruct->match | (i << 9), ostruct);
ostruct++;
}
while(ostruct->mask == 0xfff8)
{
for(i = 0;i <= 0x07;i++)
m68ki_set_one(ostruct->match | i, ostruct);
ostruct++;
}
while(ostruct->mask == 0xffff)
{
m68ki_set_one(ostruct->match, ostruct);
ostruct++;
}
// if we fell all the way through with a non-zero mask, the opcode table wasn't built properly
if (ostruct->mask != 0)
{
fatalerror("m68ki_build_opcode_table: unhandled opcode mask %x (match %x), m68k core will not function!\n", ostruct->mask, ostruct->match);
const auto &os = m68k_opcode_table[state];
u16 mask = os.mask;
u16 extraval = 0;
do {
m68ki_set_one(os.match | extraval, state, os);
extraval = ((extraval | mask) + 1) & ~mask;
} while(extraval);
}
}

View File

@ -267,18 +267,31 @@ class Info:
f.write("\n")
for h in self.opcode_handlers:
f.write('void m68000_base_device::%s()\n{\n%s}\n' % (h.function_name, h.body))
f.write("const m68000_base_device::opcode_handler_struct m68000_base_device::m68k_opcode_handler_table[] =\n{\n\n")
order = list(range(len(self.opcode_handlers)))
order.sort(key = lambda id: "%02d %04x %04x" % (self.opcode_handlers[id].bits, self.opcode_handlers[id].op_mask, self.opcode_handlers[id].op_value))
illegal_id = 0
nid = 0
f.write("const m68000_base_device::opcode_handler_ptr m68000_base_device::m68k_handler_table[] =\n{\n\n")
for id in order:
oh = self.opcode_handlers[id]
f.write("\t{&m68000_base_device::%s, 0x%04x, 0x%04x, {" % (oh.function_name, oh.op_mask, oh.op_value))
f.write("\t&m68000_base_device::%s,\n" % oh.function_name)
if oh.function_name == 'm68k_op_illegal_0':
illegal_id = nid
nid += 1
f.write("};\n\n")
f.write("const u16 m68000_base_device::m68k_state_illegal = %d;\n\n" % illegal_id)
f.write("const m68000_base_device::opcode_handler_struct m68000_base_device::m68k_opcode_table[] =\n{\n\n")
for id in order:
oh = self.opcode_handlers[id]
f.write("\t{ 0x%04x, 0x%04x, {" % (oh.op_value, oh.op_mask))
for i in range(0, CPU_COUNT):
if i != 0:
f.write(", ")
f.write("%3d" % (255 if oh.cycles[i] == None else oh.cycles[i]))
f.write("}},\n")
f.write("\t{nullptr, 0, 0, {0, 0, 0, 0, 0}}\n};\n")
f.write("\t{ 0, 0, {0, 0, 0, 0, 0}}\n};\n")
def main(argv):
if len(argv) != 4:

File diff suppressed because it is too large Load Diff