From c7635a5d2f56ee76117db1fdc7e43916abadeceb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 8 Feb 2021 23:17:15 -0800 Subject: [PATCH] Jit: Fix compilation of FakeJit. Maybe should just remove this... --- Common/FakeEmitter.h | 89 +++++++++++--------------------------- Common/MipsEmitter.cpp | 2 +- Common/MipsEmitter.h | 2 +- Core/Core.vcxproj | 2 + Core/Core.vcxproj.filters | 9 ++++ Core/MIPS/MIPS/MipsJit.cpp | 2 +- Core/MIPS/fake/FakeJit.cpp | 21 +++++---- Core/MIPS/fake/FakeJit.h | 27 +++++++++--- 8 files changed, 74 insertions(+), 80 deletions(-) diff --git a/Common/FakeEmitter.h b/Common/FakeEmitter.h index 6b827655c8..25954ee350 100644 --- a/Common/FakeEmitter.h +++ b/Common/FakeEmitter.h @@ -24,6 +24,7 @@ #include #include "Common.h" +#include "Common/CodeBlock.h" // VCVT flags #define TO_FLOAT 0 @@ -167,7 +168,7 @@ public: Operand2(FakeReg base, ShiftType type, FakeReg shift) // RSR { Type = TYPE_RSR; - _assert_msg_(JIT, type != ST_RRX, "Invalid Operand2: RRX does not take a register shift amount"); + _assert_msg_(type != ST_RRX, "Invalid Operand2: RRX does not take a register shift amount"); IndexOrShift = shift; Shift = type; Value = base; @@ -179,29 +180,29 @@ public: switch (type) { case ST_LSL: - _assert_msg_(JIT, shift < 32, "Invalid Operand2: LSL %u", shift); + _assert_msg_(shift < 32, "Invalid Operand2: LSL %u", shift); break; case ST_LSR: - _assert_msg_(JIT, shift <= 32, "Invalid Operand2: LSR %u", shift); + _assert_msg_(shift <= 32, "Invalid Operand2: LSR %u", shift); if (!shift) type = ST_LSL; if (shift == 32) shift = 0; break; case ST_ASR: - _assert_msg_(JIT, shift < 32, "Invalid Operand2: ASR %u", shift); + _assert_msg_(shift < 32, "Invalid Operand2: ASR %u", shift); if (!shift) type = ST_LSL; if (shift == 32) shift = 0; break; case ST_ROR: - _assert_msg_(JIT, shift < 32, "Invalid Operand2: ROR %u", shift); + _assert_msg_(shift < 32, "Invalid Operand2: ROR %u", shift); if (!shift) type = ST_LSL; break; case ST_RRX: - _assert_msg_(JIT, shift == 0, "Invalid Operand2: RRX does not take an immediate shift amount"); + _assert_msg_(shift == 0, "Invalid Operand2: RRX does not take an immediate shift amount"); type = ST_ROR; break; } @@ -223,45 +224,45 @@ public: case TYPE_RSR: return RSR(); default: - _assert_msg_(JIT, false, "GetData with Invalid Type"); + _assert_msg_(false, "GetData with Invalid Type"); return 0; } } u32 IMMSR() // IMM shifted register { - _assert_msg_(JIT, Type == TYPE_IMMSREG, "IMMSR must be imm shifted register"); + _assert_msg_(Type == TYPE_IMMSREG, "IMMSR must be imm shifted register"); return ((IndexOrShift & 0x1f) << 7 | (Shift << 5) | Value); } u32 RSR() // Register shifted register { - _assert_msg_(JIT, Type == TYPE_RSR, "RSR must be RSR Of Course"); + _assert_msg_(Type == TYPE_RSR, "RSR must be RSR Of Course"); return (IndexOrShift << 8) | (Shift << 5) | 0x10 | Value; } u32 Rm() { - _assert_msg_(JIT, Type == TYPE_REG, "Rm must be with Reg"); + _assert_msg_(Type == TYPE_REG, "Rm must be with Reg"); return Value; } u32 Imm5() { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm5 not IMM value"); + _assert_msg_(Type == TYPE_IMM, "Imm5 not IMM value"); return ((Value & 0x0000001F) << 7); } u32 Imm8() { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm8Rot not IMM value"); + _assert_msg_(Type == TYPE_IMM, "Imm8Rot not IMM value"); return Value & 0xFF; } u32 Imm8Rot() // IMM8 with Rotation { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm8Rot not IMM value"); - _assert_msg_(JIT, (Rotation & 0xE1) != 0, "Invalid Operand2: immediate rotation %u", Rotation); + _assert_msg_(Type == TYPE_IMM, "Imm8Rot not IMM value"); + _assert_msg_((Rotation & 0xE1) != 0, "Invalid Operand2: immediate rotation %u", Rotation); return (1 << 25) | (Rotation << 7) | (Value & 0x000000FF); } u32 Imm12() { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm12 not IMM"); + _assert_msg_(Type == TYPE_IMM, "Imm12 not IMM"); return (Value & 0x00000FFF); } @@ -272,12 +273,12 @@ public: // expand a 8bit IMM to a 32bit value and gives you some rotation as // well. // Each rotation rotates to the right by 2 bits - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm12Mod not IMM"); + _assert_msg_(Type == TYPE_IMM, "Imm12Mod not IMM"); return ((Rotation & 0xF) << 8) | (Value & 0xFF); } u32 Imm16() { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm16 not IMM"); + _assert_msg_(Type == TYPE_IMM, "Imm16 not IMM"); return ( (Value & 0xF000) << 4) | (Value & 0x0FFF); } u32 Imm16Low() @@ -286,12 +287,12 @@ public: } u32 Imm16High() // Returns high 16bits { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm16 not IMM"); + _assert_msg_(Type == TYPE_IMM, "Imm16 not IMM"); return ( ((Value >> 16) & 0xF000) << 4) | ((Value >> 16) & 0x0FFF); } u32 Imm24() { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm16 not IMM"); + _assert_msg_(Type == TYPE_IMM, "Imm16 not IMM"); return (Value & 0x0FFFFFFF); } }; @@ -380,6 +381,9 @@ public: } virtual ~FakeXEmitter() {} + void SetCodePointer(u8 *ptr, u8 *writePtr) {} + const u8 *GetCodePointer() const { return nullptr; } + void SetCodePtr(u8 *ptr) {} void ReserveCodeSpace(u32 bytes) {} const u8 *AlignCode16() { return nullptr; } @@ -411,52 +415,9 @@ public: // Everything that needs to generate machine code should inherit from this. // You get memory management for free, plus, you can use all the MOV etc functions without // having to prefix them with gen-> or something similar. -class FakeXCodeBlock : public FakeXEmitter -{ -protected: - u8 *region; - size_t region_size; - +class FakeXCodeBlock : public CodeBlock { public: - FakeXCodeBlock() : region(NULL), region_size(0) {} - virtual ~FakeXCodeBlock() { if (region) FreeCodeSpace(); } - - // Call this before you generate any code. - void AllocCodeSpace(int size) { } - - // Always clear code space with breakpoints, so that if someone accidentally executes - // uninitialized, it just breaks into the debugger. - void ClearCodeSpace() { } - - // Call this when shutting down. Don't rely on the destructor, even though it'll do the job. - void FreeCodeSpace() { } - - bool IsInSpace(const u8 *ptr) const - { - return ptr >= region && ptr < region + region_size; - } - - // Cannot currently be undone. Will write protect the entire code region. - // Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()). - void WriteProtect() { } - void UnWriteProtect() { } - - void ResetCodePtr() - { - SetCodePtr(region); - } - - size_t GetSpaceLeft() const - { - return region_size - (GetCodePtr() - region); - } - - u8 *GetBasePtr() { - return region; - } - - size_t GetOffset(const u8 *ptr) const { - return ptr - region; + void PoisonMemory(int offset) override { } }; diff --git a/Common/MipsEmitter.cpp b/Common/MipsEmitter.cpp index 5d6288be3e..682de9304c 100644 --- a/Common/MipsEmitter.cpp +++ b/Common/MipsEmitter.cpp @@ -474,7 +474,7 @@ void MIPSCodeBlock::AllocCodeSpace(int size) { // Always clear code space with breakpoints, so that if someone accidentally executes // uninitialized, it just breaks into the debugger. -void MIPSCodeBlock::ClearCodeSpace() { +void MIPSCodeBlock::ClearCodeSpace(int offset) { // Set BREAK instructions on all of it. u32 *region32 = (u32 *)region; for (u32 i = 0; i < region_size / 4; ++i) { diff --git a/Common/MipsEmitter.h b/Common/MipsEmitter.h index 19913ec2e2..298ad06b9b 100644 --- a/Common/MipsEmitter.h +++ b/Common/MipsEmitter.h @@ -285,7 +285,7 @@ public: // Always clear code space with breakpoints, so that if someone accidentally executes // uninitialized, it just breaks into the debugger. - void ClearCodeSpace(); + void ClearCodeSpace(int offset); // Call this when shutting down. Don't rely on the destructor, even though it'll do the job. void FreeCodeSpace(); diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 060eeb4ddb..065a61aff3 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -457,6 +457,7 @@ + @@ -1004,6 +1005,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 93b6b137ef..51d07653fd 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -88,6 +88,9 @@ {0201ff27-4fa8-4cf3-bbb9-accfdc0c7046} + + {678fa299-0ff7-4983-982d-2da47b52e238} + @@ -971,6 +974,9 @@ Debugger\WebSocket + + MIPS\fake + @@ -1661,6 +1667,9 @@ Debugger\WebSocket + + MIPS\fake + diff --git a/Core/MIPS/MIPS/MipsJit.cpp b/Core/MIPS/MIPS/MipsJit.cpp index 5201437784..33013481a7 100644 --- a/Core/MIPS/MIPS/MipsJit.cpp +++ b/Core/MIPS/MIPS/MipsJit.cpp @@ -82,7 +82,7 @@ void MipsJit::FlushPrefixV() void MipsJit::ClearCache() { blocks.Clear(); - ClearCodeSpace(); + ClearCodeSpace(0); //GenerateFixedCode(); } diff --git a/Core/MIPS/fake/FakeJit.cpp b/Core/MIPS/fake/FakeJit.cpp index 257005a429..a03c732118 100644 --- a/Core/MIPS/fake/FakeJit.cpp +++ b/Core/MIPS/fake/FakeJit.cpp @@ -16,10 +16,12 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Reporting.h" #include "Core/Config.h" #include "Core/Core.h" #include "Core/CoreTiming.h" +#include "Core/Debugger/Breakpoints.h" #include "Core/Debugger/SymbolMap.h" #include "Core/MemMap.h" #include "Core/MIPS/MIPS.h" @@ -45,19 +47,22 @@ FakeJit::FakeJit(MIPSState *mips) : blocks(mips, this), mips_(mips) blocks.Init(); } -void FakeJit::DoState(PointerWrap &p) -{ - auto s = p.Section("FakeJit", 1, 2); +void FakeJit::DoState(PointerWrap &p) { + auto s = p.Section("Jit", 1, 2); if (!s) return; - p.Do(js.startDefaultPrefix); + Do(p, js.startDefaultPrefix); if (s >= 2) { - p.Do(js.hasSetRounding); + Do(p, js.hasSetRounding); js.lastSetRounding = 0; } else { js.hasSetRounding = 1; } + + // The debugger sets this so that "go" on a breakpoint will actually... go. + // But if they load a state, we can end up hitting it by mistake, since it's based on PC and ticks. + CBreakPoints::SetSkipFirst(0); } // This is here so the savestate matches between jit and non-jit. @@ -68,10 +73,10 @@ void FakeJit::DoDummyState(PointerWrap &p) return; bool dummy = false; - p.Do(dummy); + Do(p, dummy); if (s >= 2) { dummy = true; - p.Do(dummy); + Do(p, dummy); } } @@ -89,7 +94,7 @@ void FakeJit::FlushPrefixV() void FakeJit::ClearCache() { blocks.Clear(); - ClearCodeSpace(); + ClearCodeSpace(0); //GenerateFixedCode(); } diff --git a/Core/MIPS/fake/FakeJit.h b/Core/MIPS/fake/FakeJit.h index d23303a654..dd1954d1bc 100644 --- a/Core/MIPS/fake/FakeJit.h +++ b/Core/MIPS/fake/FakeJit.h @@ -18,8 +18,9 @@ #pragma once #include "Common/FakeEmitter.h" -#include "Core/MIPS/JitCommon/JitState.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" +#include "Core/MIPS/JitCommon/JitState.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "../MIPSVFPUUtils.h" #ifndef offsetof @@ -30,7 +31,7 @@ namespace MIPSComp { typedef int FakeReg; -class FakeJit : public FakeGen::FakeXCodeBlock { +class FakeJit : public FakeGen::FakeXCodeBlock, public JitInterface, public MIPSFrontendInterface { public: FakeJit(MIPSState *mips); @@ -46,7 +47,9 @@ public: void Compile(u32 em_address); // Compiles a block at current MIPS PC const u8 *DoJit(u32 em_address, JitBlock *b); - bool DescribeCodePtr(const u8 *ptr, std::string &name); + const u8 *GetCrashHandler() const override { return nullptr; } + bool CodeInRange(const u8 *ptr) const override { return IsInSpace(ptr); } + bool DescribeCodePtr(const u8 *ptr, std::string &name) override; void CompileDelaySlot(int flags); void EatInstruction(MIPSOpcode op); @@ -126,9 +129,23 @@ public: int Replace_fabsf() { return 0; } JitBlockCache *GetBlockCache() { return &blocks; } + JitBlockCacheDebugInterface *GetBlockCacheDebugInterface() override { return &blocks; } - void ClearCache(); - void InvalidateCacheAt(u32 em_address, int length = 4); + MIPSOpcode GetOriginalOp(MIPSOpcode op) override { return op; } + + std::vector SaveAndClearEmuHackOps() override { return blocks.SaveAndClearEmuHackOps(); } + void RestoreSavedEmuHackOps(std::vector saved) override { blocks.RestoreSavedEmuHackOps(saved); } + + void ClearCache() override; + void InvalidateCacheAt(u32 em_address, int length = 4) override; + void UpdateFCR31() override {} + + const u8 *GetDispatcher() const override { + return nullptr; + } + + void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override {} + void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override {} void EatPrefix() { js.EatPrefix(); }