summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/rsp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/rsp')
-rw-r--r--src/emu/cpu/rsp/rspdrc.c33
-rw-r--r--src/emu/cpu/rsp/rspfe.c431
-rw-r--r--src/emu/cpu/rsp/rspfe.h40
3 files changed, 257 insertions, 247 deletions
diff --git a/src/emu/cpu/rsp/rspdrc.c b/src/emu/cpu/rsp/rspdrc.c
index 84a39f46b78..10a65bb74f5 100644
--- a/src/emu/cpu/rsp/rspdrc.c
+++ b/src/emu/cpu/rsp/rspdrc.c
@@ -106,7 +106,7 @@ struct _rspimp_state
/* core state */
drccache * cache; /* pointer to the DRC code cache */
drcuml_state * drcuml; /* DRC UML generator state */
- drcfe_state * drcfe; /* pointer to the DRC front-end state */
+ rsp_frontend * drcfe; /* pointer to the DRC front-end state */
UINT32 drcoptions; /* configurable DRC options */
/* internal stuff */
@@ -603,13 +603,6 @@ static void rspcom_init(rsp_state *rsp, legacy_cpu_device *device, device_irq_ca
static CPU_INIT( rsp )
{
- drcfe_config feconfig =
- {
- COMPILE_BACKWARDS_BYTES, /* code window start offset = startpc - window_start */
- COMPILE_FORWARDS_BYTES, /* code window end offset = startpc + window_end */
- COMPILE_MAX_SEQUENCE, /* maximum instructions to include in a sequence */
- rspfe_describe /* callback to describe a single instruction */
- };
rsp_state *rsp;
drccache *cache;
UINT32 flags = 0;
@@ -669,11 +662,7 @@ static CPU_INIT( rsp )
drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->numcycles, sizeof(rsp->impstate->numcycles), "numcycles");
/* initialize the front-end helper */
- if (SINGLE_INSTRUCTION_MODE)
- {
- feconfig.max_sequence = 1;
- }
- rsp->impstate->drcfe = drcfe_init(device, &feconfig, rsp);
+ rsp->impstate->drcfe = auto_alloc(device->machine, rsp_frontend(*rsp, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE));
/* compute the register parameters */
for (regnum = 0; regnum < 32; regnum++)
@@ -721,7 +710,7 @@ static CPU_EXIT( rsp )
rsp_state *rsp = get_safe_token(device);
/* clean up the DRC */
- drcfe_exit(rsp->impstate->drcfe);
+ auto_free(device->machine, rsp->impstate->drcfe);
drcuml_free(rsp->impstate->drcuml);
drccache_free(rsp->impstate->cache);
}
@@ -3479,7 +3468,7 @@ static void code_compile_block(rsp_state *rsp, offs_t pc)
g_profiler.start(PROFILER_DRC_COMPILE);
/* get a description of this sequence */
- desclist = drcfe_describe_code(rsp->impstate->drcfe, pc);
+ desclist = rsp->impstate->drcfe->describe_code(pc);
/* if we get an error back, flush the cache and try again */
if (setjmp(errorbuf) != 0)
@@ -3491,7 +3480,7 @@ static void code_compile_block(rsp_state *rsp, offs_t pc)
block = drcuml_block_begin(drcuml, 8192, &errorbuf);
/* loop until we get through all instruction sequences */
- for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next)
+ for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next())
{
const opcode_desc *curdesc;
UINT32 nextpc;
@@ -3501,7 +3490,7 @@ static void code_compile_block(rsp_state *rsp, offs_t pc)
UML_COMMENT(block, "-------------------------"); // comment
/* determine the last instruction in this sequence */
- for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next)
+ for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next())
if (seqlast->flags & OPFLAG_END_SEQUENCE)
break;
assert(seqlast != NULL);
@@ -3536,7 +3525,7 @@ static void code_compile_block(rsp_state *rsp, offs_t pc)
UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc
/* iterate over instructions in the sequence and compile them */
- for (curdesc = seqhead; curdesc != seqlast->next; curdesc = curdesc->next)
+ for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next())
generate_sequence_instruction(rsp, block, &compiler, curdesc);
/* if we need to return to the start, do it */
@@ -3551,7 +3540,7 @@ static void code_compile_block(rsp_state *rsp, offs_t pc)
generate_update_cycles(rsp, block, &compiler, IMM(nextpc), TRUE); // <subtract cycles>
/* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */
- if (seqlast->next == NULL || seqlast->next->pc != nextpc)
+ if (seqlast->next() == NULL || seqlast->next()->pc != nextpc)
UML_HASHJMP(block, IMM(0), IMM(nextpc), rsp->impstate->nocode); // hashjmp <mode>,nextpc,nocode
}
@@ -3800,7 +3789,7 @@ static void generate_checksum_block(rsp_state *rsp, drcuml_block *block, compile
UML_COMMENT(block, "[Validation for %08X]", seqhead->pc | 0x1000); // comment
}
/* loose verify or single instruction: just compare and fail */
- if (!(rsp->impstate->drcoptions & RSPDRC_STRICT_VERIFY) || seqhead->next == NULL)
+ if (!(rsp->impstate->drcoptions & RSPDRC_STRICT_VERIFY) || seqhead->next() == NULL)
{
if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
{
@@ -3818,7 +3807,7 @@ static void generate_checksum_block(rsp_state *rsp, drcuml_block *block, compile
void *base = rsp->direct->read_decrypted_ptr(seqhead->physpc | 0x1000);
UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,0,dword
sum += seqhead->opptr.l[0];
- for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
+ for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
{
base = rsp->direct->read_decrypted_ptr(curdesc->physpc | 0x1000);
@@ -3910,7 +3899,7 @@ static void generate_delay_slot_and_branch(rsp_state *rsp, drcuml_block *block,
/* compile the delay slot using temporary compiler state */
assert(desc->delay != NULL);
- generate_sequence_instruction(rsp, block, &compiler_temp, desc->delay); // <next instruction>
+ generate_sequence_instruction(rsp, block, &compiler_temp, desc->delay.first()); // <next instruction>
/* update the cycles and jump through the hash table to the target */
if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
diff --git a/src/emu/cpu/rsp/rspfe.c b/src/emu/cpu/rsp/rspfe.c
index 9fcad914577..225d1d551ff 100644
--- a/src/emu/cpu/rsp/rspfe.c
+++ b/src/emu/cpu/rsp/rspfe.c
@@ -1,4 +1,4 @@
- /***************************************************************************
+/***************************************************************************
rspfe.c
@@ -14,294 +14,291 @@
#include "rspfe.h"
#include "rsp.h"
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
+//**************************************************************************
+// RSP FRONTEND
+//**************************************************************************
-static int describe_instruction_special(rsp_state *rsp, UINT32 op, opcode_desc *desc);
-static int describe_instruction_regimm(rsp_state *rsp, UINT32 op, opcode_desc *desc);
-static int describe_instruction_cop0(rsp_state *rsp, UINT32 op, opcode_desc *desc);
-static int describe_instruction_cop2(rsp_state *rsp, UINT32 op, opcode_desc *desc);
+//-------------------------------------------------
+// rsp_frontend - constructor
+//-------------------------------------------------
+
+rsp_frontend::rsp_frontend(rsp_state &state, UINT32 window_start, UINT32 window_end, UINT32 max_sequence)
+ : drc_frontend(*state.device, window_start, window_end, max_sequence),
+ m_context(state)
+{
+}
-/***************************************************************************
- INSTRUCTION PARSERS
-***************************************************************************/
-/*-------------------------------------------------
- describe_instruction - build a description
- of a single instruction
--------------------------------------------------*/
+//-------------------------------------------------
+// describe - build a description of a single
+// instruction
+//-------------------------------------------------
-int rspfe_describe(void *param, opcode_desc *desc, const opcode_desc *prev)
+bool rsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
- rsp_state *rsp = (rsp_state *)param;
UINT32 op, opswitch;
- /* fetch the opcode */
- op = desc->opptr.l[0] = rsp->direct->read_decrypted_dword(desc->physpc | 0x1000);
+ // fetch the opcode
+ op = desc.opptr.l[0] = m_context.direct->read_decrypted_dword(desc.physpc | 0x1000);
- /* all instructions are 4 bytes and default to a single cycle each */
- desc->length = 4;
- desc->cycles = 1;
+ // all instructions are 4 bytes and default to a single cycle each
+ desc.length = 4;
+ desc.cycles = 1;
- /* parse the instruction */
+ // parse the instruction
opswitch = op >> 26;
switch (opswitch)
{
- case 0x00: /* SPECIAL */
- return describe_instruction_special(rsp, op, desc);
+ case 0x00: // SPECIAL
+ return describe_special(op, desc);
- case 0x01: /* REGIMM */
- return describe_instruction_regimm(rsp, op, desc);
+ case 0x01: // REGIMM
+ return describe_regimm(op, desc);
- case 0x10: /* COP0 */
- return describe_instruction_cop0(rsp, op, desc);
+ case 0x10: // COP0
+ return describe_cop0(op, desc);
- case 0x12: /* COP2 */
- return describe_instruction_cop2(rsp, op, desc);
+ case 0x12: // COP2
+ return describe_cop2(op, desc);
- case 0x02: /* J */
- desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
- desc->targetpc = ((LIMMVAL << 2) & 0x00000fff) | 0x1000;
- desc->delayslots = 1;
- return TRUE;
+ case 0x02: // J
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = ((LIMMVAL << 2) & 0x00000fff) | 0x1000;
+ desc.delayslots = 1;
+ return true;
- case 0x03: /* JAL */
- desc->regout[0] |= REGFLAG_R(31);
- desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
- desc->targetpc = ((LIMMVAL << 2) & 0x00000fff) | 0x1000;
- desc->delayslots = 1;
- return TRUE;
+ case 0x03: // JAL
+ desc.regout[0] |= REGFLAG_R(31);
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = ((LIMMVAL << 2) & 0x00000fff) | 0x1000;
+ desc.delayslots = 1;
+ return true;
- case 0x04: /* BEQ */
- case 0x05: /* BNE */
+ case 0x04: // BEQ
+ case 0x05: // BNE
if ((opswitch == 0x04 || opswitch == 0x14) && RSREG == RTREG)
- desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
else
{
- desc->regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc->flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
}
- desc->targetpc = ((desc->pc + 4 + (SIMMVAL << 2)) & 0x00000fff) | 0x1000;
- desc->delayslots = 1;
- desc->skipslots = (opswitch & 0x10) ? 1 : 0;
- return TRUE;
+ desc.targetpc = ((desc.pc + 4 + (SIMMVAL << 2)) & 0x00000fff) | 0x1000;
+ desc.delayslots = 1;
+ desc.skipslots = (opswitch & 0x10) ? 1 : 0;
+ return true;
- case 0x06: /* BLEZ */
- case 0x07: /* BGTZ */
+ case 0x06: // BLEZ
+ case 0x07: // BGTZ
if ((opswitch == 0x06 || opswitch == 0x16) && RSREG == 0)
- desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
else
{
- desc->regin[0] |= REGFLAG_R(RSREG);
- desc->flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.regin[0] |= REGFLAG_R(RSREG);
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
}
- desc->targetpc = ((desc->pc + 4 + (SIMMVAL << 2)) & 0x00000fff) | 0x1000;
- desc->delayslots = 1;
- desc->skipslots = (opswitch & 0x10) ? 1 : 0;
- return TRUE;
-
- case 0x08: /* ADDI */
- desc->regin[0] |= REGFLAG_R(RSREG);
- desc->regout[0] |= REGFLAG_R(RTREG);
- return TRUE;
-
- case 0x09: /* ADDIU */
- case 0x0a: /* SLTI */
- case 0x0b: /* SLTIU */
- case 0x0c: /* ANDI */
- case 0x0d: /* ORI */
- case 0x0e: /* XORI */
- desc->regin[0] |= REGFLAG_R(RSREG);
- desc->regout[0] |= REGFLAG_R(RTREG);
- return TRUE;
-
- case 0x0f: /* LUI */
- desc->regout[0] |= REGFLAG_R(RTREG);
- return TRUE;
-
- case 0x20: /* LB */
- case 0x21: /* LH */
- case 0x23: /* LW */
- case 0x24: /* LBU */
- case 0x25: /* LHU */
- case 0x27: /* LWU */
- desc->regin[0] |= REGFLAG_R(RSREG);
- desc->regout[0] |= REGFLAG_R(RTREG);
- desc->flags |= OPFLAG_READS_MEMORY;
- return TRUE;
-
- case 0x28: /* SB */
- case 0x29: /* SH */
- case 0x2b: /* SW */
- desc->regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc->flags |= OPFLAG_WRITES_MEMORY;
- return TRUE;
-
- case 0x32: /* LWC2 */
- desc->regin[0] |= REGFLAG_R(RSREG);
- desc->flags |= OPFLAG_READS_MEMORY;
- return TRUE;
-
- case 0x3a: /* SWC2 */
- desc->regin[0] |= REGFLAG_R(RSREG);
- desc->flags |= OPFLAG_WRITES_MEMORY;
- return TRUE;
+ desc.targetpc = ((desc.pc + 4 + (SIMMVAL << 2)) & 0x00000fff) | 0x1000;
+ desc.delayslots = 1;
+ desc.skipslots = (opswitch & 0x10) ? 1 : 0;
+ return true;
+
+ case 0x08: // ADDI
+ desc.regin[0] |= REGFLAG_R(RSREG);
+ desc.regout[0] |= REGFLAG_R(RTREG);
+ return true;
+
+ case 0x09: // ADDIU
+ case 0x0a: // SLTI
+ case 0x0b: // SLTIU
+ case 0x0c: // ANDI
+ case 0x0d: // ORI
+ case 0x0e: // XORI
+ desc.regin[0] |= REGFLAG_R(RSREG);
+ desc.regout[0] |= REGFLAG_R(RTREG);
+ return true;
+
+ case 0x0f: // LUI
+ desc.regout[0] |= REGFLAG_R(RTREG);
+ return true;
+
+ case 0x20: // LB
+ case 0x21: // LH
+ case 0x23: // LW
+ case 0x24: // LBU
+ case 0x25: // LHU
+ case 0x27: // LWU
+ desc.regin[0] |= REGFLAG_R(RSREG);
+ desc.regout[0] |= REGFLAG_R(RTREG);
+ desc.flags |= OPFLAG_READS_MEMORY;
+ return true;
+
+ case 0x28: // SB
+ case 0x29: // SH
+ case 0x2b: // SW
+ desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ return true;
+
+ case 0x32: // LWC2
+ desc.regin[0] |= REGFLAG_R(RSREG);
+ desc.flags |= OPFLAG_READS_MEMORY;
+ return true;
+
+ case 0x3a: // SWC2
+ desc.regin[0] |= REGFLAG_R(RSREG);
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ return true;
}
- return FALSE;
+ return false;
}
-/*-------------------------------------------------
- describe_instruction_special - build a
- description of a single instruction in the
- 'special' group
--------------------------------------------------*/
+//-------------------------------------------------
+// describe_special - build a description of a
+// single instruction in the 'special' group
+//-------------------------------------------------
-static int describe_instruction_special(rsp_state *rsp, UINT32 op, opcode_desc *desc)
+bool rsp_frontend::describe_special(UINT32 op, opcode_desc &desc)
{
switch (op & 63)
{
- case 0x00: /* SLL */
- case 0x02: /* SRL */
- case 0x03: /* SRA */
- desc->regin[0] |= REGFLAG_R(RTREG);
- desc->regout[0] |= REGFLAG_R(RDREG);
- return TRUE;
-
- case 0x04: /* SLLV */
- case 0x06: /* SRLV */
- case 0x07: /* SRAV */
- case 0x21: /* ADDU */
- case 0x23: /* SUBU */
- case 0x24: /* AND */
- case 0x25: /* OR */
- case 0x26: /* XOR */
- case 0x27: /* NOR */
- case 0x2a: /* SLT */
- case 0x2b: /* SLTU */
- desc->regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc->regout[0] |= REGFLAG_R(RDREG);
- return TRUE;
-
- case 0x20: /* ADD */
- case 0x22: /* SUB */
- desc->regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc->regout[0] |= REGFLAG_R(RDREG);
- return TRUE;
-
- case 0x08: /* JR */
- desc->regin[0] |= REGFLAG_R(RSREG);
- desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
- desc->targetpc = BRANCH_TARGET_DYNAMIC;
- desc->delayslots = 1;
- return TRUE;
-
- case 0x09: /* JALR */
- desc->regin[0] |= REGFLAG_R(RSREG);
- desc->regout[0] |= REGFLAG_R(RDREG);
- desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
- desc->targetpc = BRANCH_TARGET_DYNAMIC;
- desc->delayslots = 1;
- return TRUE;
-
- case 0x0d: /* BREAK */
- desc->flags |= OPFLAG_END_SEQUENCE;
- desc->targetpc = BRANCH_TARGET_DYNAMIC;
- return TRUE;
+ case 0x00: // SLL
+ case 0x02: // SRL
+ case 0x03: // SRA
+ desc.regin[0] |= REGFLAG_R(RTREG);
+ desc.regout[0] |= REGFLAG_R(RDREG);
+ return true;
+
+ case 0x04: // SLLV
+ case 0x06: // SRLV
+ case 0x07: // SRAV
+ case 0x21: // ADDU
+ case 0x23: // SUBU
+ case 0x24: // AND
+ case 0x25: // OR
+ case 0x26: // XOR
+ case 0x27: // NOR
+ case 0x2a: // SLT
+ case 0x2b: // SLTU
+ desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
+ desc.regout[0] |= REGFLAG_R(RDREG);
+ return true;
+
+ case 0x20: // ADD
+ case 0x22: // SUB
+ desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
+ desc.regout[0] |= REGFLAG_R(RDREG);
+ return true;
+
+ case 0x08: // JR
+ desc.regin[0] |= REGFLAG_R(RSREG);
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = BRANCH_TARGET_DYNAMIC;
+ desc.delayslots = 1;
+ return true;
+
+ case 0x09: // JALR
+ desc.regin[0] |= REGFLAG_R(RSREG);
+ desc.regout[0] |= REGFLAG_R(RDREG);
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = BRANCH_TARGET_DYNAMIC;
+ desc.delayslots = 1;
+ return true;
+
+ case 0x0d: // BREAK
+ desc.flags |= OPFLAG_END_SEQUENCE;
+ desc.targetpc = BRANCH_TARGET_DYNAMIC;
+ return true;
}
- return FALSE;
+ return false;
}
-/*-------------------------------------------------
- describe_instruction_regimm - build a
- description of a single instruction in the
- 'regimm' group
--------------------------------------------------*/
+//-------------------------------------------------
+// describe_regimm - build a description of a
+// single instruction in the 'regimm' group
+//-------------------------------------------------
-static int describe_instruction_regimm(rsp_state *rsp, UINT32 op, opcode_desc *desc)
+bool rsp_frontend::describe_regimm(UINT32 op, opcode_desc &desc)
{
switch (RTREG)
{
- case 0x00: /* BLTZ */
- case 0x01: /* BGEZ */
+ case 0x00: // BLTZ
+ case 0x01: // BGEZ
if (RTREG == 0x01 && RSREG == 0)
- desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
else
{
- desc->regin[0] |= REGFLAG_R(RSREG);
- desc->flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.regin[0] |= REGFLAG_R(RSREG);
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
}
- desc->targetpc = ((desc->pc + 4 + (SIMMVAL << 2)) & 0x00000fff) | 0x1000;
- desc->delayslots = 1;
- desc->skipslots = (RTREG & 0x02) ? 1 : 0;
- return TRUE;
+ desc.targetpc = ((desc.pc + 4 + (SIMMVAL << 2)) & 0x00000fff) | 0x1000;
+ desc.delayslots = 1;
+ desc.skipslots = (RTREG & 0x02) ? 1 : 0;
+ return true;
- case 0x10: /* BLTZAL */
- case 0x11: /* BGEZAL */
+ case 0x10: // BLTZAL
+ case 0x11: // BGEZAL
if (RTREG == 0x11 && RSREG == 0)
- desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
else
{
- desc->regin[0] |= REGFLAG_R(RSREG);
- desc->flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.regin[0] |= REGFLAG_R(RSREG);
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
}
- desc->regout[0] |= REGFLAG_R(31);
- desc->targetpc = ((desc->pc + 4 + (SIMMVAL << 2)) & 0x00000fff) | 0x1000;
- desc->delayslots = 1;
- desc->skipslots = (RTREG & 0x02) ? 1 : 0;
- return TRUE;
+ desc.regout[0] |= REGFLAG_R(31);
+ desc.targetpc = ((desc.pc + 4 + (SIMMVAL << 2)) & 0x00000fff) | 0x1000;
+ desc.delayslots = 1;
+ desc.skipslots = (RTREG & 0x02) ? 1 : 0;
+ return true;
}
- return FALSE;
+ return false;
}
-/*-------------------------------------------------
- describe_instruction_cop0 - build a
- description of a single instruction in the
- COP0 group
--------------------------------------------------*/
+//-------------------------------------------------
+// describe_cop0 - build a description of a
+// single instruction in the COP0 group
+//-------------------------------------------------
-static int describe_instruction_cop0(rsp_state *rsp, UINT32 op, opcode_desc *desc)
+bool rsp_frontend::describe_cop0(UINT32 op, opcode_desc &desc)
{
switch (RSREG)
{
- case 0x00: /* MFCz */
- desc->regout[0] |= REGFLAG_R(RTREG);
- return TRUE;
+ case 0x00: // MFCz
+ desc.regout[0] |= REGFLAG_R(RTREG);
+ return true;
- case 0x04: /* MTCz */
- desc->regin[0] |= REGFLAG_R(RTREG);
- return TRUE;
+ case 0x04: // MTCz
+ desc.regin[0] |= REGFLAG_R(RTREG);
+ return true;
}
- return FALSE;
+ return false;
}
-/*-------------------------------------------------
- describe_instruction_cop2 - build a
- description of a single instruction in the
- COP2 group
--------------------------------------------------*/
+//-------------------------------------------------
+// describe_cop2 - build a description of a
+// single instruction in the COP2 group
+//-------------------------------------------------
-static int describe_instruction_cop2(rsp_state *rsp, UINT32 op, opcode_desc *desc)
+bool rsp_frontend::describe_cop2(UINT32 op, opcode_desc &desc)
{
switch (RSREG)
{
- case 0x00: /* MFCz */
- case 0x02: /* CFCz */
- desc->regout[0] |= REGFLAG_R(RTREG);
- return TRUE;
-
- case 0x04: /* MTCz */
- case 0x06: /* CTCz */
- desc->regin[0] |= REGFLAG_R(RTREG);
- return TRUE;
+ case 0x00: // MFCz
+ case 0x02: // CFCz
+ desc.regout[0] |= REGFLAG_R(RTREG);
+ return true;
+
+ case 0x04: // MTCz
+ case 0x06: // CTCz
+ desc.regin[0] |= REGFLAG_R(RTREG);
+ return true;
}
- return FALSE;
+ return false;
}
diff --git a/src/emu/cpu/rsp/rspfe.h b/src/emu/cpu/rsp/rspfe.h
index 176351b8b12..b032c306b2b 100644
--- a/src/emu/cpu/rsp/rspfe.h
+++ b/src/emu/cpu/rsp/rspfe.h
@@ -15,20 +15,44 @@
#ifndef __RSPFE_H__
#define __RSPFE_H__
+#include "rsp.h"
#include "cpu/drcfe.h"
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
-/* register flags 0 */
+// register flags 0
#define REGFLAG_R(n) (((n) == 0) ? 0 : (1 << (n)))
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-int rspfe_describe(void *param, opcode_desc *desc, const opcode_desc *prev);
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class rsp_frontend : public drc_frontend
+{
+public:
+ // construction/destruction
+ rsp_frontend(rsp_state &state, UINT32 window_start, UINT32 window_end, UINT32 max_sequence);
+
+protected:
+ // required overrides
+ virtual bool describe(opcode_desc &desc, const opcode_desc *prev);
+
+private:
+ // internal helpers
+ bool describe_special(UINT32 op, opcode_desc &desc);
+ bool describe_regimm(UINT32 op, opcode_desc &desc);
+ bool describe_cop0(UINT32 op, opcode_desc &desc);
+ bool describe_cop2(UINT32 op, opcode_desc &desc);
+
+ // internal state
+ rsp_state &m_context;
+};
+
+
#endif /* __RSPFE_H__ */