Skip to content

Commit

Permalink
Merge pull request #14088 from unknownbrackets/fakejit
Browse files Browse the repository at this point in the history
Jit: Fix compilation of FakeJit and MipsJit
  • Loading branch information
hrydgard authored Feb 15, 2021
2 parents 9312635 + 4e24b27 commit a2093da
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 83 deletions.
89 changes: 25 additions & 64 deletions Common/FakeEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <stdint.h>

#include "Common.h"
#include "Common/CodeBlock.h"

// VCVT flags
#define TO_FLOAT 0
Expand Down Expand Up @@ -167,7 +168,7 @@ class Operand2
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;
Expand All @@ -179,29 +180,29 @@ class Operand2
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;
}
Expand All @@ -223,45 +224,45 @@ class Operand2
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);
}

Expand All @@ -272,12 +273,12 @@ class Operand2
// 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()
Expand All @@ -286,12 +287,12 @@ class Operand2
}
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);
}
};
Expand Down Expand Up @@ -380,6 +381,9 @@ class FakeXEmitter
}
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; }
Expand Down Expand Up @@ -411,52 +415,9 @@ class FakeXEmitter
// 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<FakeXEmitter> {
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 {
}
};

Expand Down
2 changes: 1 addition & 1 deletion Common/MipsEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion Common/MipsEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ class MIPSCodeBlock : public MIPSEmitter {

// 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();
Expand Down
2 changes: 2 additions & 0 deletions Core/Core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@
<ClCompile Include="Instance.cpp" />
<ClCompile Include="KeyMap.cpp" />
<ClCompile Include="MemFault.cpp" />
<ClCompile Include="MIPS\fake\FakeJit.cpp" />
<ClCompile Include="MIPS\IR\IRAsm.cpp" />
<ClCompile Include="MIPS\IR\IRCompALU.cpp" />
<ClCompile Include="MIPS\IR\IRCompBranch.cpp" />
Expand Down Expand Up @@ -1004,6 +1005,7 @@
<ClInclude Include="Instance.h" />
<ClInclude Include="KeyMap.h" />
<ClInclude Include="MemFault.h" />
<ClInclude Include="MIPS\fake\FakeJit.h" />
<ClInclude Include="MIPS\IR\IRFrontend.h" />
<ClInclude Include="MIPS\IR\IRInst.h" />
<ClInclude Include="MIPS\IR\IRInterpreter.h" />
Expand Down
9 changes: 9 additions & 0 deletions Core/Core.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@
<Filter Include="Ext\libzip">
<UniqueIdentifier>{0201ff27-4fa8-4cf3-bbb9-accfdc0c7046}</UniqueIdentifier>
</Filter>
<Filter Include="MIPS\fake">
<UniqueIdentifier>{678fa299-0ff7-4983-982d-2da47b52e238}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ELF\ElfReader.cpp">
Expand Down Expand Up @@ -971,6 +974,9 @@
<ClCompile Include="Debugger\WebSocket\InputBroadcaster.cpp">
<Filter>Debugger\WebSocket</Filter>
</ClCompile>
<ClCompile Include="MIPS\fake\FakeJit.cpp">
<Filter>MIPS\fake</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ELF\ElfReader.h">
Expand Down Expand Up @@ -1661,6 +1667,9 @@
<ClInclude Include="Debugger\WebSocket\InputBroadcaster.h">
<Filter>Debugger\WebSocket</Filter>
</ClInclude>
<ClInclude Include="MIPS\fake\FakeJit.h">
<Filter>MIPS\fake</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
Expand Down
4 changes: 4 additions & 0 deletions Core/MIPS/JitCommon/JitState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ namespace MIPSComp {

// We can get block linking to work with W^X by doing even more unprotect/re-protect, but let's try without first.
// enableBlocklink = !PlatformIsWXExclusive(); // Revert to this line if block linking is slow in W^X mode
#if PPSSPP_ARCH(MIPS)
enableBlocklink = false;
#else
enableBlocklink = !Disabled(JitDisable::BLOCKLINK);
#endif
immBranches = false;
continueBranches = false;
continueJumps = false;
Expand Down
20 changes: 19 additions & 1 deletion Core/MIPS/MIPS/MipsJit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,20 @@ void MipsJit::FlushPrefixV()
{
}

MIPSOpcode MipsJit::GetOriginalOp(MIPSOpcode op) {
JitBlockCache *bc = GetBlockCache();
int block_num = bc->GetBlockNumberFromEmuHackOp(op, true);
if (block_num >= 0) {
return bc->GetOriginalFirstOp(block_num);
} else {
return op;
}
}

void MipsJit::ClearCache()
{
blocks.Clear();
ClearCodeSpace();
ClearCodeSpace(0);
//GenerateFixedCode();
}

Expand Down Expand Up @@ -226,6 +236,14 @@ void MipsJit::Comp_RunBlock(MIPSOpcode op)
ERROR_LOG(JIT, "Comp_RunBlock should never be reached!");
}

void MipsJit::LinkBlock(u8 *exitPoint, const u8 *checkedEntry) {
// TODO
}

void MipsJit::UnlinkBlock(u8 *checkedEntry, u32 originalAddress) {
// TODO
}

bool MipsJit::ReplaceJalTo(u32 dest) {
const ReplacementTableEntry *entry = nullptr;
u32 funcSize = 0;
Expand Down
14 changes: 11 additions & 3 deletions Core/MIPS/MIPS/MipsJit.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class MipsJit : public MIPSGen::MIPSCodeBlock, public JitInterface, public MIPSF
void Compile(u32 em_address) override; // Compiles a block at current MIPS PC
const u8 *DoJit(u32 em_address, JitBlock *b);

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);

void CompileDelaySlot(int flags);
Expand Down Expand Up @@ -131,13 +133,22 @@ class MipsJit : public MIPSGen::MIPSCodeBlock, public JitInterface, public MIPSF
JitBlockCache *GetBlockCache() override { return &blocks; }
JitBlockCacheDebugInterface *GetBlockCacheDebugInterface() override { return &blocks; }

MIPSOpcode GetOriginalOp(MIPSOpcode op) override;

std::vector<u32> SaveAndClearEmuHackOps() override { return blocks.SaveAndClearEmuHackOps(); }
void RestoreSavedEmuHackOps(std::vector<u32> 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 dispatcher;
}

void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override;
void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override;

void EatPrefix() override { js.EatPrefix(); }

private:
Expand Down Expand Up @@ -183,8 +194,5 @@ class MipsJit : public MIPSGen::MIPSCodeBlock, public JitInterface, public MIPSF
const u8 *dispatcherNoCheck;
};

typedef void (MipsJit::*MIPSCompileFunc)(MIPSOpcode opcode);
typedef int (MipsJit::*MIPSReplaceFunc)();

} // namespace MIPSComp

Loading

0 comments on commit a2093da

Please sign in to comment.