(nw) mips3drc: Made badcop exception handling cleaner. If you haven't read Bob Martin's "Clean Code" yet, do so.

This commit is contained in:
Ryan Holtz 2014-08-27 07:19:47 +00:00
parent e5a77f7811
commit 6c5bfdd7b9
2 changed files with 60 additions and 30 deletions

View File

@ -544,20 +544,28 @@ private:
void static_generate_tlb_mismatch();
void static_generate_exception(UINT8 exception, int recover, const char *name);
void static_generate_memory_accessor(int mode, int size, int iswrite, int ismasked, const char *name, uml::code_handle **handleptr);
void generate_update_mode(drcuml_block *block);
void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, int allow_exception);
void generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast);
void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_delay_slot_and_branch(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 linkreg);
int generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
int generate_special(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
int generate_regimm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
int generate_idt(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
int generate_set_cop0_reg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 reg);
int generate_get_cop0_reg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 reg);
int generate_cop0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
int generate_cop1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
int generate_cop1x(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void check_cop0_access(drcuml_block *block);
void check_cop1_access(drcuml_block *block);
void generate_badcop(drcuml_block *block, const int cop);
void log_add_disasm_comment(drcuml_block *block, UINT32 pc, UINT32 op);
const char *log_desc_flags_to_string(UINT32 flags);
void log_register_list(drcuml_state *drcuml, const char *string, const UINT32 *reglist, const UINT32 *regnostarlist);
@ -743,12 +751,13 @@ private:
/* fix me -- how do we make this work?? */
#define MIPS3DRC_STRICT_VERIFY 0x0001 /* verify all instructions */
#define MIPS3DRC_STRICT_COP1 0x0002 /* validate all COP1 instructions */
#define MIPS3DRC_STRICT_COP2 0x0004 /* validate all COP2 instructions */
#define MIPS3DRC_FLUSH_PC 0x0008 /* flush the PC value before each memory access */
#define MIPS3DRC_CHECK_OVERFLOWS 0x0010 /* actually check overflows on add/sub instructions */
#define MIPS3DRC_STRICT_COP0 0x0002 /* validate all COP0 instructions */
#define MIPS3DRC_STRICT_COP1 0x0004 /* validate all COP1 instructions */
#define MIPS3DRC_STRICT_COP2 0x0008 /* validate all COP2 instructions */
#define MIPS3DRC_FLUSH_PC 0x0010 /* flush the PC value before each memory access */
#define MIPS3DRC_CHECK_OVERFLOWS 0x0020 /* actually check overflows on add/sub instructions */
#define MIPS3DRC_COMPATIBLE_OPTIONS (MIPS3DRC_STRICT_VERIFY | MIPS3DRC_STRICT_COP1 | MIPS3DRC_STRICT_COP2 | MIPS3DRC_FLUSH_PC)
#define MIPS3DRC_COMPATIBLE_OPTIONS (MIPS3DRC_STRICT_VERIFY | MIPS3DRC_STRICT_COP1 | MIPS3DRC_STRICT_COP0 | MIPS3DRC_STRICT_COP2 | MIPS3DRC_FLUSH_PC)
#define MIPS3DRC_FASTEST_OPTIONS (0)

View File

@ -1617,8 +1617,7 @@ int mips3_device::generate_opcode(drcuml_block *block, compiler_state *compiler,
return TRUE;
case 0x31: /* LWC1 - MIPS I */
UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1
UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1); // exh cop,1,Z
check_cop1_access(block);
UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,<rsreg>,SIMMVAL
UML_CALLH(block, *m_read32[m_core->mode >> 1]); // callh read32
UML_MOV(block, FPR32(RTREG), I0); // mov <cpr1_rt>,i0
@ -1627,8 +1626,7 @@ int mips3_device::generate_opcode(drcuml_block *block, compiler_state *compiler,
return TRUE;
case 0x35: /* LDC1 - MIPS III */
UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1
UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1); // exh cop,1,Z
check_cop1_access(block);
UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,<rsreg>,SIMMVAL
UML_CALLH(block, *m_read64[m_core->mode >> 1]); // callh read64
UML_DMOV(block, FPR64(RTREG), I0); // dmov <cpr1_rt>,i0
@ -1772,8 +1770,7 @@ int mips3_device::generate_opcode(drcuml_block *block, compiler_state *compiler,
return TRUE;
case 0x39: /* SWC1 - MIPS I */
UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1
UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1); // exh cop,1,Z
check_cop1_access(block);
UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,<rsreg>,SIMMVAL
UML_MOV(block, I1, FPR32(RTREG)); // mov i1,<cpr1_rt>
UML_CALLH(block, *m_write32[m_core->mode >> 1]); // callh write32
@ -1782,8 +1779,7 @@ int mips3_device::generate_opcode(drcuml_block *block, compiler_state *compiler,
return TRUE;
case 0x3d: /* SDC1 - MIPS III */
UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1
UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1); // exh cop,1,Z
check_cop1_access(block);
UML_ADD(block, I0, R32(RSREG), SIMMVAL); // add i0,<rsreg>,SIMMVAL
UML_DMOV(block, I1, FPR64(RTREG)); // dmov i1,<cpr1_rt>
UML_CALLH(block, *m_write64[m_core->mode >> 1]); // callh write64
@ -2480,6 +2476,28 @@ int mips3_device::generate_get_cop0_reg(drcuml_block *block, compiler_state *com
}
/*-------------------------------------------------------------------------
generate_badcop - raise a BADCOP exception
-------------------------------------------------------------------------*/
void mips3_device::generate_badcop(drcuml_block *block, const int cop)
{
UML_TEST(block, CPR032(COP0_Status), SR_COP0 << cop); // test [Status], SR_COP0 << cop
UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], cop); // exh badcop,cop,Z
}
/*-------------------------------------------------------------------------
check_cop0_access - raise a BADCOP exception if we're not in kernel mode
-------------------------------------------------------------------------*/
void mips3_device::check_cop0_access(drcuml_block *block)
{
if ((m_core->mode >> 1) != MODE_KERNEL)
{
generate_badcop(block, 0);
}
}
/*-------------------------------------------------
generate_cop0 - compile COP0 opcodes
-------------------------------------------------*/
@ -2606,6 +2624,18 @@ int mips3_device::generate_cop0(drcuml_block *block, compiler_state *compiler, c
COP1 RECOMPILATION
***************************************************************************/
/*-------------------------------------------------------------------------
check_cop1_access - raise a BADCOP exception if COP1 is not enabled
-------------------------------------------------------------------------*/
void mips3_device::check_cop1_access(drcuml_block *block)
{
if (m_drcoptions & MIPS3DRC_STRICT_COP1)
{
generate_badcop(block, 1);
}
}
/*-------------------------------------------------
generate_cop1 - compile COP1 opcodes
-------------------------------------------------*/
@ -2616,39 +2646,34 @@ int mips3_device::generate_cop1(drcuml_block *block, compiler_state *compiler, c
code_label skip;
condition_t condition;
/* generate an exception if COP1 is disabled */
if (m_drcoptions & MIPS3DRC_STRICT_COP1)
{
UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1
UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1);// exh cop,1,Z
}
check_cop1_access(block);
switch (RSREG)
{
case 0x00: /* MFCz - MIPS I */
case 0x00: /* MFC1 - MIPS I */
if (RTREG != 0)
UML_DSEXT(block, R64(RTREG), FPR32(RDREG), SIZE_DWORD); // dsext <rtreg>,fpr[rdreg],dword
return TRUE;
case 0x01: /* DMFCz - MIPS III */
case 0x01: /* DMFC1 - MIPS III */
if (RTREG != 0)
UML_DMOV(block, R64(RTREG), FPR64(RDREG)); // dmov <rtreg>,fpr[rdreg]
return TRUE;
case 0x02: /* CFCz - MIPS I */
case 0x02: /* CFC1 - MIPS I */
if (RTREG != 0)
UML_DSEXT(block, R64(RTREG), CCR132(RDREG), SIZE_DWORD); // dsext <rtreg>,ccr132[rdreg],dword
return TRUE;
case 0x04: /* MTCz - MIPS I */
case 0x04: /* MTC1 - MIPS I */
UML_MOV(block, FPR32(RDREG), R32(RTREG)); // mov fpr[rdreg],<rtreg>
return TRUE;
case 0x05: /* DMTCz - MIPS III */
case 0x05: /* DMTC1 - MIPS III */
UML_DMOV(block, FPR64(RDREG), R64(RTREG)); // dmov fpr[rdreg],<rtreg>
return TRUE;
case 0x06: /* CTCz - MIPS I */
case 0x06: /* CTC1 - MIPS I */
if (RDREG != 31)
UML_DSEXT(block, CCR164(RDREG), R32(RTREG), SIZE_DWORD); // dsext ccr1[rdreg],<rtreg>,dword
else
@ -2991,11 +3016,7 @@ int mips3_device::generate_cop1x(drcuml_block *block, compiler_state *compiler,
int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
UINT32 op = desc->opptr.l[0];
if (m_drcoptions & MIPS3DRC_STRICT_COP1)
{
UML_TEST(block, CPR032(COP0_Status), SR_COP1); // test [Status],SR_COP1
UML_EXHc(block, COND_Z, *m_exception[EXCEPTION_BADCOP], 1);// exh cop,1,Z
}
check_cop1_access(block);
switch (op & 0x3f)
{