add specialized instruction decoders (disabled for now)

This commit is contained in:
gbeauche 2003-11-01 17:07:17 +00:00
parent 066af7452a
commit d956d3c4ca
3 changed files with 120 additions and 13 deletions

View File

@ -342,7 +342,7 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
} }
#endif #endif
di->opcode = opcode; di->opcode = opcode;
di->execute = ii->execute; di->execute = ii->decode ? (this->*(ii->decode))(opcode) : ii->execute;
di++; di++;
#ifdef PPC_EXECUTE_DUMP_STATE #ifdef PPC_EXECUTE_DUMP_STATE
if (dump_state) { if (dump_state) {

View File

@ -141,11 +141,14 @@ protected:
// Callbacks associated with each instruction // Callbacks associated with each instruction
typedef void (powerpc_cpu::*execute_fn)(uint32 opcode); typedef void (powerpc_cpu::*execute_fn)(uint32 opcode);
// Specialzed instruction decoders type
typedef execute_fn (powerpc_cpu::*decode_fn)(uint32 opcode);
// Instruction information structure // Instruction information structure
struct instr_info_t { struct instr_info_t {
char name[8]; // Mnemonic char name[8]; // Mnemonic
execute_fn execute; // Semantic routine for this instruction execute_fn execute; // Semantic routine for this instruction
execute_fn decode; // Specialized instruction decoder decode_fn decode; // Specialized instruction decoder
uint16 format; // Instruction format (XO-form, D-form, etc.) uint16 format; // Instruction format (XO-form, D-form, etc.)
uint16 opcode; // Primary opcode uint16 opcode; // Primary opcode
uint16 xo; // Extended opcode uint16 xo; // Extended opcode
@ -346,6 +349,12 @@ private:
void execute_invalidate_cache_range(); void execute_invalidate_cache_range();
template< class RA, class RB > template< class RA, class RB >
void execute_dcbz(uint32 opcode); void execute_dcbz(uint32 opcode);
// Specialized instruction decoders
template< class RA, class RB, class RC, class CA >
execute_fn decode_addition(uint32 opcode);
template< class RA, class RS >
execute_fn decode_rlwinm(uint32 opcode);
}; };

View File

@ -26,6 +26,15 @@
#define DEBUG 0 #define DEBUG 0
#include "debug.h" #include "debug.h"
// Enable specialized instruction decoders?
#define SPECIALIZED_DECODERS 0
#if SPECIALIZED_DECODERS
#define SPD(X) X
#else
#define SPD(X) NULL
#endif
#define EXECUTE_0(HANDLER) \ #define EXECUTE_0(HANDLER) \
&powerpc_cpu::execute_##HANDLER &powerpc_cpu::execute_##HANDLER
@ -80,6 +89,18 @@
#define EXECUTE_FP_LOADSTORE(RA, RB, LD, DB, UP) \ #define EXECUTE_FP_LOADSTORE(RA, RB, LD, DB, UP) \
&powerpc_cpu::execute_fp_loadstore<operand_##RA, operand_##RB, LD, DB, UP> &powerpc_cpu::execute_fp_loadstore<operand_##RA, operand_##RB, LD, DB, UP>
#define _DECODE_ADDITION(RA, RB, RC, CA) \
powerpc_cpu::decode_addition<operand_##RA, operand_##RB, operand_##RC, CA>
#define DECODE_ADDITION(RA, RB, RC, CA) \
SPD(&_DECODE_ADDITION(RA, RB, RC, CA))
#define _DECODE_RLWINM(RA, RS) \
powerpc_cpu::decode_rlwinm<operand_##RA, operand_##RS>
#define DECODE_RLWINM(RA, RS) \
SPD(&_DECODE_RLWINM(RA, RS))
const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = { const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = {
{ "invalid", { "invalid",
EXECUTE_0(illegal), EXECUTE_0(illegal),
@ -88,17 +109,17 @@ const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = {
}, },
{ "add", { "add",
EXECUTE_ADDITION(RA, RB, NONE, CA_BIT_0, OE_BIT_G, RC_BIT_G), EXECUTE_ADDITION(RA, RB, NONE, CA_BIT_0, OE_BIT_G, RC_BIT_G),
NULL, DECODE_ADDITION(RA, RB, NONE, CA_BIT_0),
XO_form, 31, 266, CFLOW_NORMAL XO_form, 31, 266, CFLOW_NORMAL
}, },
{ "addc", { "addc",
EXECUTE_ADDITION(RA, RB, NONE, CA_BIT_1, OE_BIT_G, RC_BIT_G), EXECUTE_ADDITION(RA, RB, NONE, CA_BIT_1, OE_BIT_G, RC_BIT_G),
NULL, DECODE_ADDITION(RA, RB, NONE, CA_BIT_1),
XO_form, 31, 10, CFLOW_NORMAL XO_form, 31, 10, CFLOW_NORMAL
}, },
{ "adde", { "adde",
EXECUTE_ADDITION(RA, RB, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G), EXECUTE_ADDITION(RA, RB, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G),
NULL, DECODE_ADDITION(RA, RB, XER_CA, CA_BIT_1),
XO_form, 31, 138, CFLOW_NORMAL XO_form, 31, 138, CFLOW_NORMAL
}, },
{ "addi", { "addi",
@ -123,12 +144,12 @@ const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = {
}, },
{ "addme", { "addme",
EXECUTE_ADDITION(RA, MINUS_ONE, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G), EXECUTE_ADDITION(RA, MINUS_ONE, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G),
NULL, DECODE_ADDITION(RA, MINUS_ONE, XER_CA, CA_BIT_1),
XO_form, 31, 234, CFLOW_NORMAL XO_form, 31, 234, CFLOW_NORMAL
}, },
{ "addze", { "addze",
EXECUTE_ADDITION(RA, ZERO, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G), EXECUTE_ADDITION(RA, ZERO, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G),
NULL, DECODE_ADDITION(RA, ZERO, XER_CA, CA_BIT_1),
XO_form, 31, 202, CFLOW_NORMAL XO_form, 31, 202, CFLOW_NORMAL
}, },
{ "and", { "and",
@ -718,7 +739,7 @@ const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = {
}, },
{ "rlwinm", { "rlwinm",
EXECUTE_GENERIC_ARITH(ppc_rlwinm, RA, RS, SH, MASK, OE_BIT_0, RC_BIT_G), EXECUTE_GENERIC_ARITH(ppc_rlwinm, RA, RS, SH, MASK, OE_BIT_0, RC_BIT_G),
NULL, DECODE_RLWINM(RA, RS),
M_form, 21, 0, CFLOW_NORMAL M_form, 21, 0, CFLOW_NORMAL
}, },
{ "rlwnm", { "rlwnm",
@ -883,17 +904,17 @@ const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = {
}, },
{ "subf", { "subf",
EXECUTE_ADDITION(RA_compl, RB, ONE, CA_BIT_0, OE_BIT_G, RC_BIT_G), EXECUTE_ADDITION(RA_compl, RB, ONE, CA_BIT_0, OE_BIT_G, RC_BIT_G),
NULL, DECODE_ADDITION(RA_compl, RB, ONE, CA_BIT_0),
XO_form, 31, 40, CFLOW_NORMAL XO_form, 31, 40, CFLOW_NORMAL
}, },
{ "subfc", { "subfc",
EXECUTE_ADDITION(RA_compl, RB, ONE, CA_BIT_1, OE_BIT_G, RC_BIT_G), EXECUTE_ADDITION(RA_compl, RB, ONE, CA_BIT_1, OE_BIT_G, RC_BIT_G),
NULL, DECODE_ADDITION(RA_compl, RB, ONE, CA_BIT_1),
XO_form, 31, 8, CFLOW_NORMAL XO_form, 31, 8, CFLOW_NORMAL
}, },
{ "subfe", { "subfe",
EXECUTE_ADDITION(RA_compl, RB, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G), EXECUTE_ADDITION(RA_compl, RB, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G),
NULL, DECODE_ADDITION(RA_compl, RB, XER_CA, CA_BIT_1),
XO_form, 31, 136, CFLOW_NORMAL XO_form, 31, 136, CFLOW_NORMAL
}, },
{ "subfic", { "subfic",
@ -903,12 +924,12 @@ const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = {
}, },
{ "subfme", { "subfme",
EXECUTE_ADDITION(RA_compl, XER_CA, MINUS_ONE, CA_BIT_1, OE_BIT_G, RC_BIT_G), EXECUTE_ADDITION(RA_compl, XER_CA, MINUS_ONE, CA_BIT_1, OE_BIT_G, RC_BIT_G),
NULL, DECODE_ADDITION(RA_compl, XER_CA, MINUS_ONE, CA_BIT_1),
XO_form, 31, 232, CFLOW_NORMAL XO_form, 31, 232, CFLOW_NORMAL
}, },
{ "subfze", { "subfze",
EXECUTE_ADDITION(RA_compl, XER_CA, ZERO, CA_BIT_1, OE_BIT_G, RC_BIT_G), EXECUTE_ADDITION(RA_compl, XER_CA, ZERO, CA_BIT_1, OE_BIT_G, RC_BIT_G),
NULL, DECODE_ADDITION(RA_compl, XER_CA, ZERO, CA_BIT_1),
XO_form, 31, 200, CFLOW_NORMAL XO_form, 31, 200, CFLOW_NORMAL
}, },
{ "sync", { "sync",
@ -1013,3 +1034,80 @@ void powerpc_cpu::init_decoder_entry(const instr_info_t * ii)
break; break;
} }
} }
#if SPECIALIZED_DECODERS
#define DEFINE_TEMPLATE_1(T1) class T1
#define DEFINE_TEMPLATE_2(T1, T2) class T1, class T2
#define DEFINE_TEMPLATE_3(T1, T2, T3) class T1, class T2, class T3
#define DEFINE_TEMPLATE_4(T1, T2, T3, T4) class T1, class T2, class T3, class T4
#define DEFINE_TEMPLATE_5(T1, T2, T3, T4, T5) class T1, class T2, class T3, class T4, class T5
#ifndef GENEXEC
#define DEFINE_TEMPLATE(NAME, NARGS, ARGLIST) \
template< DEFINE_TEMPLATE_##NARGS ARGLIST > powerpc_cpu::execute_fn powerpc_cpu::decode_##NAME(uint32 opcode)
#endif
DEFINE_TEMPLATE(addition, 4, (RA, RB, RC, CA))
{
if (OE_field::test(opcode)) {
if (Rc_field::test(opcode))
return &powerpc_cpu::execute_addition< RA, RB, RC, CA, OE_BIT_1, RC_BIT_1 >;
else
return &powerpc_cpu::execute_addition< RA, RB, RC, CA, OE_BIT_1, RC_BIT_0 >;
}
else {
if (Rc_field::test(opcode))
return &powerpc_cpu::execute_addition< RA, RB, RC, CA, OE_BIT_0, RC_BIT_1 >;
else
return &powerpc_cpu::execute_addition< RA, RB, RC, CA, OE_BIT_0, RC_BIT_0 >;
}
abort();
return NULL;
}
#define IMPL_DECODE_ADDITION(RA, RB, RC, CA) \
template powerpc_cpu::execute_fn _DECODE_ADDITION(RA, RB, RC, CA)(uint32)
IMPL_DECODE_ADDITION(RA, RB, NONE, CA_BIT_0);
IMPL_DECODE_ADDITION(RA, RB, NONE, CA_BIT_1);
IMPL_DECODE_ADDITION(RA, RB, XER_CA, CA_BIT_1);
IMPL_DECODE_ADDITION(RA, MINUS_ONE, XER_CA, CA_BIT_1);
IMPL_DECODE_ADDITION(RA, ZERO, XER_CA, CA_BIT_1);
IMPL_DECODE_ADDITION(RA_compl, RB, ONE, CA_BIT_0);
IMPL_DECODE_ADDITION(RA_compl, RB, ONE, CA_BIT_1);
IMPL_DECODE_ADDITION(RA_compl, RB, XER_CA, CA_BIT_1);
IMPL_DECODE_ADDITION(RA_compl, XER_CA, MINUS_ONE, CA_BIT_1);
IMPL_DECODE_ADDITION(RA_compl, XER_CA, ZERO, CA_BIT_1);
DEFINE_TEMPLATE(rlwinm, 2, (RA, RS))
{
int SH = SH_field::extract(opcode);
int MB = MB_field::extract(opcode);
int ME = ME_field::extract(opcode);
int Rc = Rc_field::extract(opcode);
#define _(SH, MB, ME, Rc) (((SH) << 11) | ((MB) << 6) | ((ME) << 1) | (Rc))
switch (_(SH, MB, ME, Rc)) {
#define CASE_SHIFT_1(SH) \
case _((SH), 0, 31 - (SH), 0): return EXECUTE_7(generic_arith, op_shll, RA, RS, immediate_value<SH>, operand_NONE, OE_BIT_0, RC_BIT_0); \
case _((SH), 0, 31 - (SH), 1): return EXECUTE_7(generic_arith, op_shll, RA, RS, immediate_value<SH>, operand_NONE, OE_BIT_0, RC_BIT_1);
#define CASE_SHIFT_2(SH) CASE_SHIFT_1(SH); CASE_SHIFT_1(SH+1)
#define CASE_SHIFT_4(SH) CASE_SHIFT_2(SH); CASE_SHIFT_2(SH+2)
#define CASE_SHIFT_8(SH) CASE_SHIFT_4(SH); CASE_SHIFT_4(SH+4)
#define CASE_SHIFT_16(SH) CASE_SHIFT_8(SH); CASE_SHIFT_8(SH+8)
CASE_SHIFT_16(0);
CASE_SHIFT_16(16);
}
#undef _
if (Rc)
return EXECUTE_GENERIC_ARITH(ppc_rlwinm, RA, RS, SH, MASK, OE_BIT_0, RC_BIT_1);
else
return EXECUTE_GENERIC_ARITH(ppc_rlwinm, RA, RS, SH, MASK, OE_BIT_0, RC_BIT_0);
}
#define IMPL_DECODE_RLWINM(RA, RS) \
template powerpc_cpu::execute_fn _DECODE_RLWINM(RA, RS)(uint32)
IMPL_DECODE_RLWINM(RA, RS);
#endif /* SPECIALIZED_DECODERS */