mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-27 02:49:42 +00:00
add specialized instruction decoders (disabled for now)
This commit is contained in:
parent
066af7452a
commit
d956d3c4ca
@ -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) {
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user