diff --git a/Core/MIPS/IR/IRCompALU.cpp b/Core/MIPS/IR/IRCompALU.cpp index 4fbec417ba..6500d1b0df 100644 --- a/Core/MIPS/IR/IRCompALU.cpp +++ b/Core/MIPS/IR/IRCompALU.cpp @@ -45,7 +45,7 @@ using namespace MIPSAnalyst; namespace MIPSComp { -void IRJit::Comp_IType(MIPSOpcode op) { +void IRFrontend::Comp_IType(MIPSOpcode op) { CONDITIONAL_DISABLE; s32 simm = (s32)(s16)(op & 0xFFFF); // sign extension @@ -87,7 +87,7 @@ void IRJit::Comp_IType(MIPSOpcode op) { } } -void IRJit::Comp_RType2(MIPSOpcode op) { +void IRFrontend::Comp_RType2(MIPSOpcode op) { CONDITIONAL_DISABLE; MIPSGPReg rs = _RS; @@ -110,7 +110,7 @@ void IRJit::Comp_RType2(MIPSOpcode op) { } } -void IRJit::Comp_RType3(MIPSOpcode op) { +void IRFrontend::Comp_RType3(MIPSOpcode op) { CONDITIONAL_DISABLE; MIPSGPReg rt = _RT; @@ -182,13 +182,13 @@ void IRJit::Comp_RType3(MIPSOpcode op) { } } -void IRJit::CompShiftImm(MIPSOpcode op, IROp shiftOpImm, int sa) { +void IRFrontend::CompShiftImm(MIPSOpcode op, IROp shiftOpImm, int sa) { MIPSGPReg rd = _RD; MIPSGPReg rt = _RT; ir.Write(shiftOpImm, rd, rt, sa); } -void IRJit::CompShiftVar(MIPSOpcode op, IROp shiftOp, IROp shiftOpImm) { +void IRFrontend::CompShiftVar(MIPSOpcode op, IROp shiftOp, IROp shiftOpImm) { MIPSGPReg rd = _RD; MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; @@ -196,7 +196,7 @@ void IRJit::CompShiftVar(MIPSOpcode op, IROp shiftOp, IROp shiftOpImm) { ir.Write(shiftOp, rd, rt, IRTEMP_0); } -void IRJit::Comp_ShiftType(MIPSOpcode op) { +void IRFrontend::Comp_ShiftType(MIPSOpcode op) { CONDITIONAL_DISABLE; MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; @@ -221,7 +221,7 @@ void IRJit::Comp_ShiftType(MIPSOpcode op) { } } -void IRJit::Comp_Special3(MIPSOpcode op) { +void IRFrontend::Comp_Special3(MIPSOpcode op) { CONDITIONAL_DISABLE; MIPSGPReg rs = _RS; MIPSGPReg rt = _RT; @@ -260,7 +260,7 @@ void IRJit::Comp_Special3(MIPSOpcode op) { } -void IRJit::Comp_Allegrex(MIPSOpcode op) { +void IRFrontend::Comp_Allegrex(MIPSOpcode op) { CONDITIONAL_DISABLE; MIPSGPReg rt = _RT; MIPSGPReg rd = _RD; @@ -284,7 +284,7 @@ void IRJit::Comp_Allegrex(MIPSOpcode op) { } } -void IRJit::Comp_Allegrex2(MIPSOpcode op) { +void IRFrontend::Comp_Allegrex2(MIPSOpcode op) { CONDITIONAL_DISABLE; MIPSGPReg rt = _RT; MIPSGPReg rd = _RD; @@ -305,7 +305,7 @@ void IRJit::Comp_Allegrex2(MIPSOpcode op) { } } -void IRJit::Comp_MulDivType(MIPSOpcode op) { +void IRFrontend::Comp_MulDivType(MIPSOpcode op) { CONDITIONAL_DISABLE; MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; diff --git a/Core/MIPS/IR/IRCompBranch.cpp b/Core/MIPS/IR/IRCompBranch.cpp index acfdfaffe2..3dda003b56 100644 --- a/Core/MIPS/IR/IRCompBranch.cpp +++ b/Core/MIPS/IR/IRCompBranch.cpp @@ -53,7 +53,7 @@ namespace MIPSComp { using namespace Arm64Gen; -void IRJit::BranchRSRTComp(MIPSOpcode op, IRComparison cc, bool likely) { +void IRFrontend::BranchRSRTComp(MIPSOpcode op, IRComparison cc, bool likely) { if (js.inDelaySlot) { ERROR_LOG_REPORT(JIT, "Branch in RSRTComp delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; @@ -98,7 +98,7 @@ void IRJit::BranchRSRTComp(MIPSOpcode op, IRComparison cc, bool likely) { js.compiling = false; } -void IRJit::BranchRSZeroComp(MIPSOpcode op, IRComparison cc, bool andLink, bool likely) { +void IRFrontend::BranchRSZeroComp(MIPSOpcode op, IRComparison cc, bool andLink, bool likely) { if (js.inDelaySlot) { ERROR_LOG_REPORT(JIT, "Branch in RSZeroComp delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; @@ -135,7 +135,7 @@ void IRJit::BranchRSZeroComp(MIPSOpcode op, IRComparison cc, bool andLink, bool js.compiling = false; } -void IRJit::Comp_RelBranch(MIPSOpcode op) { +void IRFrontend::Comp_RelBranch(MIPSOpcode op) { // The CC flags here should be opposite of the actual branch becuase they skip the branching action. switch (op >> 26) { case 4: BranchRSRTComp(op, IRComparison::NotEqual, false); break;//beq @@ -156,7 +156,7 @@ void IRJit::Comp_RelBranch(MIPSOpcode op) { } } -void IRJit::Comp_RelBranchRI(MIPSOpcode op) { +void IRFrontend::Comp_RelBranchRI(MIPSOpcode op) { switch ((op >> 16) & 0x1F) { case 0: BranchRSZeroComp(op, IRComparison::GreaterEqual, false, false); break; //if ((s32)R(rs) < 0) DelayBranchTo(addr); else PC += 4; break;//bltz case 1: BranchRSZeroComp(op, IRComparison::Less, false, false); break; //if ((s32)R(rs) >= 0) DelayBranchTo(addr); else PC += 4; break;//bgez @@ -173,7 +173,7 @@ void IRJit::Comp_RelBranchRI(MIPSOpcode op) { } // If likely is set, discard the branch slot if NOT taken. -void IRJit::BranchFPFlag(MIPSOpcode op, IRComparison cc, bool likely) { +void IRFrontend::BranchFPFlag(MIPSOpcode op, IRComparison cc, bool likely) { if (js.inDelaySlot) { ERROR_LOG_REPORT(JIT, "Branch in FPFlag delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; @@ -201,7 +201,7 @@ void IRJit::BranchFPFlag(MIPSOpcode op, IRComparison cc, bool likely) { js.compiling = false; } -void IRJit::Comp_FPUBranch(MIPSOpcode op) { +void IRFrontend::Comp_FPUBranch(MIPSOpcode op) { switch((op >> 16) & 0x1f) { case 0: BranchFPFlag(op, IRComparison::NotEqual, false); break; // bc1f case 1: BranchFPFlag(op, IRComparison::Equal, false); break; // bc1t @@ -214,7 +214,7 @@ void IRJit::Comp_FPUBranch(MIPSOpcode op) { } // If likely is set, discard the branch slot if NOT taken. -void IRJit::BranchVFPUFlag(MIPSOpcode op, IRComparison cc, bool likely) { +void IRFrontend::BranchVFPUFlag(MIPSOpcode op, IRComparison cc, bool likely) { if (js.inDelaySlot) { ERROR_LOG_REPORT(JIT, "Branch in VFPU delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; @@ -223,7 +223,6 @@ void IRJit::BranchVFPUFlag(MIPSOpcode op, IRComparison cc, bool likely) { u32 targetAddr = GetCompilerPC() + offset + 4; MIPSOpcode delaySlotOp = GetOffsetInstruction(1); - logBlocks = 1; ir.Write(IROp::VfpuCtrlToReg, IRTEMP_LHS, VFPU_CTRL_CC); int dcAmount = js.downcountAmount; @@ -257,7 +256,7 @@ void IRJit::BranchVFPUFlag(MIPSOpcode op, IRComparison cc, bool likely) { js.compiling = false; } -void IRJit::Comp_VBranch(MIPSOpcode op) { +void IRFrontend::Comp_VBranch(MIPSOpcode op) { switch ((op >> 16) & 3) { case 0: BranchVFPUFlag(op, IRComparison::NotEqual, false); break; // bvf case 1: BranchVFPUFlag(op, IRComparison::Equal, false); break; // bvt @@ -266,7 +265,7 @@ void IRJit::Comp_VBranch(MIPSOpcode op) { } } -void IRJit::Comp_Jump(MIPSOpcode op) { +void IRFrontend::Comp_Jump(MIPSOpcode op) { if (js.inDelaySlot) { ERROR_LOG_REPORT(JIT, "Branch in Jump delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; @@ -311,7 +310,7 @@ void IRJit::Comp_Jump(MIPSOpcode op) { js.compiling = false; } -void IRJit::Comp_JumpReg(MIPSOpcode op) { +void IRFrontend::Comp_JumpReg(MIPSOpcode op) { if (js.inDelaySlot) { ERROR_LOG_REPORT(JIT, "Branch in JumpReg delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); return; @@ -368,7 +367,7 @@ void IRJit::Comp_JumpReg(MIPSOpcode op) { js.compiling = false; } -void IRJit::Comp_Syscall(MIPSOpcode op) { +void IRFrontend::Comp_Syscall(MIPSOpcode op) { RestoreRoundingMode(); // Note: If we're in a delay slot, this is off by one compared to the interpreter. @@ -385,7 +384,7 @@ void IRJit::Comp_Syscall(MIPSOpcode op) { js.compiling = false; } -void IRJit::Comp_Break(MIPSOpcode op) { +void IRFrontend::Comp_Break(MIPSOpcode op) { ir.Write(IROp::Break); js.compiling = false; } diff --git a/Core/MIPS/IR/IRCompFPU.cpp b/Core/MIPS/IR/IRCompFPU.cpp index b0ff42cf26..1ca4a08e96 100644 --- a/Core/MIPS/IR/IRCompFPU.cpp +++ b/Core/MIPS/IR/IRCompFPU.cpp @@ -54,7 +54,7 @@ namespace MIPSComp { -void IRJit::Comp_FPU3op(MIPSOpcode op) { +void IRFrontend::Comp_FPU3op(MIPSOpcode op) { CONDITIONAL_DISABLE; int ft = _FT; @@ -72,7 +72,7 @@ void IRJit::Comp_FPU3op(MIPSOpcode op) { } } -void IRJit::Comp_FPULS(MIPSOpcode op) { +void IRFrontend::Comp_FPULS(MIPSOpcode op) { CONDITIONAL_DISABLE; s32 offset = _IMM16; int ft = _FT; @@ -93,7 +93,7 @@ void IRJit::Comp_FPULS(MIPSOpcode op) { } } -void IRJit::Comp_FPUComp(MIPSOpcode op) { +void IRFrontend::Comp_FPUComp(MIPSOpcode op) { DISABLE; // IROps not yet implemented int opc = op & 0xF; @@ -136,7 +136,7 @@ void IRJit::Comp_FPUComp(MIPSOpcode op) { ir.Write(irOp, fs, ft); } -void IRJit::Comp_FPU2op(MIPSOpcode op) { +void IRFrontend::Comp_FPU2op(MIPSOpcode op) { CONDITIONAL_DISABLE; int fs = _FS; @@ -192,7 +192,7 @@ void IRJit::Comp_FPU2op(MIPSOpcode op) { } } -void IRJit::Comp_mxc1(MIPSOpcode op) { +void IRFrontend::Comp_mxc1(MIPSOpcode op) { CONDITIONAL_DISABLE; int fs = _FS; diff --git a/Core/MIPS/IR/IRCompLoadStore.cpp b/Core/MIPS/IR/IRCompLoadStore.cpp index 4e702a544f..41c76a1a7d 100644 --- a/Core/MIPS/IR/IRCompLoadStore.cpp +++ b/Core/MIPS/IR/IRCompLoadStore.cpp @@ -65,11 +65,11 @@ #define DISABLE { Comp_Generic(op); return; } namespace MIPSComp { - void IRJit::Comp_ITypeMemLR(MIPSOpcode op, bool load) { + void IRFrontend::Comp_ITypeMemLR(MIPSOpcode op, bool load) { DISABLE; } - void IRJit::Comp_ITypeMem(MIPSOpcode op) { + void IRFrontend::Comp_ITypeMem(MIPSOpcode op) { CONDITIONAL_DISABLE; int offset = (signed short)(op & 0xFFFF); @@ -124,7 +124,7 @@ namespace MIPSComp { } } - void IRJit::Comp_Cache(MIPSOpcode op) { + void IRFrontend::Comp_Cache(MIPSOpcode op) { // int imm = (s16)(op & 0xFFFF); // int rs = _RS; // int addr = R(rs) + imm; diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index 1f2623ac67..e6f5ca3a87 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -51,7 +51,7 @@ namespace MIPSComp { - void IRJit::Comp_VPFX(MIPSOpcode op) { + void IRFrontend::Comp_VPFX(MIPSOpcode op) { CONDITIONAL_DISABLE; int data = op & 0xFFFFF; int regnum = (op >> 24) & 3; @@ -74,7 +74,7 @@ namespace MIPSComp { } } - void IRJit::ApplyPrefixST(u8 *vregs, u32 prefix, VectorSize sz) { + void IRFrontend::ApplyPrefixST(u8 *vregs, u32 prefix, VectorSize sz) { if (prefix == 0xE4) return; @@ -128,7 +128,7 @@ namespace MIPSComp { } } - void IRJit::GetVectorRegsPrefixD(u8 *regs, VectorSize sz, int vectorReg) { + void IRFrontend::GetVectorRegsPrefixD(u8 *regs, VectorSize sz, int vectorReg) { _assert_(js.prefixDFlag & JitState::PREFIX_KNOWN); GetVectorRegs(regs, sz, vectorReg); @@ -143,7 +143,7 @@ namespace MIPSComp { } } - void IRJit::ApplyPrefixD(const u8 *vregs, VectorSize sz) { + void IRFrontend::ApplyPrefixD(const u8 *vregs, VectorSize sz) { _assert_(js.prefixDFlag & JitState::PREFIX_KNOWN); if (!js.prefixD) return; @@ -176,11 +176,11 @@ namespace MIPSComp { */ } - void IRJit::Comp_SV(MIPSOpcode op) { + void IRFrontend::Comp_SV(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_SVQ(MIPSOpcode op) { + void IRFrontend::Comp_SVQ(MIPSOpcode op) { int imm = (signed short)(op & 0xFFFC); int vt = (((op >> 16) & 0x1f)) | ((op & 1) << 5); MIPSGPReg rs = _RS; @@ -215,37 +215,37 @@ namespace MIPSComp { } } - void IRJit::Comp_VVectorInit(MIPSOpcode op) { + void IRFrontend::Comp_VVectorInit(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_VIdt(MIPSOpcode op) { + void IRFrontend::Comp_VIdt(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_VMatrixInit(MIPSOpcode op) { + void IRFrontend::Comp_VMatrixInit(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_VHdp(MIPSOpcode op) { + void IRFrontend::Comp_VHdp(MIPSOpcode op) { DISABLE; } static const float MEMORY_ALIGNED16(vavg_table[4]) = { 1.0f, 1.0f / 2.0f, 1.0f / 3.0f, 1.0f / 4.0f }; - void IRJit::Comp_Vhoriz(MIPSOpcode op) { + void IRFrontend::Comp_Vhoriz(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_VDot(MIPSOpcode op) { + void IRFrontend::Comp_VDot(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_VecDo3(MIPSOpcode op) { + void IRFrontend::Comp_VecDo3(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_VV2Op(MIPSOpcode op) { + void IRFrontend::Comp_VV2Op(MIPSOpcode op) { CONDITIONAL_DISABLE; // Pre-processing: Eliminate silly no-op VMOVs, common in Wipeout Pure if (((op >> 16) & 0x1f) == 0 && _VS == _VD && js.HasNoPrefix()) { @@ -254,19 +254,19 @@ namespace MIPSComp { DISABLE; } - void IRJit::Comp_Vi2f(MIPSOpcode op) { + void IRFrontend::Comp_Vi2f(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vh2f(MIPSOpcode op) { + void IRFrontend::Comp_Vh2f(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vf2i(MIPSOpcode op) { + void IRFrontend::Comp_Vf2i(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Mftv(MIPSOpcode op) { + void IRFrontend::Comp_Mftv(MIPSOpcode op) { int imm = op & 0xFF; MIPSGPReg rt = _RT; switch ((op >> 21) & 0x1f) { @@ -275,7 +275,6 @@ namespace MIPSComp { if (rt != 0) { if (imm < 128) { //R(rt) = VI(imm); ir.Write(IROp::VMovToGPR, rt, imm); - logBlocks = 1; } else { DISABLE; } @@ -285,7 +284,6 @@ namespace MIPSComp { case 7: // mtv if (imm < 128) { ir.Write(IROp::VMovFromGPR, imm, rt); - logBlocks = 1; } else { DISABLE; } @@ -296,93 +294,93 @@ namespace MIPSComp { } } - void IRJit::Comp_Vmfvc(MIPSOpcode op) { + void IRFrontend::Comp_Vmfvc(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vmtvc(MIPSOpcode op) { + void IRFrontend::Comp_Vmtvc(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vmmov(MIPSOpcode op) { + void IRFrontend::Comp_Vmmov(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_VScl(MIPSOpcode op) { + void IRFrontend::Comp_VScl(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vmmul(MIPSOpcode op) { + void IRFrontend::Comp_Vmmul(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vmscl(MIPSOpcode op) { + void IRFrontend::Comp_Vmscl(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vtfm(MIPSOpcode op) { + void IRFrontend::Comp_Vtfm(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_VCrs(MIPSOpcode op) { + void IRFrontend::Comp_VCrs(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_VDet(MIPSOpcode op) { + void IRFrontend::Comp_VDet(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vi2x(MIPSOpcode op) { + void IRFrontend::Comp_Vi2x(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vx2i(MIPSOpcode op) { + void IRFrontend::Comp_Vx2i(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_VCrossQuat(MIPSOpcode op) { + void IRFrontend::Comp_VCrossQuat(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vcmp(MIPSOpcode op) { + void IRFrontend::Comp_Vcmp(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vcmov(MIPSOpcode op) { + void IRFrontend::Comp_Vcmov(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Viim(MIPSOpcode op) { + void IRFrontend::Comp_Viim(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vfim(MIPSOpcode op) { + void IRFrontend::Comp_Vfim(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vcst(MIPSOpcode op) { + void IRFrontend::Comp_Vcst(MIPSOpcode op) { DISABLE; } // Very heavily used by FF:CC. Should be replaced by a fast approximation instead of // calling the math library. - void IRJit::Comp_VRot(MIPSOpcode op) { + void IRFrontend::Comp_VRot(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vsgn(MIPSOpcode op) { + void IRFrontend::Comp_Vsgn(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vocp(MIPSOpcode op) { + void IRFrontend::Comp_Vocp(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_ColorConv(MIPSOpcode op) { + void IRFrontend::Comp_ColorConv(MIPSOpcode op) { DISABLE; } - void IRJit::Comp_Vbfy(MIPSOpcode op) { + void IRFrontend::Comp_Vbfy(MIPSOpcode op) { DISABLE; } } diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index ee5f5c8206..9ed4f2eb70 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -42,11 +42,7 @@ namespace MIPSComp { -IRJit::IRJit(MIPSState *mips) : mips_(mips) { - logBlocks = 0; - dontLogBlocks = 0; - js.startDefaultPrefix = mips_->HasDefaultPrefix(); - js.currentRoundingFunc = convertS0ToSCRATCH1[0]; +IRJit::IRJit(MIPSState *mips) : mips_(mips), frontend_(mips->HasDefaultPrefix()) { u32 size = 128 * 1024; // blTrampolines_ = kernelMemory.Alloc(size, true, "trampoline"); InitIR(); @@ -55,7 +51,14 @@ IRJit::IRJit(MIPSState *mips) : mips_(mips) { IRJit::~IRJit() { } -void IRJit::DoState(PointerWrap &p) { +IRFrontend::IRFrontend(bool startDefaultPrefix) { + logBlocks = 0; + dontLogBlocks = 0; + js.startDefaultPrefix = startDefaultPrefix; + // js.currentRoundingFunc = convertS0ToSCRATCH1[0]; +} + +void IRFrontend::DoState(PointerWrap &p) { auto s = p.Section("Jit", 1, 2); if (!s) return; @@ -67,10 +70,10 @@ void IRJit::DoState(PointerWrap &p) { } else { js.hasSetRounding = 1; } +} - if (p.GetMode() == PointerWrap::MODE_READ) { - js.currentRoundingFunc = convertS0ToSCRATCH1[(mips_->fcr31) & 3]; - } +void IRJit::DoState(PointerWrap &p) { + frontend_.DoState(p); } // This is here so the savestate matches between jit and non-jit. @@ -87,11 +90,11 @@ void IRJit::DoDummyState(PointerWrap &p) { } } -void IRJit::FlushAll() { +void IRFrontend::FlushAll() { FlushPrefixV(); } -void IRJit::FlushPrefixV() { +void IRFrontend::FlushPrefixV() { if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0) { ir.Write(IROp::SetCtrlVFPU, VFPU_CTRL_SPREFIX, ir.AddConstant(js.prefixS)); js.prefixSFlag = (JitState::PrefixState) (js.prefixSFlag & ~JitState::PREFIX_DIRTY); @@ -121,7 +124,7 @@ void IRJit::InvalidateCacheAt(u32 em_address, int length) { blocks_.InvalidateICache(em_address, length); } -void IRJit::EatInstruction(MIPSOpcode op) { +void IRFrontend::EatInstruction(MIPSOpcode op) { MIPSInfo info = MIPSGetInfo(op); if (info & DELAYSLOT) { ERROR_LOG_REPORT_ONCE(ateDelaySlot, JIT, "Ate a branch op."); @@ -135,23 +138,15 @@ void IRJit::EatInstruction(MIPSOpcode op) { js.downcountAmount += MIPSGetInstructionCycleEstimate(op); } -void IRJit::CompileDelaySlot() { +void IRFrontend::CompileDelaySlot() { js.inDelaySlot = true; MIPSOpcode op = GetOffsetInstruction(1); MIPSCompileOp(op, this); js.inDelaySlot = false; } -void IRJit::Compile(u32 em_address) { - PROFILE_THIS_SCOPE("jitc"); - - int block_num = blocks_.AllocateBlock(em_address); - IRBlock *b = blocks_.GetBlock(block_num); - DoJit(em_address, b); - b->Finalize(block_num); // Overwrites the first instruction - +bool IRFrontend::CheckRounding() { bool cleanSlate = false; - if (js.hasSetRounding && !js.lastSetRounding) { WARN_LOG(JIT, "Detected rounding mode usage, rebuilding jit with checks"); // Won't loop, since hasSetRounding is only ever set to 1. @@ -161,16 +156,27 @@ void IRJit::Compile(u32 em_address) { // Drat. The VFPU hit an uneaten prefix at the end of a block. if (js.startDefaultPrefix && js.MayHavePrefix()) { - WARN_LOG(JIT, "An uneaten prefix at end of block: %08x", GetCompilerPC() - 4); + WARN_LOG(JIT, "An uneaten prefix at end of block"); js.LogPrefix(); // Let's try that one more time. We won't get back here because we toggled the value. js.startDefaultPrefix = false; - // TODO ARM64: This crashes. - //cleanSlate = true; + // TODO: Make sure this works. + // cleanSlate = true; } - if (cleanSlate) { + return cleanSlate; +} + +void IRJit::Compile(u32 em_address) { + PROFILE_THIS_SCOPE("jitc"); + + int block_num = blocks_.AllocateBlock(em_address); + IRBlock *b = blocks_.GetBlock(block_num); + frontend_.DoJit(em_address, b); + b->Finalize(block_num); // Overwrites the first instruction + + if (frontend_.CheckRounding()) { // Our assumptions are all wrong so it's clean-slate time. ClearCache(); Compile(em_address); @@ -208,18 +214,18 @@ void IRJit::RunLoopUntil(u64 globalticks) { // RestoreRoundingMode(true); } -u32 IRJit::GetCompilerPC() { +u32 IRFrontend::GetCompilerPC() { return js.compilerPC; } -MIPSOpcode IRJit::GetOffsetInstruction(int offset) { +MIPSOpcode IRFrontend::GetOffsetInstruction(int offset) { return Memory::Read_Instruction(GetCompilerPC() + 4 * offset); } -void IRJit::DoJit(u32 em_address, IRBlock *b) { +void IRFrontend::DoJit(u32 em_address, IRBlock *b) { js.cancel = false; - js.blockStart = mips_->pc; - js.compilerPC = mips_->pc; + js.blockStart = em_address; + js.compilerPC = em_address; js.lastContinuedPC = 0; js.initialBlockSize = 0; js.nextExit = 0; @@ -262,7 +268,7 @@ void IRJit::DoJit(u32 em_address, IRBlock *b) { if (logBlocks > 0 && dontLogBlocks == 0) { char temp2[256]; - ILOG("=============== mips %d %08x ===============", blocks_.GetNumBlocks(), em_address); + ILOG("=============== mips %08x ===============", em_address); for (u32 cpc = em_address; cpc != GetCompilerPC() + 4; cpc += 4) { temp2[0] = 0; MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp2, true); @@ -301,7 +307,7 @@ bool IRJit::DescribeCodePtr(const u8 *ptr, std::string &name) { return false; } -void IRJit::Comp_RunBlock(MIPSOpcode op) { +void IRFrontend::Comp_RunBlock(MIPSOpcode op) { // This shouldn't be necessary, the dispatcher should catch us before we get here. ERROR_LOG(JIT, "Comp_RunBlock should never be reached!"); } @@ -319,7 +325,7 @@ bool IRJit::ReplaceJalTo(u32 dest) { return false; } -void IRJit::Comp_ReplacementFunc(MIPSOpcode op) { +void IRFrontend::Comp_ReplacementFunc(MIPSOpcode op) { int index = op.encoding & MIPS_EMUHACK_VALUE_MASK; const ReplacementTableEntry *entry = GetReplacementFunc(index); @@ -351,7 +357,7 @@ void IRJit::Comp_ReplacementFunc(MIPSOpcode op) { } } -void IRJit::Comp_Generic(MIPSOpcode op) { +void IRFrontend::Comp_Generic(MIPSOpcode op) { FlushAll(); ir.Write(IROp::Interpret, 0, ir.AddConstant(op.encoding)); const MIPSInfo info = MIPSGetInfo(op); @@ -363,7 +369,7 @@ void IRJit::Comp_Generic(MIPSOpcode op) { } // Destroys SCRATCH2 -void IRJit::RestoreRoundingMode(bool force) { +void IRFrontend::RestoreRoundingMode(bool force) { // If the game has never set an interesting rounding mode, we can safely skip this. if (force || js.hasSetRounding) { ir.Write(IROp::RestoreRoundingMode); @@ -371,7 +377,7 @@ void IRJit::RestoreRoundingMode(bool force) { } // Destroys SCRATCH1 and SCRATCH2 -void IRJit::ApplyRoundingMode(bool force) { +void IRFrontend::ApplyRoundingMode(bool force) { // If the game has never set an interesting rounding mode, we can safely skip this. if (force || js.hasSetRounding) { ir.Write(IROp::ApplyRoundingMode); @@ -379,14 +385,14 @@ void IRJit::ApplyRoundingMode(bool force) { } // Destroys SCRATCH1 and SCRATCH2 -void IRJit::UpdateRoundingMode() { +void IRFrontend::UpdateRoundingMode() { ir.Write(IROp::UpdateRoundingMode); } -void IRJit::Comp_DoNothing(MIPSOpcode op) { +void IRFrontend::Comp_DoNothing(MIPSOpcode op) { } -int IRJit::Replace_fabsf() { +int IRFrontend::Replace_fabsf() { Crash(); return 0; } diff --git a/Core/MIPS/IR/IRJit.h b/Core/MIPS/IR/IRJit.h index 76a27d1a4b..3947136ea9 100644 --- a/Core/MIPS/IR/IRJit.h +++ b/Core/MIPS/IR/IRJit.h @@ -101,28 +101,11 @@ private: std::vector blocks_; }; -class IRJit : public JitInterface, public MIPSFrontendInterface{ +class IRFrontend : public MIPSFrontendInterface { public: - IRJit(MIPSState *mips); - virtual ~IRJit(); - - void DoState(PointerWrap &p) override; - void DoDummyState(PointerWrap &p) override; - - const JitOptions &GetJitOptions() { return jo; } - - // Compiled ops should ignore delay slots - // the compiler will take care of them by itself - // OR NOT + IRFrontend(bool startDefaultPrefix); void Comp_Generic(MIPSOpcode op) override; - void RunLoopUntil(u64 globalticks) override; - - void Compile(u32 em_address) override; // Compiles a block at current MIPS PC - void DoJit(u32 em_address, IRBlock *b); - - bool DescribeCodePtr(const u8 *ptr, std::string &name) override; - void Comp_RunBlock(MIPSOpcode op) override; void Comp_ReplacementFunc(MIPSOpcode op) override; @@ -195,25 +178,17 @@ public: void Comp_Vbfy(MIPSOpcode op) override; int Replace_fabsf(); + void DoState(PointerWrap &p); + bool CheckRounding(); // returns true if we need a do-over + void DoJit(u32 em_address, IRBlock *b); - // Not using a regular block cache. - JitBlockCache *GetBlockCache() override { return nullptr; } - MIPSOpcode GetOriginalOp(MIPSOpcode op) override; - - void ClearCache(); - void InvalidateCache(); - void InvalidateCacheAt(u32 em_address, int length = 4); +private: + void RestoreRoundingMode(bool force = false); + void ApplyRoundingMode(bool force = false); + void UpdateRoundingMode(); void EatPrefix() { js.EatPrefix(); } - const u8 *GetDispatcher() const override { - return dispatcher; - } - - void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override; - void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override; - -private: void FlushAll(); void FlushPrefixV(); @@ -222,12 +197,6 @@ private: void EatInstruction(MIPSOpcode op); MIPSOpcode GetOffsetInstruction(int offset); - void RestoreRoundingMode(bool force = false); - void ApplyRoundingMode(bool force = false); - void UpdateRoundingMode(); - - bool ReplaceJalTo(u32 dest); - // Utility compilation functions void BranchFPFlag(MIPSOpcode op, IRComparison cc, bool likely); void BranchVFPUFlag(MIPSOpcode op, IRComparison cc, bool likely); @@ -255,44 +224,55 @@ private: // Utils void Comp_ITypeMemLR(MIPSOpcode op, bool load); - JitOptions jo; + // State JitState js; + IRWriter ir; + int dontLogBlocks; + int logBlocks; +}; + +class IRJit : public JitInterface { +public: + IRJit(MIPSState *mips); + virtual ~IRJit(); + + void DoState(PointerWrap &p) override; + void DoDummyState(PointerWrap &p) override; + + const JitOptions &GetJitOptions() { return jo; } + + void RunLoopUntil(u64 globalticks) override; + + void Compile(u32 em_address) override; // Compiles a block at current MIPS PC + + bool DescribeCodePtr(const u8 *ptr, std::string &name) override; + // Not using a regular block cache. + JitBlockCache *GetBlockCache() override { return nullptr; } + MIPSOpcode GetOriginalOp(MIPSOpcode op) override; + + void ClearCache(); + void InvalidateCache(); + void InvalidateCacheAt(u32 em_address, int length = 4); + + const u8 *GetDispatcher() const override { return nullptr; } + + void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override; + void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override; + +private: + bool ReplaceJalTo(u32 dest); + + JitOptions jo; + + IRFrontend frontend_; IRBlockCache blocks_; MIPSState *mips_; - int dontLogBlocks; - int logBlocks; - - IRWriter ir; - // where to write branch-likely trampolines. not used atm // u32 blTrampolines_; // int blTrampolineCount_; - -public: - // Code pointers - const u8 *enterDispatcher; - - const u8 *outerLoop; - const u8 *outerLoopPCInSCRATCH1; - const u8 *dispatcherCheckCoreState; - const u8 *dispatcherPCInSCRATCH1; - const u8 *dispatcher; - const u8 *dispatcherNoCheck; - - const u8 *breakpointBailout; - - const u8 *saveStaticRegisters; - const u8 *loadStaticRegisters; - - const u8 *restoreRoundingMode; - const u8 *applyRoundingMode; - const u8 *updateRoundingMode; - - // Indexed by FPCR FZ:RN bits for convenience. Uses SCRATCH2. - const u8 *convertS0ToSCRATCH1[8]; }; } // namespace MIPSComp