Merge branch '6663'

Should fix some fastmem-related bugs and possibly improve performance a bit.
This commit is contained in:
comex
2013-10-04 21:19:40 -04:00
45 changed files with 276 additions and 603 deletions
-1
View File
@@ -37,7 +37,6 @@ else()
if(NOT _M_GENERIC) #X86
set(SRCS ${SRCS}
Src/x64FPURoundMode.cpp
Src/x64Thunk.cpp
)
endif()
set(SRCS ${SRCS} Src/x64CPUDetect.cpp)
-2
View File
@@ -217,7 +217,6 @@
<ClCompile Include="Src\x64CPUDetect.cpp" />
<ClCompile Include="Src\x64Emitter.cpp" />
<ClCompile Include="Src\x64FPURoundMode.cpp" />
<ClCompile Include="Src\x64Thunk.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\Atomic.h" />
@@ -263,7 +262,6 @@
<ClInclude Include="Src\SymbolDB.h" />
<ClInclude Include="Src\SysConf.h" />
<ClInclude Include="Src\Thread.h" />
<ClInclude Include="Src\Thunk.h" />
<ClInclude Include="Src\Timer.h" />
<ClInclude Include="Src\x64ABI.h" />
<ClInclude Include="Src\x64Analyzer.h" />
@@ -47,7 +47,6 @@
<ClCompile Include="Src\x64ABI.cpp" />
<ClCompile Include="Src\x64CPUDetect.cpp" />
<ClCompile Include="Src\x64FPURoundMode.cpp" />
<ClCompile Include="Src\x64Thunk.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\Atomic.h" />
@@ -84,7 +83,6 @@
<ClInclude Include="Src\SymbolDB.h" />
<ClInclude Include="Src\SysConf.h" />
<ClInclude Include="Src\Thread.h" />
<ClInclude Include="Src\Thunk.h" />
<ClInclude Include="Src\Timer.h" />
<ClInclude Include="Src\x64Analyzer.h" />
<ClInclude Include="Src\x64Emitter.h" />
-46
View File
@@ -1,46 +0,0 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#ifndef _THUNK_H_
#define _THUNK_H_
#include <map>
#include "Common.h"
#include "x64Emitter.h"
// This simple class creates a wrapper around a C/C++ function that saves all fp state
// before entering it, and restores it upon exit. This is required to be able to selectively
// call functions from generated code, without inflicting the performance hit and increase
// of complexity that it means to protect the generated code from this problem.
// This process is called thunking.
// There will only ever be one level of thunking on the stack, plus,
// we don't want to pollute the stack, so we store away regs somewhere global.
// NOT THREAD SAFE. This may only be used from the CPU thread.
// Any other thread using this stuff will be FATAL.
class ThunkManager : public Gen::XCodeBlock
{
std::map<void *, const u8 *> thunks;
const u8 *save_regs;
const u8 *load_regs;
public:
ThunkManager() {
Init();
}
~ThunkManager() {
Shutdown();
}
void *ProtectFunction(void *function, int num_params);
private:
void Init();
void Shutdown();
void Reset();
};
#endif // _THUNK_H_
+80
View File
@@ -57,6 +57,86 @@ void XEmitter::ABI_RestoreStack(unsigned int frameSize, bool noProlog) {
}
}
void XEmitter::ABI_PushRegistersAndAdjustStack(u32 mask, bool noProlog)
{
int regSize =
#ifdef _M_X64
8;
#else
4;
#endif
int shadow = 0;
#if defined(_WIN32) && defined(_M_X64)
shadow = 0x20;
#endif
int count = 0;
for (int r = 0; r < 16; r++)
{
if (mask & (1 << r))
{
PUSH((X64Reg) r);
count++;
}
}
int size = ((noProlog ? -regSize : 0) - (count * regSize)) & 0xf;
for (int x = 0; x < 16; x++)
{
if (mask & (1 << (16 + x)))
size += 16;
}
size += shadow;
if (size)
SUB(regSize * 8, R(RSP), size >= 0x80 ? Imm32(size) : Imm8(size));
int offset = shadow;
for (int x = 0; x < 16; x++)
{
if (mask & (1 << (16 + x)))
{
MOVAPD(MDisp(RSP, offset), (X64Reg) x);
offset += 16;
}
}
}
void XEmitter::ABI_PopRegistersAndAdjustStack(u32 mask, bool noProlog)
{
int regSize =
#ifdef _M_X64
8;
#else
4;
#endif
int size = 0;
#if defined(_WIN32) && defined(_M_X64)
size += 0x20;
#endif
for (int x = 0; x < 16; x++)
{
if (mask & (1 << (16 + x)))
{
MOVAPD((X64Reg) x, MDisp(RSP, size));
size += 16;
}
}
int count = 0;
for (int r = 0; r < 16; r++)
{
if (mask & (1 << r))
count++;
}
size += ((noProlog ? -regSize : 0) - (count * regSize)) & 0xf;
if (size)
ADD(regSize * 8, R(RSP), size >= 0x80 ? Imm32(size) : Imm8(size));
for (int r = 15; r >= 0; r--)
{
if (mask & (1 << r))
{
POP((X64Reg) r);
}
}
}
#ifdef _M_IX86 // All32
// Shared code between Win32 and Unix32
+12 -1
View File
@@ -43,6 +43,8 @@
// 32-bit bog standard cdecl, shared between linux and windows
// MacOSX 32-bit is same as System V with a few exceptions that we probably don't care much about.
#define ALL_CALLEE_SAVED ((1 << EAX) | (1 << ECX) | (1 << EDX))
#else // 64 bit calling convention
#ifdef _WIN32 // 64-bit Windows - the really exotic calling convention
@@ -52,7 +54,12 @@
#define ABI_PARAM3 R8
#define ABI_PARAM4 R9
#else //64-bit Unix (hopefully MacOSX too)
#define ABI_ALL_CALLEE_SAVED ((1 << RAX) | (1 << RCX) | (1 << RDX) | (1 << R8) | \
(1 << R9) | (1 << R10) | (1 << R11) | \
(1 << XMM0) | (1 << XMM1) | (1 << XMM2) | (1 << XMM3) | \
(1 << XMM4) | (1 << XMM5))
#else //64-bit Unix / OS X
#define ABI_PARAM1 RDI
#define ABI_PARAM2 RSI
@@ -61,6 +68,10 @@
#define ABI_PARAM5 R8
#define ABI_PARAM6 R9
#define ABI_ALL_CALLEE_SAVED ((1 << RAX) | (1 << RCX) | (1 << RDX) | (1 << RDI) | \
(1 << RSI) | (1 << R8) | (1 << R9) | (1 << R10) | (1 << R11) | \
0xffff0000 /* xmm0..15 */)
#endif // WIN32
#endif // X86
-68
View File
@@ -1634,74 +1634,6 @@ void XEmitter::___CallCdeclImport6(void* impptr, u32 arg0, u32 arg1, u32 arg2, u
CALLptr(M(impptr));
}
void XEmitter::PushRegistersAndAlignStack(u32 mask)
{
int shadow = 0;
#ifdef _WIN32
shadow = 0x20;
#endif
int count = 0;
for (int r = 0; r < 16; r++)
{
if (mask & (1 << r))
{
PUSH((X64Reg) r);
count++;
}
}
int size = (count & 1) ? 0 : 8;
for (int x = 0; x < 16; x++)
{
if (mask & (1 << (16 + x)))
size += 16;
}
size += shadow;
if (size)
SUB(64, R(RSP), size >= 0x80 ? Imm32(size) : Imm8(size));
int offset = shadow;
for (int x = 0; x < 16; x++)
{
if (mask & (1 << (16 + x)))
{
MOVAPD(MDisp(RSP, offset), (X64Reg) x);
offset += 16;
}
}
}
void XEmitter::PopRegistersAndAlignStack(u32 mask)
{
int size = 0;
#ifdef _WIN32
size += 0x20;
#endif
for (int x = 0; x < 16; x++)
{
if (mask & (1 << (16 + x)))
{
MOVAPD((X64Reg) x, MDisp(RSP, size));
size += 16;
}
}
int count = 0;
for (int r = 0; r < 16; r++)
{
if (mask & (1 << r))
count++;
}
size += (count & 1) ? 0 : 8;
if (size)
ADD(64, R(RSP), size >= 0x80 ? Imm32(size) : Imm8(size));
for (int r = 15; r >= 0; r--)
{
if (mask & (1 << r))
{
POP((X64Reg) r);
}
}
}
#endif
}
+4 -3
View File
@@ -646,6 +646,10 @@ public:
void ABI_PushAllCalleeSavedRegsAndAdjustStack();
void ABI_PopAllCalleeSavedRegsAndAdjustStack();
// A more flexible version of the above.
void ABI_PushRegistersAndAdjustStack(u32 mask, bool noProlog);
void ABI_PopRegistersAndAdjustStack(u32 mask, bool noProlog);
unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize, bool noProlog = false);
void ABI_AlignStack(unsigned int frameSize, bool noProlog = false);
void ABI_RestoreStack(unsigned int frameSize, bool noProlog = false);
@@ -691,9 +695,6 @@ public:
#define DECLARE_IMPORT(x) extern "C" void *__imp_##x
void PushRegistersAndAlignStack(u32 mask);
void PopRegistersAndAlignStack(u32 mask);
#endif
}; // class XEmitter
-121
View File
@@ -1,121 +0,0 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include <map>
#include "Common.h"
#include "MemoryUtil.h"
#include "x64ABI.h"
#include "Thunk.h"
#define THUNK_ARENA_SIZE 1024*1024*1
namespace
{
static u8 GC_ALIGNED32(saved_fp_state[16 * 4 * 4]);
static u8 GC_ALIGNED32(saved_gpr_state[16 * 8]);
static u16 saved_mxcsr;
} // namespace
using namespace Gen;
void ThunkManager::Init()
{
AllocCodeSpace(THUNK_ARENA_SIZE);
save_regs = GetCodePtr();
for (int i = 2; i < ABI_GetNumXMMRegs(); i++)
MOVAPS(M(saved_fp_state + i * 16), (X64Reg)(XMM0 + i));
STMXCSR(M(&saved_mxcsr));
#ifdef _M_X64
MOV(64, M(saved_gpr_state + 0 ), R(RCX));
MOV(64, M(saved_gpr_state + 8 ), R(RDX));
MOV(64, M(saved_gpr_state + 16), R(R8) );
MOV(64, M(saved_gpr_state + 24), R(R9) );
MOV(64, M(saved_gpr_state + 32), R(R10));
MOV(64, M(saved_gpr_state + 40), R(R11));
#ifndef _WIN32
MOV(64, M(saved_gpr_state + 48), R(RSI));
MOV(64, M(saved_gpr_state + 56), R(RDI));
#endif
MOV(64, M(saved_gpr_state + 64), R(RBX));
#else
MOV(32, M(saved_gpr_state + 0 ), R(RCX));
MOV(32, M(saved_gpr_state + 4 ), R(RDX));
#endif
RET();
load_regs = GetCodePtr();
LDMXCSR(M(&saved_mxcsr));
for (int i = 2; i < ABI_GetNumXMMRegs(); i++)
MOVAPS((X64Reg)(XMM0 + i), M(saved_fp_state + i * 16));
#ifdef _M_X64
MOV(64, R(RCX), M(saved_gpr_state + 0 ));
MOV(64, R(RDX), M(saved_gpr_state + 8 ));
MOV(64, R(R8) , M(saved_gpr_state + 16));
MOV(64, R(R9) , M(saved_gpr_state + 24));
MOV(64, R(R10), M(saved_gpr_state + 32));
MOV(64, R(R11), M(saved_gpr_state + 40));
#ifndef _WIN32
MOV(64, R(RSI), M(saved_gpr_state + 48));
MOV(64, R(RDI), M(saved_gpr_state + 56));
#endif
MOV(64, R(RBX), M(saved_gpr_state + 64));
#else
MOV(32, R(RCX), M(saved_gpr_state + 0 ));
MOV(32, R(RDX), M(saved_gpr_state + 4 ));
#endif
RET();
}
void ThunkManager::Reset()
{
thunks.clear();
ResetCodePtr();
}
void ThunkManager::Shutdown()
{
Reset();
FreeCodeSpace();
}
void *ThunkManager::ProtectFunction(void *function, int num_params)
{
std::map<void *, const u8 *>::iterator iter;
iter = thunks.find(function);
if (iter != thunks.end())
return (void *)iter->second;
if (!region)
PanicAlert("Trying to protect functions before the emu is started. Bad bad bad.");
const u8 *call_point = GetCodePtr();
#ifdef _M_X64
// Make sure to align stack.
ABI_AlignStack(0, true);
CALL((void*)save_regs);
CALL((void*)function);
CALL((void*)load_regs);
ABI_RestoreStack(0, true);
RET();
#else
CALL((void*)save_regs);
// Since parameters are in the previous stack frame, not in registers, this takes some
// trickery : we simply re-push the parameters. might not be optimal, but that doesn't really
// matter.
ABI_AlignStack(num_params * 4, true);
unsigned int alignedSize = ABI_GetAlignedFrameSize(num_params * 4, true);
for (int i = 0; i < num_params; i++) {
// ESP is changing, so we do not need i
PUSH(32, MDisp(ESP, alignedSize));
}
CALL(function);
ABI_RestoreStack(num_params * 4, true);
CALL((void*)load_regs);
RET();
#endif
thunks[function] = call_point;
return (void *)call_point;
}
-1
View File
@@ -409,7 +409,6 @@ void SConfig::LoadSettings()
ini.Get("Core", "SlotB", (int*)&m_EXIDevice[1], EXIDEVICE_NONE);
ini.Get("Core", "SerialPort1", (int*)&m_EXIDevice[2], EXIDEVICE_NONE);
ini.Get("Core", "BBA_MAC", &m_bba_mac);
ini.Get("Core", "ProfiledReJIT",&m_LocalCoreStartupParameter.bJITProfiledReJIT, false);
ini.Get("Core", "TimeProfiling",&m_LocalCoreStartupParameter.bJITILTimeProfiling, false);
ini.Get("Core", "OutputIR", &m_LocalCoreStartupParameter.bJITILOutputIR, false);
char sidevicenum[16];
+1 -1
View File
@@ -28,7 +28,7 @@ SCoreStartupParameter::SCoreStartupParameter()
bJITLoadStoreFloatingOff(false), bJITLoadStorePairedOff(false),
bJITFloatingPointOff(false), bJITIntegerOff(false),
bJITPairedOff(false), bJITSystemRegistersOff(false),
bJITBranchOff(false), bJITProfiledReJIT(false),
bJITBranchOff(false),
bJITILTimeProfiling(false), bJITILOutputIR(false),
bEnableFPRF(false),
bCPUThread(true), bDSPThread(false), bDSPHLE(true),
-1
View File
@@ -111,7 +111,6 @@ struct SCoreStartupParameter
bool bJITPairedOff;
bool bJITSystemRegistersOff;
bool bJITBranchOff;
bool bJITProfiledReJIT;
bool bJITILTimeProfiling;
bool bJITILOutputIR;
-1
View File
@@ -3,7 +3,6 @@
// Refer to the license.txt file included.
#include "Common.h"
#include "Thunk.h"
#include "../Core.h"
#include "HW.h"
#include "../PowerPC/PowerPC.h"
+4 -2
View File
@@ -12,7 +12,6 @@
#include "Common.h"
#include "x64Emitter.h"
#include "x64ABI.h"
#include "Thunk.h"
#include "../../HLE/HLE.h"
#include "../../Core.h"
#include "../../PatchEngine.h"
@@ -552,7 +551,10 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
{
js.fifoBytesThisBlock -= 32;
MOV(32, M(&PC), Imm32(jit->js.compilerPC)); // Helps external systems know which instruction triggered the write
ABI_CallFunction(thunks.ProtectFunction((void *)&GPFifo::CheckGatherPipe, 0));
u32 registersInUse = RegistersInUse();
ABI_PushRegistersAndAdjustStack(registersInUse, false);
ABI_CallFunction((void *)&GPFifo::CheckGatherPipe);
ABI_PopRegistersAndAdjustStack(registersInUse, false);
}
u32 function = HLE::GetFunctionIndex(ops[i].address);
-2
View File
@@ -234,6 +234,4 @@ public:
void icbi(UGeckoInstruction inst);
};
void ProfiledReJit();
#endif // _JIT64_H
@@ -3,7 +3,6 @@
// Refer to the license.txt file included.
#include "Common.h"
#include "Thunk.h"
#include "../../Core.h"
#include "../PowerPC.h"
@@ -6,7 +6,6 @@
// Should give a very noticable speed boost to paired single heavy code.
#include "Common.h"
#include "Thunk.h"
#include "../PowerPC.h"
#include "../../Core.h"
@@ -120,21 +119,20 @@ void Jit64::lXXx(UGeckoInstruction inst)
// do our job at first
s32 offset = (s32)(s16)inst.SIMM_16;
gpr.Lock(d);
SafeLoadToEAX(gpr.R(a), accessSize, offset, RegistersInUse(), signExtend);
gpr.KillImmediate(d, false, true);
MOV(32, gpr.R(d), R(EAX));
gpr.UnlockAll();
gpr.BindToRegister(d, false, true);
SafeLoadToReg(gpr.RX(d), gpr.R(a), accessSize, offset, RegistersInUse(), signExtend);
gpr.Flush(FLUSH_ALL);
fpr.Flush(FLUSH_ALL);
// if it's still 0, we can wait until the next event
TEST(32, R(EAX), R(EAX));
TEST(32, gpr.R(d), gpr.R(d));
FixupBranch noIdle = J_CC(CC_NZ);
u32 registersInUse = RegistersInUse();
ABI_PushRegistersAndAdjustStack(registersInUse, false);
ABI_CallFunctionC((void *)&PowerPC::OnIdle, PowerPC::ppcState.gpr[a] + (s32)(s16)inst.SIMM_16);
ABI_PopRegistersAndAdjustStack(registersInUse, false);
// ! we must continue executing of the loop after exception handling, maybe there is still 0 in r0
//MOV(32, M(&PowerPC::ppcState.pc), Imm32(js.compilerPC));
WriteExceptionExit();
@@ -174,18 +172,32 @@ void Jit64::lXXx(UGeckoInstruction inst)
{
if ((inst.OPCD != 31) && gpr.R(a).IsImm())
{
opAddress = Imm32((u32)gpr.R(a).offset + (s32)inst.SIMM_16);
u32 val = (u32)gpr.R(a).offset + (s32)inst.SIMM_16;
opAddress = Imm32(val);
if (update)
gpr.SetImmediate32(a, val);
}
else if ((inst.OPCD == 31) && gpr.R(a).IsImm() && gpr.R(b).IsImm())
{
opAddress = Imm32((u32)gpr.R(a).offset + (u32)gpr.R(b).offset);
u32 val = (u32)gpr.R(a).offset + (u32)gpr.R(b).offset;
opAddress = Imm32(val);
if (update)
gpr.SetImmediate32(a, val);
}
else
{
gpr.FlushLockX(ABI_PARAM1);
opAddress = R(ABI_PARAM1);
MOV(32, opAddress, gpr.R(a));
if (update || (inst.OPCD != 31 && inst.SIMM_16 == 0))
{
gpr.BindToRegister(a, true, update);
opAddress = gpr.R(a);
}
else
{
gpr.FlushLockX(ABI_PARAM1);
opAddress = R(ABI_PARAM1);
MOV(32, opAddress, gpr.R(a));
}
if (inst.OPCD == 31)
ADD(32, opAddress, gpr.R(b));
else
@@ -193,29 +205,9 @@ void Jit64::lXXx(UGeckoInstruction inst)
}
}
SafeLoadToEAX(opAddress, accessSize, 0, RegistersInUse(), signExtend);
// We must flush immediate values from the following registers because
// they may change at runtime if no MMU exception has been raised
gpr.KillImmediate(d, true, true);
if (update)
{
gpr.Lock(a);
gpr.BindToRegister(a, true, true);
}
MEMCHECK_START
if (update)
{
if (inst.OPCD == 31)
ADD(32, gpr.R(a), gpr.R(b));
else
ADD(32, gpr.R(a), Imm32((u32)(s32)inst.SIMM_16));
}
MOV(32, gpr.R(d), R(EAX));
MEMCHECK_END
gpr.Lock(a, b, d);
gpr.BindToRegister(d, false, true);
SafeLoadToReg(gpr.RX(d), opAddress, accessSize, 0, RegistersInUse(), signExtend);
gpr.UnlockAll();
gpr.UnlockAllX();
@@ -318,12 +310,15 @@ void Jit64::stX(UGeckoInstruction inst)
else
{
MOV(32, M(&PC), Imm32(jit->js.compilerPC)); // Helps external systems know which instruction triggered the write
u32 registersInUse = RegistersInUse();
ABI_PushRegistersAndAdjustStack(registersInUse, false);
switch (accessSize)
{
case 32: ABI_CallFunctionAC(thunks.ProtectFunction(true ? ((void *)&Memory::Write_U32) : ((void *)&Memory::Write_U32_Swap), 2), gpr.R(s), addr); break;
case 16: ABI_CallFunctionAC(thunks.ProtectFunction(true ? ((void *)&Memory::Write_U16) : ((void *)&Memory::Write_U16_Swap), 2), gpr.R(s), addr); break;
case 8: ABI_CallFunctionAC(thunks.ProtectFunction((void *)&Memory::Write_U8, 2), gpr.R(s), addr); break;
case 32: ABI_CallFunctionAC(true ? ((void *)&Memory::Write_U32) : ((void *)&Memory::Write_U32_Swap), gpr.R(s), addr); break;
case 16: ABI_CallFunctionAC(true ? ((void *)&Memory::Write_U16) : ((void *)&Memory::Write_U16_Swap), gpr.R(s), addr); break;
case 8: ABI_CallFunctionAC((void *)&Memory::Write_U8, gpr.R(s), addr); break;
}
ABI_PopRegistersAndAdjustStack(registersInUse, false);
if (update)
gpr.SetImmediate32(a, addr);
return;
@@ -50,7 +50,7 @@ void Jit64::lfs(UGeckoInstruction inst)
}
s32 offset = (s32)(s16)inst.SIMM_16;
SafeLoadToEAX(gpr.R(a), 32, offset, RegistersInUse(), false);
SafeLoadToReg(EAX, gpr.R(a), 32, offset, RegistersInUse(), false);
MEMCHECK_START
@@ -209,6 +209,7 @@ void Jit64::stfd(UGeckoInstruction inst)
MOVD_xmm(R(EAX), XMM0);
SafeWriteRegToReg(EAX, ABI_PARAM1, 32, 0, RegistersInUse() | (1 << (16 + XMM0)));
MOVAPD(XMM0, fpr.R(s));
MOVD_xmm(R(EAX), XMM0);
LEA(32, ABI_PARAM1, MDisp(gpr.R(a).GetSimpleReg(), offset));
SafeWriteRegToReg(EAX, ABI_PARAM1, 32, 4, RegistersInUse());
@@ -338,7 +339,7 @@ void Jit64::lfsx(UGeckoInstruction inst)
MEMCHECK_END
} else {
SafeLoadToEAX(R(EAX), 32, 0, RegistersInUse(), false);
SafeLoadToReg(EAX, R(EAX), 32, 0, RegistersInUse(), false);
MEMCHECK_START
@@ -7,7 +7,6 @@
#include "Common.h"
#include "Thunk.h"
#include "../PowerPC.h"
#include "../../Core.h"
#include "../../HW/GPFifo.h"
@@ -106,15 +105,11 @@ void Jit64::psq_st(UGeckoInstruction inst)
// One value
XORPS(XMM0, R(XMM0)); // TODO: See if we can get rid of this cheaply by tweaking the code in the singleStore* functions.
CVTSD2SS(XMM0, fpr.R(s));
ABI_AlignStack(0);
CALLptr(MScaled(EDX, addr_scale, (u32)(u64)asm_routines.singleStoreQuantized));
ABI_RestoreStack(0);
} else {
// Pair of values
CVTPD2PS(XMM0, fpr.R(s));
ABI_AlignStack(0);
CALLptr(MScaled(EDX, addr_scale, (u32)(u64)asm_routines.pairedStoreQuantized));
ABI_RestoreStack(0);
}
gpr.UnlockAll();
gpr.UnlockAllX();
@@ -11,7 +11,6 @@
#include "../PPCTables.h"
#include "x64Emitter.h"
#include "x64ABI.h"
#include "Thunk.h"
#include "Jit.h"
#include "JitRegCache.h"

Some files were not shown because too many files have changed in this diff Show More