From 19bf1b46ea6224c788350fbd43b65796c50daff1 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Mon, 16 Nov 2009 06:45:54 +0000 Subject: [PATCH] MIPS3 TLB fixes: - now properly generating TLB fill exceptions under correct circumstances - TLB exceptions no longer trash low 4 bits of Context - exceptions with the EXL bit set always go to vector 0x180 --- src/emu/cpu/drcumlsh.h | 1 + src/emu/cpu/mips/mips3drc.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/emu/cpu/drcumlsh.h b/src/emu/cpu/drcumlsh.h index 89c29beb676..7a546aa13eb 100644 --- a/src/emu/cpu/drcumlsh.h +++ b/src/emu/cpu/drcumlsh.h @@ -121,6 +121,7 @@ #define UML_ROLAND(block, dst, src, shift, mask) do { drcuml_block_append_4(block, DRCUML_OP_ROLAND, 4, IF_ALWAYS, dst, src, shift, mask); } while (0) #define UML_ROLINS(block, dst, src, shift, mask) do { drcuml_block_append_4(block, DRCUML_OP_ROLINS, 4, IF_ALWAYS, dst, src, shift, mask); } while (0) #define UML_ADD(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADD, 4, IF_ALWAYS, dst, src1, src2); } while (0) +#define UML_ADDc(block, cond, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADD, 4, cond, dst, src1, src2); } while (0) #define UML_ADDC(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADDC, 4, IF_ALWAYS, dst, src1, src2); } while (0) #define UML_SUB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_SUB, 4, IF_ALWAYS, dst, src1, src2); } while (0) #define UML_SUBB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_SUBB, 4, IF_ALWAYS, dst, src1, src2); } while (0) diff --git a/src/emu/cpu/mips/mips3drc.c b/src/emu/cpu/mips/mips3drc.c index 673ab1ef476..e5af943f03c 100644 --- a/src/emu/cpu/mips/mips3drc.c +++ b/src/emu/cpu/mips/mips3drc.c @@ -1103,8 +1103,8 @@ static void static_generate_tlb_mismatch(mips3_state *mips3) } UML_TEST(block, IREG(1), IMM(VTLB_FETCH_ALLOWED)); // test i1,VTLB_FETCH_ALLOWED UML_JMPc(block, IF_NZ, 1); // jmp 1,nz - UML_TEST(block, IREG(1), IMM(VTLB_FLAG_VALID)); // test i1,VTLB_FLAG_VALID - UML_EXHc(block, IF_Z, mips3->impstate->exception[EXCEPTION_TLBLOAD], IREG(0)); // exh exception[TLBLOAD],i0,z + UML_TEST(block, IREG(1), IMM(VTLB_FLAG_FIXED)); // test i1,VTLB_FLAG_FIXED + UML_EXHc(block, IF_NZ, mips3->impstate->exception[EXCEPTION_TLBLOAD], IREG(0)); // exh exception[TLBLOAD],i0,nz UML_EXH(block, mips3->impstate->exception[EXCEPTION_TLBLOAD_FILL], IREG(0)); // exh exception[TLBLOAD_FILL],i0 UML_LABEL(block, 1); // 1: save_fast_iregs(mips3, block); @@ -1175,8 +1175,10 @@ static void static_generate_exception(mips3_state *mips3, UINT8 exception, int r UML_OR(block, IREG(2), IREG(2), IMM(0x80000000)); // or i2,i2,0x80000000 UML_SUB(block, IREG(0), IREG(0), IMM(1)); // sub i0,i0,1 UML_LABEL(block, next); // : + UML_MOV(block, IREG(3), IMM(offset)); // mov i3,offset UML_TEST(block, CPR032(COP0_Status), IMM(SR_EXL)); // test [Status],SR_EXL UML_MOVc(block, IF_Z, CPR032(COP0_EPC), IREG(0)); // mov [EPC],i0,Z + UML_MOVc(block, IF_NZ, IREG(3), IMM(0x180)); // mov i3,0x180,NZ UML_OR(block, CPR032(COP0_Cause), IREG(2), IMM(exception << 2)); // or [Cause],i2,exception << 2 /* for BADCOP exceptions, we use the exception parameter to know which COP */ @@ -1199,9 +1201,9 @@ static void static_generate_exception(mips3_state *mips3, UINT8 exception, int r } /* choose our target PC */ - UML_MOV(block, IREG(0), IMM(0xbfc00200 + offset)); // mov i0,0xbfc00200 + offset + UML_ADD(block, IREG(0), IREG(3), IMM(0xbfc00200)); // add i0,i3,0xbfc00200 UML_TEST(block, IREG(1), IMM(SR_BEV)); // test i1,SR_BEV - UML_MOVc(block, IF_Z, IREG(0), IMM(0x80000000 + offset)); // mov i0,0x80000000 + offset,z + UML_ADDc(block, IF_Z, IREG(0), IREG(3), IMM(0x80000000)); // add i0,i3,0x80000000,z /* adjust cycles */ UML_SUB(block, MEM(&mips3->icount), MEM(&mips3->icount), IREG(1)); // sub icount,icount,cycles,S @@ -1425,8 +1427,8 @@ static void static_generate_memory_accessor(mips3_state *mips3, int mode, int si UML_EXHc(block, IF_NZ, mips3->impstate->exception[EXCEPTION_TLBMOD], IREG(0)); // exh tlbmod,i0,nz } - UML_TEST(block, IREG(3), IMM(VTLB_FLAG_VALID)); // test i3,VTLB_FLAG_VALID - UML_EXHc(block, IF_Z, exception_tlb, IREG(0)); // exh tlb,i0,z + UML_TEST(block, IREG(3), IMM(VTLB_FLAG_FIXED)); // test i3,VTLB_FLAG_FIXED + UML_EXHc(block, IF_NZ, exception_tlb, IREG(0)); // exh tlb,i0,nz UML_EXH(block, exception_tlbfill, IREG(0)); // exh tlbfill,i0 }