diff options
author | 2011-01-04 15:54:16 +0000 | |
---|---|---|
committer | 2011-01-04 15:54:16 +0000 | |
commit | 9e5207ce91c362e4c9f51443ebcb7ffb7119cb76 (patch) | |
tree | 0052cd14a788e4b576a5852763d95f88017c8759 /src/emu/cpu/rsp | |
parent | 68ebcf02543e03d9e051e26884bb226a4d5c78b3 (diff) |
C++-ified drcfe and the associated frontends. You now create a
frontend by deriving from drc_frontend and implementing the
describe method.
RB, if you send me your latest SH4 WIP, I'll convert it for you
if this makes you cranky. :)
Diffstat (limited to 'src/emu/cpu/rsp')
-rw-r--r-- | src/emu/cpu/rsp/rspdrc.c | 33 | ||||
-rw-r--r-- | src/emu/cpu/rsp/rspfe.c | 431 | ||||
-rw-r--r-- | src/emu/cpu/rsp/rspfe.h | 40 |
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__ */ |