Some work towards being able to build two JITs together

This will be useful for testing/debugging, but not there yet.
This commit is contained in:
Henrik Rydgard 2014-12-13 21:11:36 +01:00
parent 8ad1ea4c84
commit 05a8e2e35d
28 changed files with 114 additions and 72 deletions

View file

@ -1277,6 +1277,7 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/Loaders.h
Core/MIPS/JitCommon/JitCommon.cpp
Core/MIPS/JitCommon/JitCommon.h
Core/MIPS/JitCommon/NativeJit.h
Core/MIPS/JitCommon/JitBlockCache.cpp
Core/MIPS/JitCommon/JitBlockCache.h
Core/MIPS/MIPS.cpp

View file

@ -330,12 +330,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="MIPS\ARM\ArmRegCacheFPU.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="MIPS\ARM\ArmRegCacheFPU.cpp" />
<ClCompile Include="MIPS\ARM\ArmJit.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@ -595,12 +590,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="MIPS\ARM\ArmRegCacheFPU.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="MIPS\ARM\ArmRegCacheFPU.h" />
<ClInclude Include="MIPS\JitCommon\JitBlockCache.h" />
<ClInclude Include="MIPS\JitCommon\JitCommon.h" />
<ClInclude Include="MIPS\JitCommon\NativeJit.h" />
@ -673,4 +663,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View file

@ -69,6 +69,8 @@ void DisassembleArm(const u8 *data, int size);
namespace MIPSComp {
using namespace ArmJitConstants;
void ArmJit::GenerateFixedCode()
{
enterCode = AlignCode16();

View file

@ -19,6 +19,7 @@
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/MIPS/ARM/ArmJit.h"
#include "Core/MIPS/ARM/ArmRegCache.h"
#include "Common/CPUDetect.h"
using namespace MIPSAnalyst;
@ -45,6 +46,7 @@ using namespace MIPSAnalyst;
namespace MIPSComp
{
using namespace ArmGen;
using namespace ArmJitConstants;
static u32 EvalOr(u32 a, u32 b) { return a | b; }
static u32 EvalEor(u32 a, u32 b) { return a ^ b; }

View file

@ -55,6 +55,7 @@ using namespace MIPSAnalyst;
namespace MIPSComp
{
using namespace ArmGen;
using namespace ArmJitConstants;
void ArmJit::BranchRSRTComp(MIPSOpcode op, ArmGen::CCFlags cc, bool likely)
{

View file

@ -47,6 +47,7 @@
namespace MIPSComp
{
using namespace ArmGen;
using namespace ArmJitConstants;
void ArmJit::Comp_FPU3op(MIPSOpcode op)
{

View file

@ -67,6 +67,7 @@
namespace MIPSComp
{
using namespace ArmGen;
using namespace ArmJitConstants;
void ArmJit::SetR0ToEffectiveAddress(MIPSGPReg rs, s16 offset) {
Operand2 op2;

View file

@ -56,6 +56,7 @@
namespace MIPSComp
{
using namespace ArmGen;
using namespace ArmJitConstants;
// Vector regs can overlap in all sorts of swizzled ways.
// This does allow a single overlap in sregs[i].

View file

@ -43,6 +43,7 @@
#include "Core/MIPS/ARM/ArmJit.h"
#include "Core/MIPS/ARM/ArmRegCache.h"
#include "Core/MIPS/ARM/ArmRegCacheFPU.h"
#include "Core/MIPS/ARM/ArmCompVFPUNEONUtil.h"
// TODO: Somehow #ifdef away on ARMv5eabi, without breaking the linker.
@ -69,6 +70,7 @@
namespace MIPSComp {
using namespace ArmGen;
using namespace ArmJitConstants;
static const float minus_one = -1.0f;
static const float one = 1.0f;

View file

@ -64,7 +64,8 @@
namespace MIPSComp {
using namespace ArmGen;
using namespace ArmGen;
using namespace ArmJitConstants;
static const float minus_one = -1.0f;
static const float one = 1.0f;

View file

@ -17,17 +17,21 @@
#include "base/logging.h"
#include "Common/ChunkFile.h"
#include "Core/Reporting.h"
#include "Core/Config.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/Debugger/SymbolMap.h"
#include "Core/MemMap.h"
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSCodeUtils.h"
#include "Core/MIPS/MIPSInt.h"
#include "Core/MIPS/MIPSTables.h"
#include "Core/HLE/ReplaceTables.h"
#include "Core/MIPS/ARM/ArmRegCache.h"
#include "Core/MIPS/ARM/ArmRegCacheFPU.h"
#include "ArmRegCache.h"
#include "ArmJit.h"
@ -35,6 +39,8 @@
#include "ext/disarm.h"
using namespace ArmJitConstants;
void DisassembleArm(const u8 *data, int size) {
char temp[256];
for (int i = 0; i < size; i += 4) {
@ -61,10 +67,10 @@ void DisassembleArm(const u8 *data, int size) {
namespace MIPSComp
{
using namespace ArmGen;
using namespace ArmGen;
using namespace ArmJitConstants;
ArmJit::ArmJit(MIPSState *mips) : blocks(mips, this), gpr(mips, &js, &jo), fpr(mips, &js, &jo), mips_(mips)
{
ArmJit::ArmJit(MIPSState *mips) : blocks(mips, this), gpr(mips, &js, &jo), fpr(mips, &js, &jo), mips_(mips) {
logBlocks = 0;
dontLogBlocks = 0;
blocks.Init();
@ -76,6 +82,9 @@ ArmJit::ArmJit(MIPSState *mips) : blocks(mips, this), gpr(mips, &js, &jo), fpr(m
js.startDefaultPrefix = mips_->HasDefaultPrefix();
}
ArmJit::~ArmJit() {
}
void ArmJit::DoState(PointerWrap &p)
{
auto s = p.Section("Jit", 1, 2);
@ -283,6 +292,11 @@ const u8 *ArmJit::DoJit(u32 em_address, JitBlock *b)
{
gpr.SetCompilerPC(js.compilerPC); // Let it know for log messages
MIPSOpcode inst = Memory::Read_Opcode_JIT(js.compilerPC);
MIPSInfo info = MIPSGetInfo(inst);
if (info & IS_VFPU) {
logBlocks = 1;
}
js.downcountAmount += MIPSGetInstructionCycleEstimate(inst);
MIPSCompileOp(inst);
@ -374,6 +388,7 @@ void ArmJit::Comp_RunBlock(MIPSOpcode op)
}
bool ArmJit::ReplaceJalTo(u32 dest) {
#ifdef ARM
MIPSOpcode op(Memory::Read_Opcode_JIT(dest));
if (!MIPS_IS_REPLACEMENT(op.encoding))
return false;
@ -420,6 +435,7 @@ bool ArmJit::ReplaceJalTo(u32 dest) {
// Add a trigger so that if the inlined code changes, we invalidate this block.
blocks.ProxyBlock(js.blockStart, dest, symbolMap.GetFunctionSize(dest) / sizeof(u32), GetCodePtr());
#endif
return true;
}

View file

@ -18,11 +18,13 @@
#pragma once
#include "Common/CPUDetect.h"
#include "Common/ARMEmitter.h"
#include "Core/MIPS/JitCommon/JitState.h"
#include "Core/MIPS/JitCommon/JitBlockCache.h"
#include "Core/MIPS/ARM/ArmAsm.h"
#include "Core/MIPS/ARM/ArmRegCache.h"
#include "Core/MIPS/ARM/ArmRegCacheFPU.h"
#include "Core/MIPS/ARM/ArmAsm.h"
#include "Core/MIPS/MIPSVFPUUtils.h"
#ifndef offsetof
#include "stddef.h"
@ -44,7 +46,7 @@ struct ArmJitOptions
continueJumps = false;
continueMaxInstructions = 300;
useNEONVFPU = false; // true
useNEONVFPU = true; // true
if (!cpu_info.bNEON)
useNEONVFPU = false;
}
@ -65,6 +67,7 @@ class ArmJit : public ArmGen::ARMXCodeBlock
{
public:
ArmJit(MIPSState *mips);
virtual ~ArmJit();
void DoState(PointerWrap &p);
static void DoDummyState(PointerWrap &p);
@ -324,8 +327,5 @@ public:
const u8 *breakpointBailout;
};
typedef void (ArmJit::*MIPSCompileFunc)(MIPSOpcode opcode);
typedef int (ArmJit::*MIPSReplaceFunc)();
} // namespace MIPSComp

View file

@ -27,6 +27,7 @@
#endif
using namespace ArmGen;
using namespace ArmJitConstants;
ArmRegCache::ArmRegCache(MIPSState *mips, MIPSComp::JitState *js, MIPSComp::ArmJitOptions *jo) : mips_(mips), js_(js), jo_(jo) {
}

View file

@ -21,30 +21,18 @@
#include "../MIPSAnalyst.h"
#include "ArmEmitter.h"
#define CTXREG (R10)
#define MEMBASEREG (R11)
#define SCRATCHREG1 (R0)
#define SCRATCHREG2 (R14)
#define DOWNCOUNTREG (R7)
namespace ArmJitConstants {
// R1 to R6: mapped MIPS regs
// R8 = flags (maybe we could do better here?)
// R9 = code pointers
// R10 = MIPS context
// R11 = base pointer
// R14 = scratch (actually LR)
const ArmGen::ARMReg CTXREG = ArmGen::R10;
const ArmGen::ARMReg MEMBASEREG = ArmGen::R11;
const ArmGen::ARMReg SCRATCHREG1 = ArmGen::R0;
const ArmGen::ARMReg SCRATCHREG2 = ArmGen::R14;
const ArmGen::ARMReg DOWNCOUNTREG = ArmGen::R7;
enum {
TOTAL_MAPPABLE_MIPSREGS = 36,
};
typedef int MIPSReg;
struct RegARM {
MIPSGPReg mipsReg; // if -1, no mipsreg attached.
bool isDirty; // Should the register be written back?
};
enum RegMIPSLoc {
ML_IMM,
ML_ARMREG,
@ -55,9 +43,32 @@ enum RegMIPSLoc {
ML_MEM,
};
// Initing is the default so the flag is reversed.
enum {
MAP_DIRTY = 1,
MAP_NOINIT = 2 | MAP_DIRTY,
};
}
// R1 to R6: mapped MIPS regs
// R8 = flags (maybe we could do better here?)
// R9 = code pointers
// R10 = MIPS context
// R11 = base pointer
// R14 = scratch (actually LR)
typedef int MIPSReg;
struct RegARM {
MIPSGPReg mipsReg; // if -1, no mipsreg attached.
bool isDirty; // Should the register be written back?
};
struct RegMIPS {
// Where is this MIPS register?
RegMIPSLoc loc;
ArmJitConstants::RegMIPSLoc loc;
// Data (only one of these is used, depending on loc. Could make a union).
u32 imm;
ArmGen::ARMReg reg; // reg index
@ -65,14 +76,6 @@ struct RegMIPS {
// If loc == ML_MEM, it's back in its location in the CPU context struct.
};
#undef MAP_DIRTY
#undef MAP_NOINIT
// Initing is the default so the flag is reversed.
enum {
MAP_DIRTY = 1,
MAP_NOINIT = 2 | MAP_DIRTY,
};
namespace MIPSComp {
struct ArmJitOptions;
struct JitState;
@ -140,7 +143,7 @@ private:
enum {
NUM_ARMREG = 16,
NUM_MIPSREG = TOTAL_MAPPABLE_MIPSREGS,
NUM_MIPSREG = ArmJitConstants::TOTAL_MAPPABLE_MIPSREGS,
};
RegARM ar[NUM_ARMREG];

View file

@ -25,6 +25,7 @@
#include "Core/MIPS/MIPSTables.h"
using namespace ArmGen;
using namespace ArmJitConstants;
ArmRegCacheFPU::ArmRegCacheFPU(MIPSState *mips, MIPSComp::JitState *js, MIPSComp::ArmJitOptions *jo) : mips_(mips), vr(mr + 32), js_(js), jo_(jo), initialReady(false) {
if (cpu_info.bNEON) {

View file

@ -25,6 +25,8 @@
#include "Core/MIPS/MIPSVFPUUtils.h"
#include "Common/ArmEmitter.h"
namespace ArmJitConstants {
enum {
NUM_TEMPS = 16,
TEMP0 = 32 + 128,
@ -42,6 +44,8 @@ enum {
MAP_FORCE_HIGH = 128, // Only map Q8-Q15
};
}
struct FPURegARM {
int mipsReg; // if -1, no mipsreg attached.
bool isDirty; // Should the register be written back?
@ -58,7 +62,7 @@ struct FPURegQuad {
struct FPURegMIPS {
// Where is this MIPS register?
RegMIPSLoc loc;
ArmJitConstants::RegMIPSLoc loc;
// Data (only one of these is used, depending on loc. Could make a union).
u32 reg;
int lane;
@ -193,7 +197,7 @@ private:
// are individually mappable though.
MAX_ARMFPUREG = 32,
MAX_ARMQUADS = 16,
NUM_MIPSFPUREG = TOTAL_MAPPABLE_MIPSFPUREGS,
NUM_MIPSFPUREG = ArmJitConstants::TOTAL_MAPPABLE_MIPSFPUREGS,
};
FPURegARM ar[MAX_ARMFPUREG];

View file

@ -71,6 +71,7 @@ op_agent_t agent;
#ifdef ARM
using namespace ArmGen;
using namespace ArmJitConstants;
#elif defined(_M_X64) || defined(_M_IX86)
using namespace Gen;
#endif

View file

@ -42,4 +42,8 @@ typedef MIPSComp::Jit FakeJit;
namespace MIPSComp {
extern NativeJit *jit;
typedef void (NativeJit::*MIPSCompileFunc)(MIPSOpcode opcode);
typedef int (NativeJit::*MIPSReplaceFunc)();
}

View file

@ -32,6 +32,7 @@
#include "Core/MIPS/x86/Jit.h"
using namespace Gen;
using namespace X64JitConstants;
//TODO - make an option
//#if _DEBUG

View file

@ -44,6 +44,7 @@ using namespace MIPSAnalyst;
namespace MIPSComp
{
using namespace Gen;
using namespace X64JitConstants;
static bool HasLowSubregister(OpArg arg) {
#ifndef _M_X64

View file

@ -43,7 +43,9 @@
#define DISABLE { Comp_Generic(op); return; }
namespace MIPSComp {
using namespace Gen;
using namespace X64JitConstants;
void Jit::CompFPTriArith(MIPSOpcode op, void (XEmitter::*arith)(X64Reg reg, OpArg), bool orderMatters) {
int ft = _FT;

View file

@ -54,6 +54,7 @@
namespace MIPSComp
{
using namespace Gen;
using namespace X64JitConstants;
static const float one = 1.0f;
static const float minus_one = -1.0f;

View file

@ -19,6 +19,7 @@
#include "Common/CommonTypes.h"
#include "Common/Thunk.h"
#include "Common/x64Emitter.h"
#include "Core/MIPS/x86/Asm.h"
#if defined(ARM)
@ -313,8 +314,5 @@ private:
friend class JitSafeMemFuncs;
};
typedef void (Jit::*MIPSCompileFunc)(MIPSOpcode opcode);
typedef int (Jit::*MIPSReplaceFunc)();
} // namespace MIPSComp

View file

@ -18,12 +18,13 @@
#pragma once
#include <vector>
#include "Core/MIPS/x86/Jit.h"
class ThunkManager;
namespace MIPSComp {
class Jit;
class JitSafeMem {
public:
JitSafeMem(Jit *jit, MIPSGPReg raddr, s32 offset, u32 alignMask = 0xFFFFFFFF);

View file

@ -17,6 +17,7 @@
#include <cstring>
#include "Common/x64Emitter.h"
#include "Core/Reporting.h"
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSTables.h"
@ -26,6 +27,7 @@
#include "Core/MIPS/x86/RegCache.h"
using namespace Gen;
using namespace X64JitConstants;
static const int allocationOrder[] =
{

View file

@ -21,22 +21,23 @@
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSAnalyst.h"
namespace X64JitConstants {
#ifdef _M_X64
#define NUM_X_REGS 16
#elif _M_IX86
#define NUM_X_REGS 8
#endif
#define NUM_MIPS_GPRS 36
#ifdef _M_X64
#define CTXREG R14
const Gen::X64Reg CTXREG = Gen::R14;
#else
#define CTXREG EBP
const Gen::X64Reg CTXREG = Gen::EBP;
#endif
// This must be one of EAX, EBX, ECX, EDX as they have 8-bit subregisters.
#define TEMPREG EAX
// This must be one of EAX, EBX, ECX, EDX as they have 8-bit subregisters.
const Gen::X64Reg TEMPREG = Gen::EAX;
const int NUM_MIPS_GPRS = 36;
#ifdef _M_X64
const int NUM_X_REGS = 16;
#elif _M_IX86
const int NUM_X_REGS = 8;
#endif
}
struct MIPSCachedReg {
Gen::OpArg location;
@ -52,8 +53,8 @@ struct X64CachedReg {
};
struct GPRRegCacheState {
MIPSCachedReg regs[NUM_MIPS_GPRS];
X64CachedReg xregs[NUM_X_REGS];
MIPSCachedReg regs[X64JitConstants::NUM_MIPS_GPRS];
X64CachedReg xregs[X64JitConstants::NUM_X_REGS];
};
namespace MIPSComp {
@ -118,8 +119,8 @@ private:
Gen::X64Reg FindBestToSpill(bool unusedOnly, bool *clobbered);
const int *GetAllocationOrder(int &count);
MIPSCachedReg regs[NUM_MIPS_GPRS];
X64CachedReg xregs[NUM_X_REGS];
MIPSCachedReg regs[X64JitConstants::NUM_MIPS_GPRS];
X64CachedReg xregs[X64JitConstants::NUM_X_REGS];
Gen::XEmitter *emit;
MIPSComp::JitState *js_;

View file

@ -26,6 +26,7 @@
#include "Core/MIPS/x86/RegCacheFPU.h"
using namespace Gen;
using namespace X64JitConstants;
float FPURegCache::tempValues[NUM_TEMPS];

View file

@ -216,6 +216,8 @@ bool TestArmEmitter() {
MIPSAnalyst::AnalysisResults results;
memset(&results, 0, sizeof(results));
using namespace ArmJitConstants;
fpr.Start(results);
fpr.QMapReg(C000, V_Quad, MAP_DIRTY);
fpr.QMapReg(C010, V_Quad, MAP_DIRTY);